Ruby  1.9.3p551(2014-11-13revision48407)
iseq.c
Go to the documentation of this file.
1 /**********************************************************************
2 
3  iseq.c -
4 
5  $Author: usa $
6  created at: 2006-07-11(Tue) 09:00:03 +0900
7 
8  Copyright (C) 2006 Koichi Sasada
9 
10 **********************************************************************/
11 
12 #include "ruby/ruby.h"
13 #include "internal.h"
14 
15 /* #define RUBY_MARK_FREE_DEBUG 1 */
16 #include "gc.h"
17 #include "vm_core.h"
18 #include "iseq.h"
19 
20 #include "insns.inc"
21 #include "insns_info.inc"
22 
23 #define ISEQ_MAJOR_VERSION 1
24 #define ISEQ_MINOR_VERSION 2
25 
27 
28 #define hidden_obj_p(obj) (!SPECIAL_CONST_P(obj) && !RBASIC(obj)->klass)
29 
30 static inline VALUE
32 {
33  if (hidden_obj_p(obj)) {
34  switch (BUILTIN_TYPE(obj)) {
35  case T_STRING:
36  obj = rb_str_resurrect(obj);
37  break;
38  case T_ARRAY:
39  obj = rb_ary_resurrect(obj);
40  break;
41  }
42  }
43  return obj;
44 }
45 
46 static void
47 compile_data_free(struct iseq_compile_data *compile_data)
48 {
49  if (compile_data) {
50  struct iseq_compile_data_storage *cur, *next;
51  cur = compile_data->storage_head;
52  while (cur) {
53  next = cur->next;
54  ruby_xfree(cur);
55  cur = next;
56  }
57  ruby_xfree(compile_data);
58  }
59 }
60 
61 static void
62 iseq_free(void *ptr)
63 {
64  rb_iseq_t *iseq;
65  RUBY_FREE_ENTER("iseq");
66 
67  if (ptr) {
68  iseq = ptr;
69  if (!iseq->orig) {
70  /* It's possible that strings are freed */
71  if (0) {
72  RUBY_GC_INFO("%s @ %s\n", RSTRING_PTR(iseq->name),
73  RSTRING_PTR(iseq->filename));
74  }
75 
76  if (iseq->iseq != iseq->iseq_encoded) {
78  }
79 
87  }
88  ruby_xfree(ptr);
89  }
90  RUBY_FREE_LEAVE("iseq");
91 }
92 
93 static void
94 iseq_mark(void *ptr)
95 {
96  RUBY_MARK_ENTER("iseq");
97 
98  if (ptr) {
99  rb_iseq_t *iseq = ptr;
100 
101  RUBY_GC_INFO("%s @ %s\n", RSTRING_PTR(iseq->name), RSTRING_PTR(iseq->filename));
109 #if 0
110  RUBY_MARK_UNLESS_NULL((VALUE)iseq->node);
111  RUBY_MARK_UNLESS_NULL(iseq->cached_special_block);
112 #endif
114 
115  if (iseq->compile_data != 0) {
116  struct iseq_compile_data *const compile_data = iseq->compile_data;
117  RUBY_MARK_UNLESS_NULL(compile_data->mark_ary);
118  RUBY_MARK_UNLESS_NULL(compile_data->err_info);
119  RUBY_MARK_UNLESS_NULL(compile_data->catch_table_ary);
120  }
121  }
122  RUBY_MARK_LEAVE("iseq");
123 }
124 
125 static size_t
126 iseq_memsize(const void *ptr)
127 {
128  size_t size = sizeof(rb_iseq_t);
129  const rb_iseq_t *iseq;
130 
131  if (ptr) {
132  iseq = ptr;
133  if (!iseq->orig) {
134  if (iseq->iseq != iseq->iseq_encoded) {
135  size += iseq->iseq_size * sizeof(VALUE);
136  }
137 
138  size += iseq->iseq_size * sizeof(VALUE);
139  size += iseq->insn_info_size * sizeof(struct iseq_insn_info_entry);
140  size += iseq->local_table_size * sizeof(ID);
141  size += iseq->catch_table_size * sizeof(struct iseq_catch_table_entry);
142  size += iseq->arg_opts * sizeof(VALUE);
143  size += iseq->ic_size * sizeof(struct iseq_inline_cache_entry);
144 
145  if (iseq->compile_data) {
146  struct iseq_compile_data_storage *cur;
147 
148  cur = iseq->compile_data->storage_head;
149  while (cur) {
150  size += cur->size + sizeof(struct iseq_compile_data_storage);
151  cur = cur->next;
152  }
153  size += sizeof(struct iseq_compile_data);
154  }
155  }
156  }
157 
158  return size;
159 }
160 
162  "iseq",
163  {
164  iseq_mark,
165  iseq_free,
166  iseq_memsize,
167  },
168 };
169 
170 static VALUE
172 {
173  rb_iseq_t *iseq;
174  return TypedData_Make_Struct(klass, rb_iseq_t, &iseq_data_type, iseq);
175 }
176 
177 static void
178 set_relation(rb_iseq_t *iseq, const VALUE parent)
179 {
180  const VALUE type = iseq->type;
182 
183  /* set class nest stack */
184  if (type == ISEQ_TYPE_TOP) {
185  /* toplevel is private */
187  iseq->cref_stack->nd_visi = NOEX_PRIVATE;
188  if (th->top_wrapper) {
189  NODE *cref = NEW_BLOCK(th->top_wrapper);
190  cref->nd_visi = NOEX_PRIVATE;
191  cref->nd_next = iseq->cref_stack;
192  iseq->cref_stack = cref;
193  }
194  }
195  else if (type == ISEQ_TYPE_METHOD || type == ISEQ_TYPE_CLASS) {
196  iseq->cref_stack = NEW_BLOCK(0); /* place holder */
197  }
198  else if (RTEST(parent)) {
199  rb_iseq_t *piseq;
200  GetISeqPtr(parent, piseq);
201  iseq->cref_stack = piseq->cref_stack;
202  }
203 
204  if (type == ISEQ_TYPE_TOP ||
205  type == ISEQ_TYPE_METHOD || type == ISEQ_TYPE_CLASS) {
206  iseq->local_iseq = iseq;
207  }
208  else if (RTEST(parent)) {
209  rb_iseq_t *piseq;
210  GetISeqPtr(parent, piseq);
211  iseq->local_iseq = piseq->local_iseq;
212  }
213 
214  if (RTEST(parent)) {
215  rb_iseq_t *piseq;
216  GetISeqPtr(parent, piseq);
217  iseq->parent_iseq = piseq;
218  }
219 
220  if (type == ISEQ_TYPE_MAIN) {
221  iseq->local_iseq = iseq;
222  }
223 }
224 
225 static VALUE
227  VALUE name, VALUE filename, VALUE filepath, VALUE line_no,
228  VALUE parent, enum iseq_type type, VALUE block_opt,
230 {
231  OBJ_FREEZE(name);
232  OBJ_FREEZE(filename);
233 
234  iseq->name = name;
235  iseq->filename = filename;
236  iseq->filepath = filepath;
237  iseq->line_no = (unsigned short)line_no; /* TODO: really enough? */
238  iseq->defined_method_id = 0;
239  iseq->mark_ary = rb_ary_tmp_new(3);
240  OBJ_UNTRUST(iseq->mark_ary);
241  RBASIC(iseq->mark_ary)->klass = 0;
242 
243  iseq->type = type;
244  iseq->arg_rest = -1;
245  iseq->arg_block = -1;
246  iseq->klass = 0;
247 
248  /*
249  * iseq->special_block_builder = GC_GUARDED_PTR_REF(block_opt);
250  * iseq->cached_special_block_builder = 0;
251  * iseq->cached_special_block = 0;
252  */
253 
254  iseq->compile_data = ALLOC(struct iseq_compile_data);
255  MEMZERO(iseq->compile_data, struct iseq_compile_data, 1);
256  iseq->compile_data->err_info = Qnil;
258 
260  (struct iseq_compile_data_storage *)
262  sizeof(struct iseq_compile_data_storage));
263 
265  iseq->compile_data->storage_head->pos = 0;
266  iseq->compile_data->storage_head->next = 0;
267  iseq->compile_data->storage_head->size =
269  iseq->compile_data->storage_head->buff =
270  (char *)(&iseq->compile_data->storage_head->buff + 1);
271  iseq->compile_data->option = option;
272  iseq->compile_data->last_coverable_line = -1;
273 
274  set_relation(iseq, parent);
275 
276  iseq->coverage = Qfalse;
277  if (!GET_THREAD()->parse_in_eval) {
278  VALUE coverages = rb_get_coverages();
279  if (RTEST(coverages)) {
280  iseq->coverage = rb_hash_lookup(coverages, filename);
281  if (NIL_P(iseq->coverage)) iseq->coverage = Qfalse;
282  }
283  }
284 
285  return Qtrue;
286 }
287 
288 static VALUE
290 {
291  struct iseq_compile_data *data = iseq->compile_data;
292  VALUE err = data->err_info;
293  iseq->compile_data = 0;
294  compile_data_free(data);
295 
296  if (RTEST(err)) {
297  rb_funcall2(err, rb_intern("set_backtrace"), 1, &iseq->filename);
298  rb_exc_raise(err);
299  }
300  return Qtrue;
301 }
302 
304  OPT_INLINE_CONST_CACHE, /* int inline_const_cache; */
305  OPT_PEEPHOLE_OPTIMIZATION, /* int peephole_optimization; */
306  OPT_TAILCALL_OPTIMIZATION, /* int tailcall_optimization */
307  OPT_SPECIALISED_INSTRUCTION, /* int specialized_instruction; */
308  OPT_OPERANDS_UNIFICATION, /* int operands_unification; */
309  OPT_INSTRUCTIONS_UNIFICATION, /* int instructions_unification; */
310  OPT_STACK_CACHING, /* int stack_caching; */
311  OPT_TRACE_INSTRUCTION, /* int trace_instruction */
312 };
314 
315 static void
317 {
318  if (opt == Qnil) {
319  *option = COMPILE_OPTION_DEFAULT;
320  }
321  else if (opt == Qfalse) {
322  *option = COMPILE_OPTION_FALSE;
323  }
324  else if (opt == Qtrue) {
325  memset(option, 1, sizeof(rb_compile_option_t));
326  }
327  else if (CLASS_OF(opt) == rb_cHash) {
328  *option = COMPILE_OPTION_DEFAULT;
329 
330 #define SET_COMPILE_OPTION(o, h, mem) \
331  { VALUE flag = rb_hash_aref((h), ID2SYM(rb_intern(#mem))); \
332  if (flag == Qtrue) { (o)->mem = 1; } \
333  else if (flag == Qfalse) { (o)->mem = 0; } \
334  }
335 #define SET_COMPILE_OPTION_NUM(o, h, mem) \
336  { VALUE num = rb_hash_aref(opt, ID2SYM(rb_intern(#mem))); \
337  if (!NIL_P(num)) (o)->mem = NUM2INT(num); \
338  }
339  SET_COMPILE_OPTION(option, opt, inline_const_cache);
340  SET_COMPILE_OPTION(option, opt, peephole_optimization);
341  SET_COMPILE_OPTION(option, opt, tailcall_optimization);
342  SET_COMPILE_OPTION(option, opt, specialized_instruction);
343  SET_COMPILE_OPTION(option, opt, operands_unification);
344  SET_COMPILE_OPTION(option, opt, instructions_unification);
345  SET_COMPILE_OPTION(option, opt, stack_caching);
346  SET_COMPILE_OPTION(option, opt, trace_instruction);
347  SET_COMPILE_OPTION_NUM(option, opt, debug_level);
348 #undef SET_COMPILE_OPTION
349 #undef SET_COMPILE_OPTION_NUM
350  }
351  else {
352  rb_raise(rb_eTypeError, "Compile option must be Hash/true/false/nil");
353  }
354 }
355 
356 static VALUE
358 {
359  VALUE opt = rb_hash_new();
360 #define SET_COMPILE_OPTION(o, h, mem) \
361  rb_hash_aset((h), ID2SYM(rb_intern(#mem)), (o)->mem ? Qtrue : Qfalse)
362 #define SET_COMPILE_OPTION_NUM(o, h, mem) \
363  rb_hash_aset((h), ID2SYM(rb_intern(#mem)), INT2NUM((o)->mem))
364  {
365  SET_COMPILE_OPTION(option, opt, inline_const_cache);
366  SET_COMPILE_OPTION(option, opt, peephole_optimization);
367  SET_COMPILE_OPTION(option, opt, tailcall_optimization);
368  SET_COMPILE_OPTION(option, opt, specialized_instruction);
369  SET_COMPILE_OPTION(option, opt, operands_unification);
370  SET_COMPILE_OPTION(option, opt, instructions_unification);
371  SET_COMPILE_OPTION(option, opt, stack_caching);
372  SET_COMPILE_OPTION_NUM(option, opt, debug_level);
373  }
374 #undef SET_COMPILE_OPTION
375 #undef SET_COMPILE_OPTION_NUM
376  return opt;
377 }
378 
379 VALUE
380 rb_iseq_new(NODE *node, VALUE name, VALUE filename, VALUE filepath,
381  VALUE parent, enum iseq_type type)
382 {
383  return rb_iseq_new_with_opt(node, name, filename, filepath, INT2FIX(0), parent, type,
384  &COMPILE_OPTION_DEFAULT);
385 }
386 
387 VALUE
388 rb_iseq_new_top(NODE *node, VALUE name, VALUE filename, VALUE filepath, VALUE parent)
389 {
390  return rb_iseq_new_with_opt(node, name, filename, filepath, INT2FIX(0), parent, ISEQ_TYPE_TOP,
391  &COMPILE_OPTION_DEFAULT);
392 }
393 
394 VALUE
395 rb_iseq_new_main(NODE *node, VALUE filename, VALUE filepath)
396 {
398  VALUE parent = th->base_block->iseq->self;
399  return rb_iseq_new_with_opt(node, rb_str_new2("<main>"), filename, filepath, INT2FIX(0),
400  parent, ISEQ_TYPE_MAIN, &COMPILE_OPTION_DEFAULT);
401 }
402 
403 static VALUE
404 rb_iseq_new_with_bopt_and_opt(NODE *node, VALUE name, VALUE filename, VALUE filepath, VALUE line_no,
405  VALUE parent, enum iseq_type type, VALUE bopt,
407 {
408  rb_iseq_t *iseq;
409  VALUE self = iseq_alloc(rb_cISeq);
410 
411  GetISeqPtr(self, iseq);
412  iseq->self = self;
413 
414  prepare_iseq_build(iseq, name, filename, filepath, line_no, parent, type, bopt, option);
415  rb_iseq_compile_node(self, node);
416  cleanup_iseq_build(iseq);
417  return self;
418 }
419 
420 VALUE
421 rb_iseq_new_with_opt(NODE *node, VALUE name, VALUE filename, VALUE filepath, VALUE line_no,
422  VALUE parent, enum iseq_type type,
424 {
425  /* TODO: argument check */
426  return rb_iseq_new_with_bopt_and_opt(node, name, filename, filepath, line_no, parent, type,
427  Qfalse, option);
428 }
429 
430 VALUE
431 rb_iseq_new_with_bopt(NODE *node, VALUE name, VALUE filename, VALUE filepath, VALUE line_no,
432  VALUE parent, enum iseq_type type, VALUE bopt)
433 {
434  /* TODO: argument check */
435  return rb_iseq_new_with_bopt_and_opt(node, name, filename, filepath, line_no, parent, type,
436  bopt, &COMPILE_OPTION_DEFAULT);
437 }
438 
439 #define CHECK_ARRAY(v) rb_convert_type((v), T_ARRAY, "Array", "to_ary")
440 #define CHECK_STRING(v) rb_convert_type((v), T_STRING, "String", "to_str")
441 #define CHECK_SYMBOL(v) rb_convert_type((v), T_SYMBOL, "Symbol", "to_sym")
442 static inline VALUE CHECK_INTEGER(VALUE v) {(void)NUM2LONG(v); return v;}
443 static VALUE
444 iseq_load(VALUE self, VALUE data, VALUE parent, VALUE opt)
445 {
446  VALUE iseqval = iseq_alloc(self);
447 
448  VALUE magic, version1, version2, format_type, misc;
449  VALUE name, filename, filepath, line_no;
450  VALUE type, body, locals, args, exception;
451 
452  st_data_t iseq_type;
453  static struct st_table *type_map_cache = 0;
454  struct st_table *type_map = 0;
455  rb_iseq_t *iseq;
456  rb_compile_option_t option;
457  int i = 0;
458 
459  /* [magic, major_version, minor_version, format_type, misc,
460  * name, filename, line_no,
461  * type, locals, args, exception_table, body]
462  */
463 
464  data = CHECK_ARRAY(data);
465 
466  magic = CHECK_STRING(rb_ary_entry(data, i++));
467  version1 = CHECK_INTEGER(rb_ary_entry(data, i++));
468  version2 = CHECK_INTEGER(rb_ary_entry(data, i++));
469  format_type = CHECK_INTEGER(rb_ary_entry(data, i++));
470  misc = rb_ary_entry(data, i++); /* TODO */
471 
472  name = CHECK_STRING(rb_ary_entry(data, i++));
473  filename = CHECK_STRING(rb_ary_entry(data, i++));
474  filepath = rb_ary_entry(data, i++);
475  filepath = NIL_P(filepath) ? Qnil : CHECK_STRING(filepath);
476  line_no = CHECK_INTEGER(rb_ary_entry(data, i++));
477 
478  type = CHECK_SYMBOL(rb_ary_entry(data, i++));
479  locals = CHECK_ARRAY(rb_ary_entry(data, i++));
480 
481  args = rb_ary_entry(data, i++);
482  if (FIXNUM_P(args) || (args = CHECK_ARRAY(args))) {
483  /* */
484  }
485 
486  exception = CHECK_ARRAY(rb_ary_entry(data, i++));
487  body = CHECK_ARRAY(rb_ary_entry(data, i++));
488 
489  GetISeqPtr(iseqval, iseq);
490  iseq->self = iseqval;
491 
492  type_map = type_map_cache;
493  if (type_map == 0) {
494  struct st_table *cached_map;
495  type_map = st_init_numtable();
496  st_insert(type_map, ID2SYM(rb_intern("top")), ISEQ_TYPE_TOP);
497  st_insert(type_map, ID2SYM(rb_intern("method")), ISEQ_TYPE_METHOD);
498  st_insert(type_map, ID2SYM(rb_intern("block")), ISEQ_TYPE_BLOCK);
499  st_insert(type_map, ID2SYM(rb_intern("class")), ISEQ_TYPE_CLASS);
500  st_insert(type_map, ID2SYM(rb_intern("rescue")), ISEQ_TYPE_RESCUE);
501  st_insert(type_map, ID2SYM(rb_intern("ensure")), ISEQ_TYPE_ENSURE);
502  st_insert(type_map, ID2SYM(rb_intern("eval")), ISEQ_TYPE_EVAL);
503  st_insert(type_map, ID2SYM(rb_intern("main")), ISEQ_TYPE_MAIN);
504  st_insert(type_map, ID2SYM(rb_intern("defined_guard")), ISEQ_TYPE_DEFINED_GUARD);
505  cached_map = ATOMIC_PTR_CAS(type_map_cache, (struct st_table *)0, type_map);
506  if (cached_map) {
507  st_free_table(type_map);
508  type_map = cached_map;
509  }
510  }
511 
512  if (st_lookup(type_map, type, &iseq_type) == 0) {
513  const char *typename = rb_id2name(type);
514  if (typename)
515  rb_raise(rb_eTypeError, "unsupport type: :%s", typename);
516  else
517  rb_raise(rb_eTypeError, "unsupport type: %p", (void *)type);
518  }
519 
520  if (parent == Qnil) {
521  parent = 0;
522  }
523 
524  make_compile_option(&option, opt);
525  prepare_iseq_build(iseq, name, filename, filepath, line_no,
526  parent, (enum iseq_type)iseq_type, 0, &option);
527 
528  rb_iseq_build_from_ary(iseq, locals, args, exception, body);
529 
530  cleanup_iseq_build(iseq);
531  return iseqval;
532 }
533 
534 static VALUE
536 {
537  VALUE data, opt=Qnil;
538  rb_scan_args(argc, argv, "11", &data, &opt);
539 
540  return iseq_load(self, data, 0, opt);
541 }
542 
543 VALUE
545 {
546  return iseq_load(rb_cISeq, data, parent, opt);
547 }
548 
549 static NODE *
550 parse_string(VALUE str, const char *file, int line)
551 {
553  NODE *node = rb_parser_compile_string(parser, file, str, line);
554 
555  if (!node) {
556  rb_exc_raise(GET_THREAD()->errinfo); /* TODO: check err */
557  }
558  return node;
559 }
560 
561 VALUE
563 {
564  rb_compile_option_t option;
565  const char *fn = StringValueCStr(file);
566  int ln = NUM2INT(line);
567  NODE *node = parse_string(StringValue(src), fn, ln);
569  make_compile_option(&option, opt);
570 
571  if (th->base_block && th->base_block->iseq) {
572  return rb_iseq_new_with_opt(node, th->base_block->iseq->name,
573  file, filepath, line, th->base_block->iseq->self,
574  ISEQ_TYPE_EVAL, &option);
575  }
576  else {
577  return rb_iseq_new_with_opt(node, rb_str_new2("<compiled>"), file, filepath, line, Qfalse,
578  ISEQ_TYPE_TOP, &option);
579  }
580 }
581 
582 VALUE
584 {
585  return rb_iseq_compile_with_option(src, file, Qnil, line, Qnil);
586 }
587 
588 static VALUE
590 {
591  VALUE src, file = Qnil, path = Qnil, line = INT2FIX(1), opt = Qnil;
592 
593  rb_secure(1);
594 
595  rb_scan_args(argc, argv, "14", &src, &file, &path, &line, &opt);
596  if (NIL_P(file)) file = rb_str_new2("<compiled>");
597  if (NIL_P(line)) line = INT2FIX(1);
598 
599  return rb_iseq_compile_with_option(src, file, path, line, opt);
600 }
601 
602 static VALUE
604 {
605  VALUE file, line = INT2FIX(1), opt = Qnil;
606  VALUE parser;
607  VALUE f;
608  NODE *node;
609  const char *fname;
610  rb_compile_option_t option;
611 
612  rb_secure(1);
613  rb_scan_args(argc, argv, "11", &file, &opt);
614  FilePathValue(file);
615  fname = StringValueCStr(file);
616 
617  f = rb_file_open_str(file, "r");
618 
619  parser = rb_parser_new();
620  node = rb_parser_compile_file(parser, fname, f, NUM2INT(line));
621  make_compile_option(&option, opt);
622  return rb_iseq_new_with_opt(node, rb_str_new2("<main>"), file,
623  rb_realpath_internal(Qnil, file, 1), line, Qfalse,
624  ISEQ_TYPE_TOP, &option);
625 }
626 
627 static VALUE
629 {
630  rb_compile_option_t option;
631  rb_secure(1);
632  make_compile_option(&option, opt);
633  COMPILE_OPTION_DEFAULT = option;
634  return opt;
635 }
636 
637 static VALUE
639 {
640  return make_compile_option_value(&COMPILE_OPTION_DEFAULT);
641 }
642 
643 static rb_iseq_t *
645 {
646  rb_iseq_t *iseq;
647  GetISeqPtr(val, iseq);
648  if (!iseq->name) {
649  rb_raise(rb_eTypeError, "uninitialized InstructionSequence");
650  }
651  return iseq;
652 }
653 
654 static VALUE
656 {
657  rb_secure(1);
658  return rb_iseq_eval(self);
659 }
660 
661 static VALUE
663 {
664  rb_iseq_t *iseq;
665  GetISeqPtr(self, iseq);
666  if (!iseq->name) {
667  return rb_sprintf("#<%s: uninitialized>", rb_obj_classname(self));
668  }
669 
670  return rb_sprintf("<%s:%s@%s>",
671  rb_obj_classname(self),
672  RSTRING_PTR(iseq->name), RSTRING_PTR(iseq->filename));
673 }
674 
675 static
677 
678 static VALUE
680 {
681  rb_iseq_t *iseq = iseq_check(self);
682  rb_secure(1);
683  return iseq_data_to_ary(iseq);
684 }
685 
686 int
688 {
689  return FIX2INT(iseq->line_no);
690 }
691 
692 /* TODO: search algorithm is brute force.
693  this should be binary search or so. */
694 
695 static struct iseq_insn_info_entry *
696 get_insn_info(const rb_iseq_t *iseq, const unsigned long pos)
697 {
698  unsigned long i, size = iseq->insn_info_size;
700 
701  for (i = 0; i < size; i++) {
702  if (table[i].position == pos) {
703  return &table[i];
704  }
705  }
706 
707  return 0;
708 }
709 
710 static unsigned short
711 find_line_no(rb_iseq_t *iseq, unsigned long pos)
712 {
713  struct iseq_insn_info_entry *entry = get_insn_info(iseq, pos);
714  if (entry) {
715  return entry->line_no;
716  }
717  else {
718  return 0;
719  }
720 }
721 
722 static unsigned short
723 find_prev_line_no(rb_iseq_t *iseqdat, unsigned long pos)
724 {
725  unsigned long i, size = iseqdat->insn_info_size;
726  struct iseq_insn_info_entry *iiary = iseqdat->insn_info_table;
727 
728  for (i = 0; i < size; i++) {
729  if (iiary[i].position == pos) {
730  if (i > 0) {
731  return iiary[i - 1].line_no;
732  }
733  else {
734  return 0;
735  }
736  }
737  }
738 
739  return 0;
740 }
741 
742 static VALUE
744  VALUE insn, int op_no, VALUE op,
745  int len, size_t pos, VALUE *pnop, VALUE child)
746 {
747  const char *types = insn_op_types(insn);
748  char type = types[op_no];
749  VALUE ret;
750 
751  switch (type) {
752  case TS_OFFSET: /* LONG */
753  ret = rb_sprintf("%"PRIdVALUE, (VALUE)(pos + len + op));
754  break;
755 
756  case TS_NUM: /* ULONG */
757  ret = rb_sprintf("%"PRIuVALUE, op);
758  break;
759 
760  case TS_LINDEX:
761  {
762  rb_iseq_t *liseq = iseq->local_iseq;
763  int lidx = liseq->local_size - (int)op;
764  const char *name = rb_id2name(liseq->local_table[lidx]);
765 
766  if (name) {
767  ret = rb_str_new2(name);
768  }
769  else {
770  ret = rb_str_new2("*");
771  }
772  break;
773  }
774  case TS_DINDEX:{
775  if (insn == BIN(getdynamic) || insn == BIN(setdynamic)) {
776  rb_iseq_t *diseq = iseq;
777  VALUE level = *pnop, i;
778  const char *name;
779  for (i = 0; i < level; i++) {
780  diseq = diseq->parent_iseq;
781  }
782  name = rb_id2name(diseq->local_table[diseq->local_size - op]);
783 
784  if (!name) {
785  name = "*";
786  }
787  ret = rb_str_new2(name);
788  }
789  else {
790  ret = rb_inspect(INT2FIX(op));
791  }
792  break;
793  }
794  case TS_ID: /* ID (symbol) */
795  op = ID2SYM(op);
796 
797  case TS_VALUE: /* VALUE */
798  op = obj_resurrect(op);
799  ret = rb_inspect(op);
800  if (CLASS_OF(op) == rb_cISeq) {
801  rb_ary_push(child, op);
802  }
803  break;
804 
805  case TS_ISEQ: /* iseq */
806  {
807  rb_iseq_t *iseq = (rb_iseq_t *)op;
808  if (iseq) {
809  ret = iseq->name;
810  if (child) {
811  rb_ary_push(child, iseq->self);
812  }
813  }
814  else {
815  ret = rb_str_new2("nil");
816  }
817  break;
818  }
819  case TS_GENTRY:
820  {
821  struct rb_global_entry *entry = (struct rb_global_entry *)op;
822  ret = rb_str_dup(rb_id2str(entry->id));
823  }
824  break;
825 
826  case TS_IC:
827  ret = rb_sprintf("<ic:%"PRIdPTRDIFF">", (struct iseq_inline_cache_entry *)op - iseq->ic_entries);
828  break;
829 
830  case TS_CDHASH:
831  ret = rb_str_new2("<cdhash>");
832  break;
833 
834  case TS_FUNCPTR:
835  ret = rb_str_new2("<funcptr>");
836  break;
837 
838  default:
839  rb_bug("rb_iseq_disasm: unknown operand type: %c", type);
840  }
841  return ret;
842 }
843 
848 int
849 rb_iseq_disasm_insn(VALUE ret, VALUE *iseq, size_t pos,
850  rb_iseq_t *iseqdat, VALUE child)
851 {
852  VALUE insn = iseq[pos];
853  int len = insn_len(insn);
854  int j;
855  const char *types = insn_op_types(insn);
856  VALUE str = rb_str_new(0, 0);
857  const char *insn_name_buff;
858 
859  insn_name_buff = insn_name(insn);
860  if (1) {
861  rb_str_catf(str, "%04"PRIdSIZE" %-16s ", pos, insn_name_buff);
862  }
863  else {
864  rb_str_catf(str, "%04"PRIdSIZE" %-16.*s ", pos,
865  (int)strcspn(insn_name_buff, "_"), insn_name_buff);
866  }
867 
868  for (j = 0; types[j]; j++) {
869  const char *types = insn_op_types(insn);
870  VALUE opstr = insn_operand_intern(iseqdat, insn, j, iseq[pos + j + 1],
871  len, pos, &iseq[pos + j + 2],
872  child);
873  rb_str_concat(str, opstr);
874 
875  if (types[j + 1]) {
876  rb_str_cat2(str, ", ");
877  }
878  }
879 
880  if (1) {
881  int line_no = find_line_no(iseqdat, pos);
882  int prev = find_prev_line_no(iseqdat, pos);
883  if (line_no && line_no != prev) {
884  long slen = RSTRING_LEN(str);
885  slen = (slen > 70) ? 0 : (70 - slen);
886  str = rb_str_catf(str, "%*s(%4d)", (int)slen, "", line_no);
887  }
888  }
889  else {
890  /* for debug */
891  struct iseq_insn_info_entry *entry = get_insn_info(iseqdat, pos);
892  long slen = RSTRING_LEN(str);
893  slen = (slen > 60) ? 0 : (60 - slen);
894  str = rb_str_catf(str, "%*s(line: %d, sp: %d)",
895  (int)slen, "", entry->line_no, entry->sp);
896  }
897 
898  if (ret) {
899  rb_str_cat2(str, "\n");
900  rb_str_concat(ret, str);
901  }
902  else {
903  printf("%s\n", RSTRING_PTR(str));
904  }
905  return len;
906 }
907 
908 static const char *
910 {
911  switch (type) {
912  case CATCH_TYPE_RESCUE:
913  return "rescue";
914  case CATCH_TYPE_ENSURE:
915  return "ensure";
916  case CATCH_TYPE_RETRY:
917  return "retry";
918  case CATCH_TYPE_BREAK:
919  return "break";
920  case CATCH_TYPE_REDO:
921  return "redo";
922  case CATCH_TYPE_NEXT:
923  return "next";
924  default:
925  rb_bug("unknown catch type (%d)", type);
926  return 0;
927  }
928 }
929 
930 VALUE
932 {
933  rb_iseq_t *iseqdat = iseq_check(self);
934  VALUE *iseq;
935  VALUE str = rb_str_new(0, 0);
936  VALUE child = rb_ary_new();
937  unsigned long size;
938  int i;
939  long l;
940  ID *tbl;
941  size_t n;
942  enum {header_minlen = 72};
943 
944  rb_secure(1);
945 
946  iseq = iseqdat->iseq;
947  size = iseqdat->iseq_size;
948 
949  rb_str_cat2(str, "== disasm: ");
950 
951  rb_str_concat(str, iseq_inspect(iseqdat->self));
952  if ((l = RSTRING_LEN(str)) < header_minlen) {
953  rb_str_resize(str, header_minlen);
954  memset(RSTRING_PTR(str) + l, '=', header_minlen - l);
955  }
956  rb_str_cat2(str, "\n");
957 
958  /* show catch table information */
959  if (iseqdat->catch_table_size != 0) {
960  rb_str_cat2(str, "== catch table\n");
961  }
962  for (i = 0; i < iseqdat->catch_table_size; i++) {
963  struct iseq_catch_table_entry *entry = &iseqdat->catch_table[i];
964  rb_str_catf(str,
965  "| catch type: %-6s st: %04d ed: %04d sp: %04d cont: %04d\n",
966  catch_type((int)entry->type), (int)entry->start,
967  (int)entry->end, (int)entry->sp, (int)entry->cont);
968  if (entry->iseq) {
969  rb_str_concat(str, rb_iseq_disasm(entry->iseq));
970  }
971  }
972  if (iseqdat->catch_table_size != 0) {
973  rb_str_cat2(str, "|-------------------------------------"
974  "-----------------------------------\n");
975  }
976 
977  /* show local table information */
978  tbl = iseqdat->local_table;
979 
980  if (tbl) {
981  rb_str_catf(str,
982  "local table (size: %d, argc: %d "
983  "[opts: %d, rest: %d, post: %d, block: %d] s%d)\n",
984  iseqdat->local_size, iseqdat->argc,
985  iseqdat->arg_opts, iseqdat->arg_rest,
986  iseqdat->arg_post_len, iseqdat->arg_block,
987  iseqdat->arg_simple);
988 
989  for (i = 0; i < iseqdat->local_table_size; i++) {
990  const char *name = rb_id2name(tbl[i]);
991  char info[0x100];
992  char argi[0x100] = "";
993  char opti[0x100] = "";
994 
995  if (iseqdat->arg_opts) {
996  int argc = iseqdat->argc;
997  int opts = iseqdat->arg_opts;
998  if (i >= argc && i < argc + opts - 1) {
999  snprintf(opti, sizeof(opti), "Opt=%"PRIdVALUE,
1000  iseqdat->arg_opt_table[i - argc]);
1001  }
1002  }
1003 
1004  snprintf(argi, sizeof(argi), "%s%s%s%s%s", /* arg, opts, rest, post block */
1005  iseqdat->argc > i ? "Arg" : "",
1006  opti,
1007  iseqdat->arg_rest == i ? "Rest" : "",
1008  (iseqdat->arg_post_start <= i &&
1009  i < iseqdat->arg_post_start + iseqdat->arg_post_len) ? "Post" : "",
1010  iseqdat->arg_block == i ? "Block" : "");
1011 
1012  snprintf(info, sizeof(info), "%s%s%s%s", name ? name : "?",
1013  *argi ? "<" : "", argi, *argi ? ">" : "");
1014 
1015  rb_str_catf(str, "[%2d] %-11s", iseqdat->local_size - i, info);
1016  }
1017  rb_str_cat2(str, "\n");
1018  }
1019 
1020  /* show each line */
1021  for (n = 0; n < size;) {
1022  n += rb_iseq_disasm_insn(str, iseq, n, iseqdat, child);
1023  }
1024 
1025  for (i = 0; i < RARRAY_LEN(child); i++) {
1026  VALUE isv = rb_ary_entry(child, i);
1027  rb_str_concat(str, rb_iseq_disasm(isv));
1028  }
1029 
1030  return str;
1031 }
1032 
1033 static VALUE
1035 {
1036  VALUE ret = Qnil;
1037  rb_iseq_t *iseq;
1038 
1039  rb_secure(1);
1040 
1041  if (rb_obj_is_proc(body)) {
1042  rb_proc_t *proc;
1043  GetProcPtr(body, proc);
1044  iseq = proc->block.iseq;
1045  if (RUBY_VM_NORMAL_ISEQ_P(iseq)) {
1046  ret = rb_iseq_disasm(iseq->self);
1047  }
1048  }
1049  else if ((iseq = rb_method_get_iseq(body)) != 0) {
1050  ret = rb_iseq_disasm(iseq->self);
1051  }
1052 
1053  return ret;
1054 }
1055 
1056 const char *
1058 {
1059  switch (node) {
1060 #include "node_name.inc"
1061  default:
1062  rb_bug("unknown node (%d)", node);
1063  return 0;
1064  }
1065 }
1066 
1067 #define DECL_SYMBOL(name) \
1068  static VALUE sym_##name
1069 
1070 #define INIT_SYMBOL(name) \
1071  sym_##name = ID2SYM(rb_intern(#name))
1072 
1073 static VALUE
1074 register_label(struct st_table *table, unsigned long idx)
1075 {
1076  VALUE sym;
1077  char buff[8 + (sizeof(idx) * CHAR_BIT * 32 / 100)];
1078 
1079  snprintf(buff, sizeof(buff), "label_%lu", idx);
1080  sym = ID2SYM(rb_intern(buff));
1081  st_insert(table, idx, sym);
1082  return sym;
1083 }
1084 
1085 static VALUE
1087 {
1088  ID id;
1089  switch(type) {
1090  case CATCH_TYPE_RESCUE: CONST_ID(id, "rescue"); break;
1091  case CATCH_TYPE_ENSURE: CONST_ID(id, "ensure"); break;
1092  case CATCH_TYPE_RETRY: CONST_ID(id, "retry"); break;
1093  case CATCH_TYPE_BREAK: CONST_ID(id, "break"); break;
1094  case CATCH_TYPE_REDO: CONST_ID(id, "redo"); break;
1095  case CATCH_TYPE_NEXT: CONST_ID(id, "next"); break;
1096  default:
1097  rb_bug("...");
1098  }
1099  return ID2SYM(id);
1100 }
1101 
1102 static int
1104 {
1105  rb_ary_push(ary, obj_resurrect(key));
1106  rb_ary_push(ary, value);
1107  return ST_CONTINUE;
1108 }
1109 
1110 static VALUE
1112 {
1113  long i, pos;
1114  int line = 0;
1115  VALUE *seq;
1116 
1117  VALUE val = rb_ary_new();
1118  VALUE type; /* Symbol */
1119  VALUE locals = rb_ary_new();
1120  VALUE args = rb_ary_new();
1121  VALUE body = rb_ary_new(); /* [[:insn1, ...], ...] */
1122  VALUE nbody;
1123  VALUE exception = rb_ary_new(); /* [[....]] */
1124  VALUE misc = rb_hash_new();
1125 
1126  static VALUE insn_syms[VM_INSTRUCTION_SIZE];
1127  struct st_table *labels_table = st_init_numtable();
1128 
1129  DECL_SYMBOL(top);
1131  DECL_SYMBOL(block);
1132  DECL_SYMBOL(class);
1133  DECL_SYMBOL(rescue);
1134  DECL_SYMBOL(ensure);
1135  DECL_SYMBOL(eval);
1136  DECL_SYMBOL(main);
1137  DECL_SYMBOL(defined_guard);
1138 
1139  if (sym_top == 0) {
1140  int i;
1141  for (i=0; i<VM_INSTRUCTION_SIZE; i++) {
1142  insn_syms[i] = ID2SYM(rb_intern(insn_name(i)));
1143  }
1144  INIT_SYMBOL(top);
1146  INIT_SYMBOL(block);
1147  INIT_SYMBOL(class);
1148  INIT_SYMBOL(rescue);
1149  INIT_SYMBOL(ensure);
1150  INIT_SYMBOL(eval);
1151  INIT_SYMBOL(main);
1152  INIT_SYMBOL(defined_guard);
1153  }
1154 
1155  /* type */
1156  switch(iseq->type) {
1157  case ISEQ_TYPE_TOP: type = sym_top; break;
1158  case ISEQ_TYPE_METHOD: type = sym_method; break;
1159  case ISEQ_TYPE_BLOCK: type = sym_block; break;
1160  case ISEQ_TYPE_CLASS: type = sym_class; break;
1161  case ISEQ_TYPE_RESCUE: type = sym_rescue; break;
1162  case ISEQ_TYPE_ENSURE: type = sym_ensure; break;
1163  case ISEQ_TYPE_EVAL: type = sym_eval; break;
1164  case ISEQ_TYPE_MAIN: type = sym_main; break;
1165  case ISEQ_TYPE_DEFINED_GUARD: type = sym_defined_guard; break;
1166  default: rb_bug("unsupported iseq type");
1167  };
1168 
1169  /* locals */
1170  for (i=0; i<iseq->local_table_size; i++) {
1171  ID lid = iseq->local_table[i];
1172  if (lid) {
1173  if (rb_id2str(lid)) rb_ary_push(locals, ID2SYM(lid));
1174  }
1175  else {
1176  rb_ary_push(locals, ID2SYM(rb_intern("#arg_rest")));
1177  }
1178  }
1179 
1180  /* args */
1181  {
1182  /*
1183  * [argc, # argc
1184  * [label1, label2, ...] # opts
1185  * rest index,
1186  * post_len
1187  * post_start
1188  * block index,
1189  * simple,
1190  * ]
1191  */
1192  VALUE arg_opt_labels = rb_ary_new();
1193  int j;
1194 
1195  for (j=0; j<iseq->arg_opts; j++) {
1196  rb_ary_push(arg_opt_labels,
1197  register_label(labels_table, iseq->arg_opt_table[j]));
1198  }
1199 
1200  /* commit */
1201  if (iseq->arg_simple == 1) {
1202  args = INT2FIX(iseq->argc);
1203  }
1204  else {
1205  rb_ary_push(args, INT2FIX(iseq->argc));
1206  rb_ary_push(args, arg_opt_labels);
1207  rb_ary_push(args, INT2FIX(iseq->arg_post_len));
1208  rb_ary_push(args, INT2FIX(iseq->arg_post_start));
1209  rb_ary_push(args, INT2FIX(iseq->arg_rest));
1210  rb_ary_push(args, INT2FIX(iseq->arg_block));
1211  rb_ary_push(args, INT2FIX(iseq->arg_simple));
1212  }
1213  }
1214 
1215  /* body */
1216  for (seq = iseq->iseq; seq < iseq->iseq + iseq->iseq_size; ) {
1217  VALUE insn = *seq++;
1218  int j, len = insn_len(insn);
1219  VALUE *nseq = seq + len - 1;
1220  VALUE ary = rb_ary_new2(len);
1221 
1222  rb_ary_push(ary, insn_syms[insn]);
1223  for (j=0; j<len-1; j++, seq++) {
1224  switch (insn_op_type(insn, j)) {
1225  case TS_OFFSET: {
1226  unsigned long idx = nseq - iseq->iseq + *seq;
1227  rb_ary_push(ary, register_label(labels_table, idx));
1228  break;
1229  }
1230  case TS_LINDEX:
1231  case TS_DINDEX:
1232  case TS_NUM:
1233  rb_ary_push(ary, INT2FIX(*seq));
1234  break;
1235  case TS_VALUE:
1236  rb_ary_push(ary, obj_resurrect(*seq));
1237  break;
1238  case TS_ISEQ:
1239  {
1240  rb_iseq_t *iseq = (rb_iseq_t *)*seq;
1241  if (iseq) {
1242  VALUE val = iseq_data_to_ary(iseq);
1243  rb_ary_push(ary, val);
1244  }
1245  else {
1246  rb_ary_push(ary, Qnil);
1247  }
1248  }
1249  break;
1250  case TS_GENTRY:
1251  {
1252  struct rb_global_entry *entry = (struct rb_global_entry *)*seq;
1253  rb_ary_push(ary, ID2SYM(entry->id));
1254  }
1255  break;
1256  case TS_IC: {
1257  struct iseq_inline_cache_entry *ic = (struct iseq_inline_cache_entry *)*seq;
1258  rb_ary_push(ary, INT2FIX(ic - iseq->ic_entries));
1259  }
1260  break;
1261  case TS_ID:
1262  rb_ary_push(ary, ID2SYM(*seq));
1263  break;
1264  case TS_CDHASH:
1265  {
1266  VALUE hash = *seq;
1267  VALUE val = rb_ary_new();
1268  int i;
1269 
1270  rb_hash_foreach(hash, cdhash_each, val);
1271 
1272  for (i=0; i<RARRAY_LEN(val); i+=2) {
1273  VALUE pos = FIX2INT(rb_ary_entry(val, i+1));
1274  unsigned long idx = nseq - iseq->iseq + pos;
1275 
1276  rb_ary_store(val, i+1,
1277  register_label(labels_table, idx));
1278  }
1279  rb_ary_push(ary, val);
1280  }
1281  break;
1282  default:
1283  rb_bug("unknown operand: %c", insn_op_type(insn, j));
1284  }
1285  }
1286  rb_ary_push(body, ary);
1287  }
1288 
1289  nbody = body;
1290 
1291  /* exception */
1292  for (i=0; i<iseq->catch_table_size; i++) {
1293  VALUE ary = rb_ary_new();
1294  struct iseq_catch_table_entry *entry = &iseq->catch_table[i];
1295  rb_ary_push(ary, exception_type2symbol(entry->type));
1296  if (entry->iseq) {
1297  rb_iseq_t *eiseq;
1298  GetISeqPtr(entry->iseq, eiseq);
1299  rb_ary_push(ary, iseq_data_to_ary(eiseq));
1300  }
1301  else {
1302  rb_ary_push(ary, Qnil);
1303  }
1304  rb_ary_push(ary, register_label(labels_table, entry->start));
1305  rb_ary_push(ary, register_label(labels_table, entry->end));
1306  rb_ary_push(ary, register_label(labels_table, entry->cont));
1307  rb_ary_push(ary, INT2FIX(entry->sp));
1308  rb_ary_push(exception, ary);
1309  }
1310 
1311  /* make body with labels and insert line number */
1312  body = rb_ary_new();
1313 
1314  for (i=0, pos=0; i<RARRAY_LEN(nbody); i++) {
1315  VALUE ary = RARRAY_PTR(nbody)[i];
1316  st_data_t label;
1317 
1318  if (st_lookup(labels_table, pos, &label)) {
1319  rb_ary_push(body, (VALUE)label);
1320  }
1321 
1322  if (iseq->insn_info_table[i].line_no != line) {
1323  line = iseq->insn_info_table[i].line_no;
1324  rb_ary_push(body, INT2FIX(line));
1325  }
1326 
1327  rb_ary_push(body, ary);
1328  pos += RARRAY_LENINT(ary); /* reject too huge data */
1329  }
1330 
1331  st_free_table(labels_table);
1332 
1333  rb_hash_aset(misc, ID2SYM(rb_intern("arg_size")), INT2FIX(iseq->arg_size));
1334  rb_hash_aset(misc, ID2SYM(rb_intern("local_size")), INT2FIX(iseq->local_size));
1335  rb_hash_aset(misc, ID2SYM(rb_intern("stack_max")), INT2FIX(iseq->stack_max));
1336 
1337  /*
1338  * [:magic, :major_version, :minor_version, :format_type, :misc,
1339  * :name, :filename, :filepath, :line_no, :type, :locals, :args,
1340  * :catch_table, :bytecode]
1341  */
1342  rb_ary_push(val, rb_str_new2("YARVInstructionSequence/SimpleDataFormat"));
1343  rb_ary_push(val, INT2FIX(ISEQ_MAJOR_VERSION)); /* major */
1344  rb_ary_push(val, INT2FIX(ISEQ_MINOR_VERSION)); /* minor */
1345  rb_ary_push(val, INT2FIX(1));
1346  rb_ary_push(val, misc);
1347  rb_ary_push(val, iseq->name);
1348  rb_ary_push(val, iseq->filename);
1349  rb_ary_push(val, iseq->filepath);
1350  rb_ary_push(val, iseq->line_no);
1351  rb_ary_push(val, type);
1352  rb_ary_push(val, locals);
1353  rb_ary_push(val, args);
1354  rb_ary_push(val, exception);
1355  rb_ary_push(val, body);
1356  return val;
1357 }
1358 
1359 VALUE
1360 rb_iseq_clone(VALUE iseqval, VALUE newcbase)
1361 {
1362  VALUE newiseq = iseq_alloc(rb_cISeq);
1363  rb_iseq_t *iseq0, *iseq1;
1364 
1365  GetISeqPtr(iseqval, iseq0);
1366  GetISeqPtr(newiseq, iseq1);
1367 
1368  *iseq1 = *iseq0;
1369  iseq1->self = newiseq;
1370  if (!iseq1->orig) {
1371  iseq1->orig = iseqval;
1372  }
1373  if (iseq0->local_iseq == iseq0) {
1374  iseq1->local_iseq = iseq1;
1375  }
1376  if (newcbase) {
1377  iseq1->cref_stack = NEW_BLOCK(newcbase);
1378  if (iseq0->cref_stack->nd_next) {
1379  iseq1->cref_stack->nd_next = iseq0->cref_stack->nd_next;
1380  }
1381  iseq1->klass = newcbase;
1382  }
1383 
1384  return newiseq;
1385 }
1386 
1387 VALUE
1388 rb_iseq_parameters(const rb_iseq_t *iseq, int is_proc)
1389 {
1390  int i, r, s;
1391  VALUE a, args = rb_ary_new2(iseq->arg_size);
1392  ID req, opt, rest, block;
1393 #define PARAM_TYPE(type) rb_ary_push(a = rb_ary_new2(2), ID2SYM(type))
1394 #define PARAM_ID(i) iseq->local_table[(i)]
1395 #define PARAM(i, type) ( \
1396  PARAM_TYPE(type), \
1397  rb_id2name(PARAM_ID(i)) ? \
1398  rb_ary_push(a, ID2SYM(PARAM_ID(i))) : \
1399  a)
1400 
1401  CONST_ID(req, "req");
1402  CONST_ID(opt, "opt");
1403  if (is_proc) {
1404  for (i = 0; i < iseq->argc; i++) {
1405  PARAM_TYPE(opt);
1407  rb_ary_push(args, a);
1408  }
1409  }
1410  else {
1411  for (i = 0; i < iseq->argc; i++) {
1412  rb_ary_push(args, PARAM(i, req));
1413  }
1414  }
1415  r = iseq->arg_rest != -1 ? iseq->arg_rest :
1416  iseq->arg_post_len > 0 ? iseq->arg_post_start :
1417  iseq->arg_block != -1 ? iseq->arg_block :
1418  iseq->arg_size;
1419  for (s = i; i < r; i++) {
1420  PARAM_TYPE(opt);
1421  if (rb_id2name(PARAM_ID(i))) {
1422  rb_ary_push(a, ID2SYM(PARAM_ID(i)));
1423  }
1424  rb_ary_push(args, a);
1425  }
1426  if (iseq->arg_rest != -1) {
1427  CONST_ID(rest, "rest");
1428  rb_ary_push(args, PARAM(iseq->arg_rest, rest));
1429  }
1430  r = iseq->arg_post_start + iseq->arg_post_len;
1431  if (is_proc) {
1432  for (i = iseq->arg_post_start; i < r; i++) {
1433  PARAM_TYPE(opt);
1435  rb_ary_push(args, a);
1436  }
1437  }
1438  else {
1439  for (i = iseq->arg_post_start; i < r; i++) {
1440  rb_ary_push(args, PARAM(i, req));
1441  }
1442  }
1443  if (iseq->arg_block != -1) {
1444  CONST_ID(block, "block");
1445  rb_ary_push(args, PARAM(iseq->arg_block, block));
1446  }
1447  return args;
1448 }
1449 
1450 /* ruby2cext */
1451 
1452 VALUE
1454  const rb_iseq_t *iseq_template,
1455  const rb_insn_func_t *func,
1456  const struct iseq_insn_info_entry *insn_info_table,
1457  const char **local_table,
1458  const VALUE *arg_opt_table,
1459  const struct iseq_catch_table_entry *catch_table,
1460  const char *name,
1461  const char *filename,
1462  const unsigned short line_no)
1463 {
1464  unsigned long i;
1465  VALUE iseqval = iseq_alloc(rb_cISeq);
1466  rb_iseq_t *iseq;
1467  GetISeqPtr(iseqval, iseq);
1468 
1469  /* copy iseq */
1470  *iseq = *iseq_template;
1471  iseq->name = rb_str_new2(name);
1472  iseq->filename = rb_str_new2(filename);
1473  iseq->line_no = line_no;
1474  iseq->mark_ary = rb_ary_tmp_new(3);
1475  OBJ_UNTRUST(iseq->mark_ary);
1476  iseq->self = iseqval;
1477 
1478  iseq->iseq = ALLOC_N(VALUE, iseq->iseq_size);
1479 
1480  for (i=0; i<iseq->iseq_size; i+=2) {
1481  iseq->iseq[i] = BIN(opt_call_c_function);
1482  iseq->iseq[i+1] = (VALUE)func;
1483  }
1484 
1486 
1487 #define ALLOC_AND_COPY(dst, src, type, size) do { \
1488  if (size) { \
1489  (dst) = ALLOC_N(type, (size)); \
1490  MEMCPY((dst), (src), type, (size)); \
1491  } \
1492 } while (0)
1493 
1494  ALLOC_AND_COPY(iseq->insn_info_table, insn_info_table,
1495  struct iseq_insn_info_entry, iseq->insn_info_size);
1496 
1497  ALLOC_AND_COPY(iseq->catch_table, catch_table,
1499 
1500  ALLOC_AND_COPY(iseq->arg_opt_table, arg_opt_table,
1501  VALUE, iseq->arg_opts);
1502 
1503  set_relation(iseq, 0);
1504 
1505  return iseqval;
1506 }
1507 
1508 void
1510 {
1511  /* declare ::RubyVM::InstructionSequence */
1512  rb_cISeq = rb_define_class_under(rb_cRubyVM, "InstructionSequence", rb_cObject);
1514  rb_define_method(rb_cISeq, "inspect", iseq_inspect, 0);
1515  rb_define_method(rb_cISeq, "disasm", rb_iseq_disasm, 0);
1516  rb_define_method(rb_cISeq, "disassemble", rb_iseq_disasm, 0);
1517  rb_define_method(rb_cISeq, "to_a", iseq_to_a, 0);
1518  rb_define_method(rb_cISeq, "eval", iseq_eval, 0);
1519 
1520 #if 0 /* TBD */
1521  rb_define_method(rb_cISeq, "marshal_dump", iseq_marshal_dump, 0);
1522  rb_define_method(rb_cISeq, "marshal_load", iseq_marshal_load, 1);
1523 #endif
1524 
1525  /* disable this feature because there is no verifier. */
1526  /* rb_define_singleton_method(rb_cISeq, "load", iseq_s_load, -1); */
1527  (void)iseq_s_load;
1528 
1536 }
1537 
#define RSTRING_LEN(string)
Definition: generator.h:45
static long NUM2LONG(VALUE x)
Definition: ruby.h:510
RARRAY_PTR(q->result)[0]
int rb_iseq_disasm_insn(VALUE ret, VALUE *iseq, size_t pos, rb_iseq_t *iseqdat, VALUE child)
Disassemble a instruction Iseq -&gt; Iseq inspect object.
Definition: iseq.c:849
int arg_simple
Definition: vm_core.h:215
ssize_t n
Definition: bigdecimal.c:5519
int register char * block
Definition: crypt.c:949
VALUE sym
Definition: tkutil.c:1298
volatile VALUE ary
Definition: tcltklib.c:9700
VP_EXPORT int
Definition: bigdecimal.c:4911
int rb_iseq_first_lineno(rb_iseq_t *iseq)
Definition: iseq.c:687
VALUE rb_get_coverages(void)
Definition: thread.c:4886
VALUE rb_ary_entry(VALUE ary, long offset)
Definition: array.c:956
void rb_bug(const char *fmt,...)
Definition: error.c:265
#define DECL_SYMBOL(name)
Definition: iseq.c:1067
#define rb_hash_lookup
Definition: tcltklib.c:264
static VALUE VALUE th
Definition: tcltklib.c:2937
int idx
Definition: tcltklib.c:9703
NODE * rb_parser_compile_file(volatile VALUE vparser, const char *f, VALUE file, int start)
Definition: ripper.c:11652
static void iseq_mark(void *ptr)
Definition: iseq.c:94
unsigned long size
Definition: iseq.h:73
Definition: st.h:77
VALUE rb_id2str(ID id)
Definition: ripper.c:16301
unsigned long end
Definition: iseq.h:63
#define OPT_SPECIALISED_INSTRUCTION
#define NUM2INT(x)
Definition: ruby.h:536
static void make_compile_option(rb_compile_option_t *option, VALUE opt)
Definition: iseq.c:316
parser parser_yylval val
Definition: ripper.c:14289
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1343
Definition: iseq.h:56
#define GetProcPtr(obj, ptr)
Definition: vm_core.h:523
#define RUBY_VM_NORMAL_ISEQ_P(ptr)
Definition: vm_core.h:621
#define FilePathValue(v)
Definition: ruby.h:487
static void set_relation(rb_iseq_t *iseq, const VALUE parent)
Definition: iseq.c:178
#define CLASS_OF(v)
Definition: ruby.h:376
VALUE proc
Definition: tcltklib.c:2948
static VALUE VALUE table
Definition: tcltklib.c:10121
#define ATOMIC_PTR_CAS(var, oldval, val)
Definition: ruby_atomic.h:171
SSL_METHOD *(* func)(void)
Definition: ossl_ssl.c:104
struct iseq_compile_data * compile_data
Definition: vm_core.h:258
static unsigned short find_line_no(rb_iseq_t *iseq, unsigned long pos)
Definition: iseq.c:711
rb_hash_aset(CALLBACK_TABLE, id_num, cmd)
VALUE rb_cHash
Definition: hash.c:35
rb_iseq_t * iseq
Definition: vm_core.h:350
VALUE catch_table_ary
Definition: iseq.h:81
struct iseq_compile_data_storage * storage_head
Definition: iseq.h:93
Tcl_CmdInfo * info
Definition: tcltklib.c:1454
VALUE coverage
Definition: vm_core.h:175
int ret
Definition: tcltklib.c:276
static VALUE iseq_s_compile(int argc, VALUE *argv, VALUE self)
Definition: iseq.c:589
return ST_CONTINUE
Definition: tkutil.c:1273
VALUE rb_eTypeError
Definition: error.c:467
int rb_iseq_translate_threaded_code(rb_iseq_t *iseq)
Definition: compile.c:555
unsigned long VALUE
Definition: ruby.h:88
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:740
VALUE rb_str_concat(VALUE, VALUE)
Definition: string.c:2088
gz path
Definition: zlib.c:2040
VALUE rb_ary_tmp_new(long capa)
Definition: array.c:380
int local_table_size
Definition: vm_core.h:183
static int cdhash_each(VALUE key, VALUE value, VALUE ary)
Definition: iseq.c:1103
#define RSTRING_PTR(string)
Definition: generator.h:42
struct rb_iseq_struct * local_iseq
Definition: vm_core.h:232
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:515
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1574
#define RUBY_MARK_LEAVE(msg)
Definition: gc.h:54
return Qtrue
Definition: tcltklib.c:9597
struct iseq_compile_data_storage * next
Definition: iseq.h:71
unsigned short sp
Definition: iseq.h:49
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
struct iseq_inline_cache_entry * ic_entries
Definition: vm_core.h:188
#define RARRAY_LEN(ARRAY)
Definition: generator.h:39
size_t stack_max
Definition: vm_core.h:224
return str
Definition: ruby.c:1183
ID defined_method_id
Definition: vm_core.h:254
#define RUBY_GC_INFO
Definition: gc.h:57
#define T_ARRAY
Definition: ruby.h:420
r
Definition: bigdecimal.c:1154
VALUE rb_iseq_compile_node(VALUE self, NODE *node)
Definition: compile.c:462
#define st_lookup
Definition: regint.h:149
ID id
Definition: ripper.y:479
#define ALLOC_AND_COPY(dst, src, type, size)
VALUE rb_file_open_str(VALUE, const char *)
Definition: io.c:5142
static VALUE rb_iseq_new_with_bopt_and_opt(NODE *node, VALUE name, VALUE filename, VALUE filepath, VALUE line_no, VALUE parent, enum iseq_type type, VALUE bopt, const rb_compile_option_t *option)
Definition: iseq.c:404
#define FIXNUM_P(f)
Definition: ruby.h:338
VALUE tbl
Definition: tkutil.c:1279
int arg_post_len
Definition: vm_core.h:219
VALUE VALUE args
Definition: tcltklib.c:2550
VALUE orig
Definition: vm_core.h:239
#define ID2SYM(i)
Definition: cparse.c:63
const char * rb_obj_classname(VALUE)
Definition: variable.c:318
const rb_compile_option_t * option
Definition: iseq.h:99
#define GET_THREAD()
Definition: vm_core.h:690
rb_secure(4)
Definition: ripper.y:236
enum iseq_catch_table_entry::catch_type type
unsigned long pos
Definition: iseq.h:72
VALUE name
Definition: vm_core.h:168
#define OPT_STACK_CACHING
VALUE rb_cISeq
Definition: iseq.c:26
void rb_exc_raise(VALUE mesg)
Definition: eval.c:460
#define SET_COMPILE_OPTION_NUM(o, h, mem)
#define Qnil
Definition: ruby.h:367
VALUE * iseq
Definition: vm_core.h:171
static VALUE iseq_s_compile_file(int argc, VALUE *argv, VALUE self)
Definition: iseq.c:603
#define CHECK_SYMBOL(v)
Definition: iseq.c:441
enum rb_iseq_struct::iseq_type type
VALUE hash
Definition: tkutil.c:267
static VALUE iseq_load(VALUE self, VALUE data, VALUE parent, VALUE opt)
Definition: iseq.c:444
VALUE filename
Definition: vm_core.h:169
#define MEMZERO(p, type, n)
Definition: ruby.h:1052
static rb_compile_option_t COMPILE_OPTION_DEFAULT
Definition: iseq.c:303
memset(y->frac+ix+1, 0,(y->Prec-(ix+1))*sizeof(BDIGIT))
void * data
Definition: yaml2byte.c:131
NODE * rb_parser_compile_string(volatile VALUE vparser, const char *f, VALUE s, int line)
Definition: ripper.c:11617
Definition: iseq.h:54
return Qfalse
Definition: tcltklib.c:6768
NODE * cref_stack
Definition: vm_core.h:250
static VALUE CHECK_INTEGER(VALUE v)
Definition: iseq.c:442
#define ALLOC_N(type, n)
Definition: ruby.h:1034
VALUE mark_ary
Definition: iseq.h:80
Definition: ripper.y:477
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:1246
VALUE filepath
Definition: vm_core.h:170
#define PRIdVALUE
Definition: ruby.h:126
#define PARAM(i, type)
static VALUE register_label(struct st_table *table, unsigned long idx)
Definition: iseq.c:1074
#define NEW_BLOCK(a)
VALUE rb_str_cat2(VALUE, const char *)
Definition: string.c:1908
VALUE rb_ary_new(void)
Definition: array.c:339
static VALUE obj_resurrect(VALUE obj)
Definition: iseq.c:31
VALUE rb_iseq_new_top(NODE *node, VALUE name, VALUE filename, VALUE filepath, VALUE parent)
Definition: iseq.c:388
static VALUE make_compile_option_value(rb_compile_option_t *option)
Definition: iseq.c:357
VALUE rb_iseq_new_with_bopt(NODE *node, VALUE name, VALUE filename, VALUE filepath, VALUE line_no, VALUE parent, enum iseq_type type, VALUE bopt)
Definition: iseq.c:431
int argc
argument information
Definition: vm_core.h:214
#define snprintf
Definition: subst.h:6
int arg_post_start
Definition: vm_core.h:220
#define NIL_P(v)
Definition: ruby.h:374
static VALUE iseq_eval(VALUE self)
Definition: iseq.c:655
#define CHECK_ARRAY(v)
Definition: iseq.c:439
static VALUE VALUE obj
Definition: tcltklib.c:3147
void rb_ary_store(VALUE ary, long idx, VALUE val)
Definition: array.c:635
VALUE * arg_opt_table
Definition: vm_core.h:222
VALUE rb_cRubyVM
Definition: vm.c:35
#define RUBY_MARK_ENTER(msg)
Definition: gc.h:53
#define OBJ_UNTRUST(x)
Definition: ruby.h:966
volatile ID method
Definition: tcltklib.c:3588
static unsigned short find_prev_line_no(rb_iseq_t *iseqdat, unsigned long pos)
Definition: iseq.c:723
rb_block_t * base_block
Definition: vm_core.h:421
int err
Definition: win32.c:78
#define OBJ_FREEZE(x)
Definition: ruby.h:970
#define PRIdPTRDIFF
Definition: ruby.h:155
ID * local_table
Definition: vm_core.h:182
static int VALUE key
Definition: tkutil.c:265
static struct iseq_insn_info_entry * get_insn_info(const rb_iseq_t *iseq, const unsigned long pos)
Definition: iseq.c:696
Definition: error.c:344
unsigned long start
Definition: iseq.h:62
#define ALLOC(type)
Definition: ruby.h:1035
VALUE rb_str_resurrect(VALUE str)
Definition: string.c:911
void Init_ISeq(void)
Definition: iseq.c:1509
#define PRIuVALUE
Definition: ruby.h:129
#define OPT_INLINE_CONST_CACHE
VALUE rb_str_resize(VALUE, long)
Definition: string.c:1779
Definition: vm_core.h:128
static VALUE exception_type2symbol(VALUE type)
Definition: iseq.c:1086
gz level
Definition: zlib.c:2025
#define INIT_SYMBOL(name)
Definition: iseq.c:1070
VALUE * argv
Definition: tcltklib.c:1962
Definition: iseq.h:55
const int id
Definition: nkf.c:209
#define hidden_obj_p(obj)
Definition: iseq.c:28
Definition: iseq.h:59
VALUE rb_iseq_build_for_ruby2cext(const rb_iseq_t *iseq_template, const rb_insn_func_t *func, const struct iseq_insn_info_entry *insn_info_table, const char **local_table, const VALUE *arg_opt_table, const struct iseq_catch_table_entry *catch_table, const char *name, const char *filename, const unsigned short line_no)
Definition: iseq.c:1453
VALUE rb_obj_is_proc(VALUE)
Definition: proc.c:88
VALUE rb_funcall2(VALUE, ID, int, const VALUE *)
Calls a method.
Definition: vm_eval.c:669
VALUE rb_iseq_new_main(NODE *node, VALUE filename, VALUE filepath)
Definition: iseq.c:395
#define ISEQ_MINOR_VERSION
Definition: iseq.c:24
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1203
volatile VALUE value
Definition: tcltklib.c:9429
VALUE mark_ary
Definition: vm_core.h:174
static VALUE prepare_iseq_build(rb_iseq_t *iseq, VALUE name, VALUE filename, VALUE filepath, VALUE line_no, VALUE parent, enum iseq_type type, VALUE block_opt, const rb_compile_option_t *option)
Definition: iseq.c:226
register char * s
Definition: os2.c:56
VALUE rb_hash_new(void)
Definition: hash.c:229
void ruby_xfree(void *x)
Definition: gc.c:916
VALUE rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE locals, VALUE args, VALUE exception, VALUE body)
Definition: compile.c:5452
VP_EXPORT void
Definition: bigdecimal.c:4944
#define OPT_PEEPHOLE_OPTIMIZATION
static VALUE iseq_data_to_ary(rb_iseq_t *iseq)
Definition: iseq.c:1111
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1416
struct rb_iseq_struct * parent_iseq
Definition: vm_core.h:231
unsigned long ID
Definition: ruby.h:89
static VALUE iseq_s_compile_option_set(VALUE self, VALUE opt)
Definition: iseq.c:628
#define OPT_INSTRUCTIONS_UNIFICATION
int type
Definition: tcltklib.c:107
#define SET_COMPILE_OPTION(o, h, mem)
VALUE * iseq_encoded
Definition: vm_core.h:172
#define BUILTIN_TYPE(x)
Definition: ruby.h:438
int argc
Definition: tcltklib.c:1961
VALUE rb_iseq_eval(VALUE iseqval)
Definition: vm.c:1456
int catch_table_size
Definition: vm_core.h:228
#define RBASIC(obj)
Definition: ruby.h:904
Definition: iseq.h:52
#define FIX2INT(x)
Definition: ruby.h:538
rb_hash_foreach(tbl, each_attr_def, self)
register unsigned int len
Definition: name2ctype.h:22210
VALUE rb_iseq_load(VALUE data, VALUE parent, VALUE opt)
Definition: iseq.c:544
unsigned short line_no
Definition: vm_core.h:176
#define INITIAL_ISEQ_COMPILE_DATA_STORAGE_BUFF_SIZE
Definition: iseq.h:68
Definition: iseq.h:57
#define RARRAY_LENINT(ary)
Definition: ruby.h:718
VALUE err_info
Definition: iseq.h:79
VALUE rb_str_dup(VALUE)
Definition: string.c:905
return ptr
Definition: tcltklib.c:780
static VALUE cleanup_iseq_build(rb_iseq_t *iseq)
Definition: iseq.c:289
#define CHAR_BIT
Definition: ruby.h:192
long st_data_t
Definition: syck.h:69
#define PARAM_ID(i)
Definition: iseq.h:58
#define StringValueCStr(v)
Definition: ruby.h:468
static VALUE iseq_s_disasm(VALUE klass, VALUE body)
Definition: iseq.c:1034
static VALUE iseq_s_load(int argc, VALUE *argv, VALUE self)
Definition: iseq.c:535
#define RUBY_FREE_UNLESS_NULL(ptr)
Definition: gc.h:61
struct rb_iseq_struct rb_iseq_t
Definition: method.h:57
unsigned int top
Definition: nkf.c:3914
VALUE src
Definition: tcltklib.c:7940
static VALUE iseq_alloc(VALUE klass)
Definition: iseq.c:171
#define ISEQ_MAJOR_VERSION
Definition: iseq.c:23
unsigned long sp
Definition: iseq.h:65
VALUE rb_realpath_internal(VALUE basedir, VALUE path, int strict)
Definition: file.c:3447
static VALUE insn_operand_intern(rb_iseq_t *iseq, VALUE insn, int op_no, VALUE op, int len, size_t pos, VALUE *pnop, VALUE child)
Definition: iseq.c:743
int size
Definition: encoding.c:51
Definition: iseq.h:46
#define PARAM_TYPE(type)
#define INT2FIX(i)
Definition: ruby.h:225
VALUE top_wrapper
Definition: vm_core.h:418
rb_block_t block
Definition: vm_core.h:527
VALUE klass
Definition: vm_core.h:251
static NODE * parse_string(VALUE str, const char *file, int line)
Definition: iseq.c:550
#define st_init_numtable
Definition: regint.h:142
#define RUBY_FREE_LEAVE(msg)
Definition: gc.h:56
#define RUBY_FREE_ENTER(msg)
Definition: gc.h:55
const char * ruby_node_name(int node)
Definition: iseq.c:1057
VALUE rb_str_catf(VALUE str, const char *format,...)
Definition: sprintf.c:1239
struct iseq_compile_data_storage * storage_current
Definition: iseq.h:94
struct iseq_catch_table_entry * catch_table
Definition: vm_core.h:227
rb_control_frame_t *FUNC_FASTCALL rb_insn_func_t(rb_thread_t *, rb_control_frame_t *)
Definition: vm_core.h:605
VALUE rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE filepath, VALUE line, VALUE opt)
Definition: iseq.c:562
static VALUE iseq_to_a(VALUE self)
Definition: iseq.c:679
#define RTEST(v)
Definition: ruby.h:373
static VALUE iseq_inspect(VALUE self)
Definition: iseq.c:662
#define T_STRING
Definition: ruby.h:418
klass
Definition: tcltklib.c:3493
int local_size
Definition: vm_core.h:186
#define RUBY_MARK_UNLESS_NULL(ptr)
Definition: gc.h:60
size_t insn_info_size
Definition: vm_core.h:180
int last_coverable_line
Definition: iseq.h:96
static const rb_data_type_t iseq_data_type
Definition: iseq.c:161
unsigned long iseq_size
Definition: vm_core.h:173
#define TypedData_Make_Struct(klass, type, data_type, sval)
Definition: ruby.h:829
#define OPT_TRACE_INSTRUCTION
unsigned short line_no
Definition: iseq.h:48
#define OPT_OPERANDS_UNIFICATION
rb_iseq_t * rb_method_get_iseq(VALUE body)
Definition: proc.c:1704
#define OPT_TAILCALL_OPTIMIZATION
#define st_insert
Definition: regint.h:148
VALUE rb_ary_new2(long capa)
Definition: array.c:332
#define CHECK_STRING(v)
Definition: iseq.c:440
static const char * catch_type(int type)
Definition: iseq.c:909
VALUE rb_parser_new(void)
Definition: ripper.c:16587
struct parser_params * parser
Definition: ripper.c:4323
#define PRIdSIZE
Definition: ruby.h:170
int main(int argc, char **argv)
Definition: nkf.c:6446
VALUE self
Definition: vm_core.h:238
#define GetISeqPtr(obj, ptr)
Definition: vm_core.h:146
unsigned long cont
Definition: iseq.h:64
const char * rb_id2name(ID id)
Definition: ripper.c:16362
static const rb_compile_option_t COMPILE_OPTION_FALSE
Definition: iseq.c:313
#define st_free_table
Definition: regint.h:152
VALUE rb_inspect(VALUE)
Definition: object.c:372
VALUE iseq
Definition: iseq.h:61
VALUE opts
Definition: tcltklib.c:6135
#define CONST_ID(var, str)
Definition: ruby.h:1127
VALUE rb_iseq_new(NODE *node, VALUE name, VALUE filename, VALUE filepath, VALUE parent, enum iseq_type type)
Definition: iseq.c:380
struct iseq_insn_info_entry * insn_info_table
Definition: vm_core.h:179
Tcl_QueuePosition position
Definition: tcltklib.c:7605
ssize_t i
Definition: bigdecimal.c:5519
VALUE rb_ary_resurrect(VALUE ary)
Definition: array.c:1606
#define rb_intern(str)
BDIGIT v
Definition: bigdecimal.c:5520
const char * name
Definition: nkf.c:208
static void iseq_free(void *ptr)
Definition: iseq.c:62
Real * a
Definition: bigdecimal.c:1140
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1210
VALUE rb_iseq_disasm(VALUE self)
Definition: iseq.c:931
VALUE rb_str_new2(const char *)
VALUE rb_iseq_parameters(const rb_iseq_t *iseq, int is_proc)
Definition: iseq.c:1388
VALUE rb_iseq_new_with_opt(NODE *node, VALUE name, VALUE filename, VALUE filepath, VALUE line_no, VALUE parent, enum iseq_type type, const rb_compile_option_t *option)
Definition: iseq.c:421
static size_t iseq_memsize(const void *ptr)
Definition: iseq.c:126
VALUE rb_iseq_compile(VALUE src, VALUE file, VALUE line)
Definition: iseq.c:583
static void compile_data_free(struct iseq_compile_data *compile_data)
Definition: iseq.c:47
static rb_iseq_t * iseq_check(VALUE val)
Definition: iseq.c:644
#define StringValue(v)
Definition: ruby.h:466
static VALUE iseq_s_compile_option_get(VALUE self)
Definition: iseq.c:638
VALUE rb_iseq_clone(VALUE iseqval, VALUE newcbase)
Definition: iseq.c:1360
VALUE rb_str_new(const char *, long)
Definition: string.c:410