Ruby  2.0.0p353(2013-11-22revision43784)
vm_eval.c
Go to the documentation of this file.
1 /**********************************************************************
2 
3  vm_eval.c -
4 
5  $Author: nagachika $
6  created at: Sat May 24 16:02:32 JST 2008
7 
8  Copyright (C) 1993-2007 Yukihiro Matsumoto
9  Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
10  Copyright (C) 2000 Information-technology Promotion Agency, Japan
11 
12 **********************************************************************/
13 
14 static inline VALUE method_missing(VALUE obj, ID id, int argc, const VALUE *argv, int call_status);
15 static inline VALUE vm_yield_with_cref(rb_thread_t *th, int argc, const VALUE *argv, const NODE *cref);
16 static inline VALUE vm_yield(rb_thread_t *th, int argc, const VALUE *argv);
17 static NODE *vm_cref_push(rb_thread_t *th, VALUE klass, int noex, rb_block_t *blockptr);
18 static VALUE vm_exec(rb_thread_t *th);
19 static void vm_set_eval_stack(rb_thread_t * th, VALUE iseqval, const NODE *cref, rb_block_t *base_block);
21 
22 /* vm_backtrace.c */
23 VALUE vm_backtrace_str_ary(rb_thread_t *th, int lev, int n);
24 
25 typedef enum call_type {
30 } call_type;
31 
32 static VALUE send_internal(int argc, const VALUE *argv, VALUE recv, call_type scope);
33 
34 static VALUE vm_call0_body(rb_thread_t* th, rb_call_info_t *ci, const VALUE *argv);
35 
36 static VALUE
37 vm_call0(rb_thread_t* th, VALUE recv, ID id, int argc, const VALUE *argv,
38  const rb_method_entry_t *me, VALUE defined_class)
39 {
40  rb_call_info_t ci_entry, *ci = &ci_entry;
41 
42  ci->flag = 0;
43  ci->mid = id;
44  ci->recv = recv;
45  ci->defined_class = defined_class;
46  ci->argc = argc;
47  ci->me = me;
48 
49  return vm_call0_body(th, ci, argv);
50 }
51 
52 #if OPT_CALL_CFUNC_WITHOUT_FRAME
53 static VALUE
55 {
56  VALUE val;
57 
60  {
61  rb_control_frame_t *reg_cfp = th->cfp;
62  const rb_method_entry_t *me = ci->me;
63  const rb_method_cfunc_t *cfunc = &me->def->body.cfunc;
64  int len = cfunc->argc;
65 
66  if (len >= 0) rb_check_arity(ci->argc, len, len);
67 
68  th->passed_ci = ci;
69  ci->aux.inc_sp = 0;
70  VM_PROFILE_UP(2);
71  val = (*cfunc->invoker)(cfunc->func, ci, argv);
72 
73  if (reg_cfp == th->cfp) {
74  if (UNLIKELY(th->passed_ci != ci)) {
75  rb_bug("vm_call0_cfunc: passed_ci error (ci: %p, passed_ci: %p)", ci, th->passed_ci);
76  }
77  th->passed_ci = 0;
78  }
79  else {
80  if (reg_cfp != th->cfp + 1) {
81  rb_bug("vm_call0_cfunc: cfp consistency error");
82  }
83  VM_PROFILE_UP(3);
84  vm_pop_frame(th);
85  }
86  }
87  EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, ci->recv, ci->mid, ci->defined_class, val);
89 
90  return val;
91 }
92 #else
93 static VALUE
95 {
96  VALUE val;
97  const rb_method_entry_t *me = ci->me;
98  const rb_method_cfunc_t *cfunc = &me->def->body.cfunc;
99  int len = cfunc->argc;
100  VALUE recv = ci->recv;
101  VALUE defined_class = ci->defined_class;
102  int argc = ci->argc;
103  ID mid = ci->mid;
104  rb_block_t *blockptr = ci->blockptr;
105 
106  RUBY_DTRACE_CMETHOD_ENTRY_HOOK(th, defined_class, mid);
107  EXEC_EVENT_HOOK(th, RUBY_EVENT_C_CALL, recv, mid, defined_class, Qnil);
108  {
109  rb_control_frame_t *reg_cfp = th->cfp;
110 
111  vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC, recv, defined_class,
112  VM_ENVVAL_BLOCK_PTR(blockptr), 0, reg_cfp->sp, 1, me);
113 
114  if (len >= 0) rb_check_arity(argc, len, len);
115 
116  VM_PROFILE_UP(2);
117  val = (*cfunc->invoker)(cfunc->func, recv, argc, argv);
118 
119  if (UNLIKELY(reg_cfp != th->cfp + 1)) {
120  rb_bug("vm_call0_cfunc_with_frame: cfp consistency error");
121  }
122  VM_PROFILE_UP(3);
123  vm_pop_frame(th);
124  }
125  EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, recv, mid, defined_class, val);
126  RUBY_DTRACE_CMETHOD_RETURN_HOOK(th, defined_class, mid);
127 
128  return val;
129 }
130 
131 static VALUE
133 {
134  return vm_call0_cfunc_with_frame(th, ci, argv);
135 }
136 #endif
137 
138 /* `ci' should point temporal value (on stack value) */
139 static VALUE
141 {
142  VALUE ret;
143 
144  if (!ci->me->def) return Qnil;
145 
146  if (th->passed_block) {
147  ci->blockptr = (rb_block_t *)th->passed_block;
148  th->passed_block = 0;
149  }
150  else {
151  ci->blockptr = 0;
152  }
153 
154  again:
155  switch (ci->me->def->type) {
156  case VM_METHOD_TYPE_ISEQ:
157  {
158  rb_control_frame_t *reg_cfp = th->cfp;
159  int i;
160 
161  CHECK_VM_STACK_OVERFLOW(reg_cfp, ci->argc + 1);
162 
163  *reg_cfp->sp++ = ci->recv;
164  for (i = 0; i < ci->argc; i++) {
165  *reg_cfp->sp++ = argv[i];
166  }
167 
168  vm_call_iseq_setup(th, reg_cfp, ci);
169  th->cfp->flag |= VM_FRAME_FLAG_FINISH;
170  return vm_exec(th); /* CHECK_INTS in this function */
171  }
174  ret = vm_call0_cfunc(th, ci, argv);
175  goto success;
177  rb_check_arity(ci->argc, 1, 1);
178  ret = rb_ivar_set(ci->recv, ci->me->def->body.attr.id, argv[0]);
179  goto success;
180  case VM_METHOD_TYPE_IVAR:
181  rb_check_arity(ci->argc, 0, 0);
182  ret = rb_attr_get(ci->recv, ci->me->def->body.attr.id);
183  goto success;
185  ret = vm_call_bmethod_body(th, ci, argv);
186  goto success;
189  {
190  if (ci->me->def->type == VM_METHOD_TYPE_REFINED &&
191  ci->me->def->body.orig_me) {
192  ci->me = ci->me->def->body.orig_me;
193  goto again;
194  }
195 
197 
198  if (!ci->defined_class || !(ci->me = rb_method_entry(ci->defined_class, ci->mid, &ci->defined_class))) {
199  ret = method_missing(ci->recv, ci->mid, ci->argc, argv, NOEX_SUPER);
200  goto success;
201  }
202  RUBY_VM_CHECK_INTS(th);
203  if (!ci->me->def) return Qnil;
204  goto again;
205  }
207  {
208  VALUE new_args = rb_ary_new4(ci->argc, argv);
209 
210  RB_GC_GUARD(new_args);
211  rb_ary_unshift(new_args, ID2SYM(ci->mid));
212  th->passed_block = ci->blockptr;
213  return rb_funcall2(ci->recv, idMethodMissing, ci->argc+1, RARRAY_PTR(new_args));
214  }
216  switch (ci->me->def->body.optimize_type) {
217  case OPTIMIZED_METHOD_TYPE_SEND:
218  ret = send_internal(ci->argc, argv, ci->recv, CALL_FCALL);
219  goto success;
220  case OPTIMIZED_METHOD_TYPE_CALL:
221  {
222  rb_proc_t *proc;
223  GetProcPtr(ci->recv, proc);
224  ret = rb_vm_invoke_proc(th, proc, ci->argc, argv, ci->blockptr);
225  goto success;
226  }
227  default:
228  rb_bug("vm_call0: unsupported optimized method type (%d)", ci->me->def->body.optimize_type);
229  }
230  break;
232  break;
233  }
234  rb_bug("vm_call0: unsupported method type (%d)", ci->me->def->type);
235  return Qundef;
236 
237  success:
238  RUBY_VM_CHECK_INTS(th);
239  return ret;
240 }
241 
242 VALUE
243 rb_vm_call(rb_thread_t *th, VALUE recv, VALUE id, int argc, const VALUE *argv,
244  const rb_method_entry_t *me, VALUE defined_class)
245 {
246  return vm_call0(th, recv, id, argc, argv, me, defined_class);
247 }
248 
249 static inline VALUE
250 vm_call_super(rb_thread_t *th, int argc, const VALUE *argv)
251 {
252  VALUE recv = th->cfp->self;
253  VALUE klass;
254  ID id;
255  rb_method_entry_t *me;
256  rb_control_frame_t *cfp = th->cfp;
257 
258  if (cfp->iseq || NIL_P(cfp->klass)) {
259  rb_bug("vm_call_super: should not be reached");
260  }
261 
262  klass = RCLASS_SUPER(cfp->klass);
263  id = cfp->me->def->original_id;
264  me = rb_method_entry(klass, id, &klass);
265  if (!me) {
266  return method_missing(recv, id, argc, argv, NOEX_SUPER);
267  }
268 
269  return vm_call0(th, recv, id, argc, argv, me, klass);
270 }
271 
272 VALUE
273 rb_call_super(int argc, const VALUE *argv)
274 {
276  return vm_call_super(GET_THREAD(), argc, argv);
277 }
278 
279 static inline void
281 {
282  rb_thread_t *th = GET_THREAD();
283 
287  }
288 }
289 
290 static inline rb_method_entry_t *
291  rb_search_method_entry(VALUE recv, ID mid, VALUE *defined_class_ptr);
292 static inline int rb_method_call_status(rb_thread_t *th, const rb_method_entry_t *me, call_type scope, VALUE self);
293 #define NOEX_OK NOEX_NOSUPER
294 
310 static inline VALUE
311 rb_call0(VALUE recv, ID mid, int argc, const VALUE *argv,
312  call_type scope, VALUE self)
313 {
314  VALUE defined_class;
315  rb_method_entry_t *me =
316  rb_search_method_entry(recv, mid, &defined_class);
317  rb_thread_t *th = GET_THREAD();
318  int call_status = rb_method_call_status(th, me, scope, self);
319 
320  if (call_status != NOEX_OK) {
321  return method_missing(recv, mid, argc, argv, call_status);
322  }
323  stack_check();
324  return vm_call0(th, recv, mid, argc, argv, me, defined_class);
325 }
326 
330  int argc;
332 };
333 
334 static VALUE
336 {
337  VALUE new_args = rb_ary_new4(args->argc, args->argv);
338 
339  RB_GC_GUARD(new_args);
340  rb_ary_unshift(new_args, args->sym);
341  return rb_funcall2(args->recv, idMethodMissing,
342  args->argc+1, RARRAY_PTR(new_args));
343 }
344 
345 static VALUE
347 {
348  if (rb_respond_to(args->recv, SYM2ID(args->sym))) {
349  rb_exc_raise(e);
350  }
351  return Qundef;
352 }
353 
354 static int
356 {
357  VALUE defined_class;
358  const rb_method_entry_t *me = rb_method_entry(klass, idRespond_to, &defined_class);
359 
360  if (me && !(me->flag & NOEX_BASIC)) {
361  const rb_block_t *passed_block = th->passed_block;
362  VALUE args[2], result;
363  int arity = rb_method_entry_arity(me);
364 
365  if (arity > 2)
366  rb_raise(rb_eArgError, "respond_to? must accept 1 or 2 arguments (requires %d)", arity);
367 
368  if (arity < 1) arity = 2;
369 
370  args[0] = ID2SYM(mid);
371  args[1] = Qtrue;
372  result = vm_call0(th, recv, idRespond_to, arity, args, me, defined_class);
373  th->passed_block = passed_block;
374  if (!RTEST(result)) {
375  return FALSE;
376  }
377  }
378  return TRUE;
379 }
380 
381 static int
383 {
384  return rb_method_call_status(th, me, CALL_FCALL, th->cfp->self) == NOEX_OK;
385 }
386 
387 static VALUE
388 check_funcall_missing(rb_thread_t *th, VALUE klass, VALUE recv, ID mid, int argc, VALUE *argv)
389 {
390  if (rb_method_basic_definition_p(klass, idMethodMissing)) {
391  return Qundef;
392  }
393  else {
394  struct rescue_funcall_args args;
395 
396  th->method_missing_reason = 0;
397  args.recv = recv;
398  args.sym = ID2SYM(mid);
399  args.argc = argc;
400  args.argv = argv;
401  return rb_rescue2(check_funcall_exec, (VALUE)&args,
402  check_funcall_failed, (VALUE)&args,
404  }
405 }
406 
407 VALUE
409 {
410  VALUE klass = CLASS_OF(recv);
411  const rb_method_entry_t *me;
412  rb_thread_t *th = GET_THREAD();
413  VALUE defined_class;
414 
415  if (!check_funcall_respond_to(th, klass, recv, mid))
416  return Qundef;
417 
418  me = rb_search_method_entry(recv, mid, &defined_class);
419  if (check_funcall_callable(th, me) != NOEX_OK) {
420  return check_funcall_missing(th, klass, recv, mid, argc, argv);
421  }
422  stack_check();
423  return vm_call0(th, recv, mid, argc, argv, me, defined_class);
424 }
425 
426 VALUE
428  rb_check_funcall_hook *hook, VALUE arg)
429 {
430  VALUE klass = CLASS_OF(recv);
431  const rb_method_entry_t *me;
432  rb_thread_t *th = GET_THREAD();
433  VALUE defined_class;
434 
435  if (!check_funcall_respond_to(th, klass, recv, mid))
436  return Qundef;
437 
438  me = rb_search_method_entry(recv, mid, &defined_class);
439  if (check_funcall_callable(th, me) != NOEX_OK) {
440  (*hook)(FALSE, recv, mid, argc, argv, arg);
441  return check_funcall_missing(th, klass, recv, mid, argc, argv);
442  }
443  stack_check();
444  (*hook)(TRUE, recv, mid, argc, argv, arg);
445  return vm_call0(th, recv, mid, argc, argv, me, defined_class);
446 }
447 
448 static const char *
450 {
451 #define type_case(t) case t: return #t;
452  switch (type) {
478  default: return NULL;
479  }
480 #undef type_case
481 }
482 
483 static inline rb_method_entry_t *
484 rb_search_method_entry(VALUE recv, ID mid, VALUE *defined_class_ptr)
485 {
486  VALUE klass = CLASS_OF(recv);
487 
488  if (!klass) {
489  VALUE flags, klass;
490  if (IMMEDIATE_P(recv)) {
492  "method `%s' called on unexpected immediate object (%p)",
493  rb_id2name(mid), (void *)recv);
494  }
495  flags = RBASIC(recv)->flags;
496  klass = RBASIC(recv)->klass;
497  if (flags == 0) {
499  "method `%s' called on terminated object"
500  " (%p flags=0x%"PRIxVALUE" klass=0x%"PRIxVALUE")",
501  rb_id2name(mid), (void *)recv, flags, klass);
502  }
503  else {
504  int type = BUILTIN_TYPE(recv);
505  const char *typestr = rb_type_str(type);
506  if (typestr && T_OBJECT <= type && type < T_NIL)
508  "method `%s' called on hidden %s object"
509  " (%p flags=0x%"PRIxVALUE" klass=0x%"PRIxVALUE")",
510  rb_id2name(mid), typestr, (void *)recv, flags, klass);
511  if (typestr)
513  "method `%s' called on unexpected %s object"
514  " (%p flags=0x%"PRIxVALUE" klass=0x%"PRIxVALUE")",
515  rb_id2name(mid), typestr, (void *)recv, flags, klass);
516  else
518  "method `%s' called on broken T_???" "(0x%02x) object"
519  " (%p flags=0x%"PRIxVALUE" klass=0x%"PRIxVALUE")",
520  rb_id2name(mid), type, (void *)recv, flags, klass);
521  }
522  }
523  return rb_method_entry(klass, mid, defined_class_ptr);
524 }
525 
526 static inline int
528 {
529  VALUE klass;
530  ID oid;
531  int noex;
532 
533  if (UNDEFINED_METHOD_ENTRY_P(me)) {
534  return scope == CALL_VCALL ? NOEX_VCALL : 0;
535  }
536  klass = me->klass;
537  oid = me->def->original_id;
538  noex = me->flag;
539 
540  if (oid != idMethodMissing) {
541  /* receiver specified form for private method */
542  if (UNLIKELY(noex)) {
543  if (((noex & NOEX_MASK) & NOEX_PRIVATE) && scope == CALL_PUBLIC) {
544  return NOEX_PRIVATE;
545  }
546 
547  /* self must be kind of a specified form for protected method */
548  if (((noex & NOEX_MASK) & NOEX_PROTECTED) && scope == CALL_PUBLIC) {
549  VALUE defined_class = klass;
550 
551  if (RB_TYPE_P(defined_class, T_ICLASS)) {
552  defined_class = RBASIC(defined_class)->klass;
553  }
554 
555  if (self == Qundef || !rb_obj_is_kind_of(self, defined_class)) {
556  return NOEX_PROTECTED;
557  }
558  }
559 
560  if (NOEX_SAFE(noex) > th->safe_level) {
561  rb_raise(rb_eSecurityError, "calling insecure method: %s",
562  rb_id2name(me->called_id));
563  }
564  }
565  }
566  return NOEX_OK;
567 }
568 
569 
581 static inline VALUE
582 rb_call(VALUE recv, ID mid, int argc, const VALUE *argv, call_type scope)
583 {
584  rb_thread_t *th = GET_THREAD();
585  return rb_call0(recv, mid, argc, argv, scope, th->cfp->self);
586 }
587 
588 NORETURN(static void raise_method_missing(rb_thread_t *th, int argc, const VALUE *argv,
589  VALUE obj, int call_status));
590 
591 /*
592  * call-seq:
593  * obj.method_missing(symbol [, *args] ) -> result
594  *
595  * Invoked by Ruby when <i>obj</i> is sent a message it cannot handle.
596  * <i>symbol</i> is the symbol for the method called, and <i>args</i>
597  * are any arguments that were passed to it. By default, the interpreter
598  * raises an error when this method is called. However, it is possible
599  * to override the method to provide more dynamic behavior.
600  * If it is decided that a particular method should not be handled, then
601  * <i>super</i> should be called, so that ancestors can pick up the
602  * missing method.
603  * The example below creates
604  * a class <code>Roman</code>, which responds to methods with names
605  * consisting of roman numerals, returning the corresponding integer
606  * values.
607  *
608  * class Roman
609  * def roman_to_int(str)
610  * # ...
611  * end
612  * def method_missing(methId)
613  * str = methId.id2name
614  * roman_to_int(str)
615  * end
616  * end
617  *
618  * r = Roman.new
619  * r.iv #=> 4
620  * r.xxiii #=> 23
621  * r.mm #=> 2000
622  */
623 
624 static VALUE
625 rb_method_missing(int argc, const VALUE *argv, VALUE obj)
626 {
627  rb_thread_t *th = GET_THREAD();
628  raise_method_missing(th, argc, argv, obj, th->method_missing_reason);
629  UNREACHABLE;
630 }
631 
632 #define NOEX_MISSING 0x80
633 
634 static VALUE
635 make_no_method_exception(VALUE exc, const char *format, VALUE obj, int argc, const VALUE *argv)
636 {
637  int n = 0;
638  VALUE mesg;
639  VALUE args[3];
640 
641  if (!format) {
642  format = "undefined method `%s' for %s";
643  }
644  mesg = rb_const_get(exc, rb_intern("message"));
645  if (rb_method_basic_definition_p(CLASS_OF(mesg), '!')) {
646  args[n++] = rb_name_err_mesg_new(mesg, rb_str_new2(format), obj, argv[0]);
647  }
648  else {
649  args[n++] = rb_funcall(mesg, '!', 3, rb_str_new2(format), obj, argv[0]);
650  }
651  args[n++] = argv[0];
652  if (exc == rb_eNoMethodError) {
653  args[n++] = rb_ary_new4(argc - 1, argv + 1);
654  }
655  return rb_class_new_instance(n, args, exc);
656 }
657 
658 static void
659 raise_method_missing(rb_thread_t *th, int argc, const VALUE *argv, VALUE obj,
660  int last_call_status)
661 {
662  VALUE exc = rb_eNoMethodError;
663  const char *format = 0;
664 
665  if (argc == 0 || !SYMBOL_P(argv[0])) {
666  rb_raise(rb_eArgError, "no id given");
667  }
668 
669  stack_check();
670 
671  if (last_call_status & NOEX_PRIVATE) {
672  format = "private method `%s' called for %s";
673  }
674  else if (last_call_status & NOEX_PROTECTED) {
675  format = "protected method `%s' called for %s";
676  }
677  else if (last_call_status & NOEX_VCALL) {
678  format = "undefined local variable or method `%s' for %s";
679  exc = rb_eNameError;
680  }
681  else if (last_call_status & NOEX_SUPER) {
682  format = "super: no superclass method `%s' for %s";
683  }
684 
685  {
686  exc = make_no_method_exception(exc, format, obj, argc, argv);
687  if (!(last_call_status & NOEX_MISSING)) {
689  }
690  rb_exc_raise(exc);
691  }
692 }
693 
694 static inline VALUE
695 method_missing(VALUE obj, ID id, int argc, const VALUE *argv, int call_status)
696 {
697  VALUE *nargv, result, argv_ary = 0;
698  rb_thread_t *th = GET_THREAD();
699  const rb_block_t *blockptr = th->passed_block;
700 
701  th->method_missing_reason = call_status;
702  th->passed_block = 0;
703 
704  if (id == idMethodMissing) {
705  raise_method_missing(th, argc, argv, obj, call_status | NOEX_MISSING);
706  }
707 
708  if (argc < 0x100) {
709  nargv = ALLOCA_N(VALUE, argc + 1);
710  }
711  else {
712  argv_ary = rb_ary_tmp_new(argc + 1);
713  nargv = RARRAY_PTR(argv_ary);
714  }
715  nargv[0] = ID2SYM(id);
716  MEMCPY(nargv + 1, argv, VALUE, argc);
717  if (argv_ary) rb_ary_set_len(argv_ary, argc + 1);
718 
719  if (rb_method_basic_definition_p(CLASS_OF(obj) , idMethodMissing)) {
720  raise_method_missing(th, argc+1, nargv, obj, call_status | NOEX_MISSING);
721  }
722  th->passed_block = blockptr;
723  result = rb_funcall2(obj, idMethodMissing, argc + 1, nargv);
724  if (argv_ary) rb_ary_clear(argv_ary);
725  return result;
726 }
727 
728 void
730  VALUE obj, int call_status)
731 {
732  th->passed_block = 0;
733  raise_method_missing(th, argc, argv, obj, call_status | NOEX_MISSING);
734 }
735 
744 VALUE
746 {
747  int argc;
748  VALUE *argv, ret;
749 
750  argc = RARRAY_LENINT(args);
751  if (argc >= 0x100) {
752  args = rb_ary_subseq(args, 0, argc);
753  RBASIC(args)->klass = 0;
754  OBJ_FREEZE(args);
755  ret = rb_call(recv, mid, argc, RARRAY_PTR(args), CALL_FCALL);
756  RB_GC_GUARD(args);
757  return ret;
758  }
759  argv = ALLOCA_N(VALUE, argc);
760  MEMCPY(argv, RARRAY_PTR(args), VALUE, argc);
761  return rb_call(recv, mid, argc, argv, CALL_FCALL);
762 }
763 
773 VALUE
774 rb_funcall(VALUE recv, ID mid, int n, ...)
775 {
776  VALUE *argv;
777  va_list ar;
778 
779  if (n > 0) {
780  long i;
781 
782  va_init_list(ar, n);
783 
784  argv = ALLOCA_N(VALUE, n);
785 
786  for (i = 0; i < n; i++) {
787  argv[i] = va_arg(ar, VALUE);
788  }
789  va_end(ar);
790  }
791  else {
792  argv = 0;
793  }
794  return rb_call(recv, mid, n, argv, CALL_FCALL);
795 }
796 
804 VALUE
805 rb_funcall2(VALUE recv, ID mid, int argc, const VALUE *argv)
806 {
807  return rb_call(recv, mid, argc, argv, CALL_FCALL);
808 }
809 
819 VALUE
820 rb_funcall3(VALUE recv, ID mid, int argc, const VALUE *argv)
821 {
822  return rb_call(recv, mid, argc, argv, CALL_PUBLIC);
823 }
824 
825 VALUE
827 {
829 
830  return rb_call(recv, mid, argc, argv, CALL_PUBLIC);
831 }
832 
833 VALUE
834 rb_funcall_with_block(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE pass_procval)
835 {
836  if (!NIL_P(pass_procval)) {
837  rb_thread_t *th = GET_THREAD();
838  rb_block_t *block = 0;
839 
840  rb_proc_t *pass_proc;
841  GetProcPtr(pass_procval, pass_proc);
842  block = &pass_proc->block;
843 
844  th->passed_block = block;
845  }
846 
847  return rb_call(recv, mid, argc, argv, CALL_PUBLIC);
848 }
849 
850 static VALUE
851 send_internal(int argc, const VALUE *argv, VALUE recv, call_type scope)
852 {
853  ID id;
854  VALUE vid;
855  VALUE self;
856  rb_thread_t *th = GET_THREAD();
857 
858  if (scope == CALL_PUBLIC) {
859  self = Qundef;
860  }
861  else {
862  self = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp)->self;
863  }
864 
865  if (argc == 0) {
866  rb_raise(rb_eArgError, "no method name given");
867  }
868 
869  vid = *argv++; argc--;
870 
871  id = rb_check_id(&vid);
872  if (!id) {
873  if (rb_method_basic_definition_p(CLASS_OF(recv), idMethodMissing)) {
875  recv, ++argc, --argv);
876  rb_exc_raise(exc);
877  }
878  id = rb_to_id(vid);
879  }
881  return rb_call0(recv, id, argc, argv, scope, self);
882 }
883 
884 /*
885  * call-seq:
886  * foo.send(symbol [, args...]) -> obj
887  * foo.__send__(symbol [, args...]) -> obj
888  *
889  * Invokes the method identified by _symbol_, passing it any
890  * arguments specified. You can use <code>__send__</code> if the name
891  * +send+ clashes with an existing method in _obj_.
892  *
893  * class Klass
894  * def hello(*args)
895  * "Hello " + args.join(' ')
896  * end
897  * end
898  * k = Klass.new
899  * k.send :hello, "gentle", "readers" #=> "Hello gentle readers"
900  */
901 
902 VALUE
904 {
905  return send_internal(argc, argv, recv, CALL_FCALL);
906 }
907 
908 /*
909  * call-seq:
910  * obj.public_send(symbol [, args...]) -> obj
911  *
912  * Invokes the method identified by _symbol_, passing it any
913  * arguments specified. Unlike send, public_send calls public
914  * methods only.
915  *
916  * 1.public_send(:puts, "hello") # causes NoMethodError
917  */
918 
919 VALUE
921 {
922  return send_internal(argc, argv, recv, CALL_PUBLIC);
923 }
924 
925 /* yield */
926 
927 static inline VALUE
928 rb_yield_0(int argc, const VALUE * argv)
929 {
930  return vm_yield(GET_THREAD(), argc, argv);
931 }
932 
933 VALUE
935 {
936  if (val == Qundef) {
937  return rb_yield_0(0, 0);
938  }
939  else {
940  return rb_yield_0(1, &val);
941  }
942 }
943 
944 VALUE
945 rb_yield_values(int n, ...)
946 {
947  if (n == 0) {
948  return rb_yield_0(0, 0);
949  }
950  else {
951  int i;
952  VALUE *argv;
953  va_list args;
954  argv = ALLOCA_N(VALUE, n);
955 
956  va_init_list(args, n);
957  for (i=0; i<n; i++) {
958  argv[i] = va_arg(args, VALUE);
959  }
960  va_end(args);
961 
962  return rb_yield_0(n, argv);
963  }
964 }
965 
966 VALUE
967 rb_yield_values2(int argc, const VALUE *argv)
968 {
969  return rb_yield_0(argc, argv);
970 }
971 
972 VALUE
974 {
975  VALUE tmp = rb_check_array_type(values);
976  volatile VALUE v;
977  if (NIL_P(tmp)) {
978  rb_raise(rb_eArgError, "not an array");
979  }
980  v = rb_yield_0(RARRAY_LENINT(tmp), RARRAY_PTR(tmp));
981  return v;
982 }
983 
984 static VALUE
985 loop_i(void)
986 {
987  for (;;) {
988  rb_yield_0(0, 0);
989  }
990  return Qnil;
991 }
992 
993 static VALUE
995 {
996  return DBL2NUM(INFINITY);
997 }
998 
999 /*
1000  * call-seq:
1001  * loop { block }
1002  * loop -> an_enumerator
1003  *
1004  * Repeatedly executes the block.
1005  *
1006  * If no block is given, an enumerator is returned instead.
1007  *
1008  * loop do
1009  * print "Input: "
1010  * line = gets
1011  * break if !line or line =~ /^qQ/
1012  * # ...
1013  * end
1014  *
1015  * StopIteration raised in the block breaks the loop.
1016  */
1017 
1018 static VALUE
1020 {
1022  rb_rescue2(loop_i, (VALUE)0, 0, 0, rb_eStopIteration, (VALUE)0);
1023  return Qnil; /* dummy */
1024 }
1025 
1026 #if VMDEBUG
1027 static const char *
1028 vm_frametype_name(const rb_control_frame_t *cfp);
1029 #endif
1030 
1031 VALUE
1032 rb_iterate(VALUE (* it_proc) (VALUE), VALUE data1,
1033  VALUE (* bl_proc) (ANYARGS), VALUE data2)
1034 {
1035  int state;
1036  volatile VALUE retval = Qnil;
1037  NODE *node = NEW_IFUNC(bl_proc, data2);
1038  rb_thread_t *th = GET_THREAD();
1039  rb_control_frame_t *volatile cfp = th->cfp;
1040 
1041  node->nd_aid = rb_frame_this_func();
1042  TH_PUSH_TAG(th);
1043  state = TH_EXEC_TAG();
1044  if (state == 0) {
1045  iter_retry:
1046  {
1047  rb_block_t *blockptr;
1048  if (bl_proc) {
1049  blockptr = RUBY_VM_GET_BLOCK_PTR_IN_CFP(th->cfp);
1050  blockptr->iseq = (void *)node;
1051  blockptr->proc = 0;
1052  }
1053  else {
1054  blockptr = VM_CF_BLOCK_PTR(th->cfp);
1055  }
1056  th->passed_block = blockptr;
1057  }
1058  retval = (*it_proc) (data1);
1059  }
1060  else {
1061  VALUE err = th->errinfo;
1062  if (state == TAG_BREAK) {
1063  VALUE *escape_ep = GET_THROWOBJ_CATCH_POINT(err);
1064  VALUE *cep = cfp->ep;
1065 
1066  if (cep == escape_ep) {
1067  state = 0;
1068  th->state = 0;
1069  th->errinfo = Qnil;
1070  retval = GET_THROWOBJ_VAL(err);
1071 
1072  /* check skipped frame */
1073  while (th->cfp != cfp) {
1074 #if VMDEBUG
1075  printf("skipped frame: %s\n", vm_frametype_name(th->cfp));
1076 #endif
1078  const rb_method_entry_t *me = th->cfp->me;
1081  }
1082 
1084  }
1085  }
1086  else{
1087  /* SDR(); printf("%p, %p\n", cdfp, escape_dfp); */
1088  }
1089  }
1090  else if (state == TAG_RETRY) {
1091  VALUE *escape_ep = GET_THROWOBJ_CATCH_POINT(err);
1092  VALUE *cep = cfp->ep;
1093 
1094  if (cep == escape_ep) {
1095  state = 0;
1096  th->state = 0;
1097  th->errinfo = Qnil;
1098  th->cfp = cfp;
1099  goto iter_retry;
1100  }
1101  }
1102  }
1103  TH_POP_TAG();
1104 
1105  switch (state) {
1106  case 0:
1107  break;
1108  default:
1109  TH_JUMP_TAG(th, state);
1110  }
1111  return retval;
1112 }
1113 
1117  int argc;
1119 };
1120 
1121 static VALUE
1123 {
1124  const struct iter_method_arg * arg =
1125  (struct iter_method_arg *) obj;
1126 
1127  return rb_call(arg->obj, arg->mid, arg->argc, arg->argv, CALL_FCALL);
1128 }
1129 
1130 VALUE
1132  VALUE (*bl_proc) (ANYARGS), VALUE data2)
1133 {
1134  struct iter_method_arg arg;
1135 
1136  arg.obj = obj;
1137  arg.mid = mid;
1138  arg.argc = argc;
1139  arg.argv = argv;
1140  return rb_iterate(iterate_method, (VALUE)&arg, bl_proc, data2);
1141 }
1142 
1143 static VALUE
1145 {
1146  const struct iter_method_arg * arg =
1147  (struct iter_method_arg *) obj;
1148 
1149  return rb_check_funcall(arg->obj, arg->mid, arg->argc, arg->argv);
1150 }
1151 
1152 VALUE
1153 rb_check_block_call(VALUE obj, ID mid, int argc, VALUE * argv,
1154  VALUE (*bl_proc) (ANYARGS), VALUE data2)
1155 {
1156  struct iter_method_arg arg;
1157 
1158  arg.obj = obj;
1159  arg.mid = mid;
1160  arg.argc = argc;
1161  arg.argv = argv;
1162  return rb_iterate(iterate_check_method, (VALUE)&arg, bl_proc, data2);
1163 }
1164 
1165 VALUE
1167 {
1168  return rb_call(obj, idEach, 0, 0, CALL_FCALL);
1169 }
1170 
1171 static VALUE
1172 eval_string_with_cref(VALUE self, VALUE src, VALUE scope, NODE *cref, const char *volatile file, volatile int line)
1173 {
1174  int state;
1175  VALUE result = Qundef;
1176  VALUE envval;
1177  rb_thread_t *th = GET_THREAD();
1178  rb_env_t *env = NULL;
1179  rb_block_t block, *base_block;
1180  volatile int parse_in_eval;
1181  volatile int mild_compile_error;
1182 
1183  if (file == 0) {
1184  file = rb_sourcefile();
1185  line = rb_sourceline();
1186  }
1187 
1188  parse_in_eval = th->parse_in_eval;
1189  mild_compile_error = th->mild_compile_error;
1190  TH_PUSH_TAG(th);
1191  if ((state = TH_EXEC_TAG()) == 0) {
1192  rb_binding_t *bind = 0;
1193  rb_iseq_t *iseq;
1194  volatile VALUE iseqval;
1195  VALUE absolute_path = Qnil;
1196 
1197  if (scope != Qnil) {
1198  if (rb_obj_is_kind_of(scope, rb_cBinding)) {
1199  GetBindingPtr(scope, bind);
1200  envval = bind->env;
1201  if (strcmp(file, "(eval)") != 0) {
1202  absolute_path = rb_str_new_cstr(file);
1203  }
1204  else if (bind->path != Qnil) {
1205  file = RSTRING_PTR(bind->path);
1206  line = bind->first_lineno;
1207  absolute_path = rb_current_realfilepath();
1208  }
1209  }
1210  else {
1212  "wrong argument type %s (expected Binding)",
1213  rb_obj_classname(scope));
1214  }
1215  GetEnvPtr(envval, env);
1216  base_block = &env->block;
1217  }
1218  else {
1220 
1221  if (cfp != 0) {
1222  block = *RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp);
1223  base_block = &block;
1224  base_block->self = self;
1225  base_block->iseq = cfp->iseq; /* TODO */
1226  }
1227  else {
1228  rb_raise(rb_eRuntimeError, "Can't eval on top of Fiber or Thread");
1229  }
1230  }
1231 
1232  /* make eval iseq */
1233  th->parse_in_eval++;
1234  th->mild_compile_error++;
1235  iseqval = rb_iseq_compile_with_option(src, rb_str_new2(file), absolute_path, INT2FIX(line), base_block, Qnil);
1236  th->mild_compile_error--;
1237  th->parse_in_eval--;
1238 
1239  vm_set_eval_stack(th, iseqval, cref, base_block);
1240 
1241  if (0) { /* for debug */
1242  VALUE disasm = rb_iseq_disasm(iseqval);
1243  printf("%s\n", StringValuePtr(disasm));
1244  }
1245 
1246  /* save new env */
1247  GetISeqPtr(iseqval, iseq);
1248  if (bind && iseq->local_table_size > 0) {
1249  bind->env = rb_vm_make_env_object(th, th->cfp);
1250  }
1251 
1252  /* kick */
1254  result = vm_exec(th);
1255  }
1256  TH_POP_TAG();
1257  th->mild_compile_error = mild_compile_error;
1258  th->parse_in_eval = parse_in_eval;
1259 
1260  if (state) {
1261  if (state == TAG_RAISE) {
1262  VALUE errinfo = th->errinfo;
1263  if (strcmp(file, "(eval)") == 0) {
1264  VALUE mesg, errat, bt2;
1265  ID id_mesg;
1266 
1267  CONST_ID(id_mesg, "mesg");
1268  errat = rb_get_backtrace(errinfo);
1269  mesg = rb_attr_get(errinfo, id_mesg);
1270  if (!NIL_P(errat) && RB_TYPE_P(errat, T_ARRAY) &&
1271  (bt2 = vm_backtrace_str_ary(th, 0, 0), RARRAY_LEN(bt2) > 0)) {
1272  if (!NIL_P(mesg) && RB_TYPE_P(mesg, T_STRING) && !RSTRING_LEN(mesg)) {
1273  if (OBJ_FROZEN(mesg)) {
1274  VALUE m = rb_str_cat(rb_str_dup(RARRAY_PTR(errat)[0]), ": ", 2);
1275  rb_ivar_set(errinfo, id_mesg, rb_str_append(m, mesg));
1276  }
1277  else {
1278  rb_str_update(mesg, 0, 0, rb_str_new2(": "));
1279  rb_str_update(mesg, 0, 0, RARRAY_PTR(errat)[0]);
1280  }
1281  }
1282  RARRAY_PTR(errat)[0] = RARRAY_PTR(bt2)[0];
1283  }
1284  }
1285  rb_exc_raise(errinfo);
1286  }
1287  JUMP_TAG(state);
1288  }
1289  return result;
1290 }
1291 
1292 static VALUE
1293 eval_string(VALUE self, VALUE src, VALUE scope, const char *file, int line)
1294 {
1295  return eval_string_with_cref(self, src, scope, 0, file, line);
1296 }
1297 
1298 /*
1299  * call-seq:
1300  * eval(string [, binding [, filename [,lineno]]]) -> obj
1301  *
1302  * Evaluates the Ruby expression(s) in <em>string</em>. If
1303  * <em>binding</em> is given, which must be a <code>Binding</code>
1304  * object, the evaluation is performed in its context. If the
1305  * optional <em>filename</em> and <em>lineno</em> parameters are
1306  * present, they will be used when reporting syntax errors.
1307  *
1308  * def get_binding(str)
1309  * return binding
1310  * end
1311  * str = "hello"
1312  * eval "str + ' Fred'" #=> "hello Fred"
1313  * eval "str + ' Fred'", get_binding("bye") #=> "bye Fred"
1314  */
1315 
1316 VALUE
1317 rb_f_eval(int argc, VALUE *argv, VALUE self)
1318 {
1319  VALUE src, scope, vfile, vline;
1320  const char *file = "(eval)";
1321  int line = 1;
1322 
1323  rb_scan_args(argc, argv, "13", &src, &scope, &vfile, &vline);
1324  if (rb_safe_level() >= 4) {
1325  StringValue(src);
1326  if (!NIL_P(scope) && !OBJ_TAINTED(scope)) {
1328  "Insecure: can't modify trusted binding");
1329  }
1330  }
1331  else {
1332  SafeStringValue(src);
1333  }
1334  if (argc >= 3) {
1335  StringValue(vfile);
1336  }
1337  if (argc >= 4) {
1338  line = NUM2INT(vline);
1339  }
1340 
1341  if (!NIL_P(vfile))
1342  file = RSTRING_PTR(vfile);
1343  return eval_string(self, src, scope, file, line);
1344 }
1345 
1347 VALUE
1348 ruby_eval_string_from_file(const char *str, const char *filename)
1349 {
1350  return eval_string(rb_vm_top_self(), rb_str_new2(str), Qnil, filename, 1);
1351 }
1352 
1354  const char *str;
1355  const char *filename;
1356 };
1357 
1358 static VALUE
1360 {
1361  const struct eval_string_from_file_arg *const arg = (struct eval_string_from_file_arg*)data;
1362  return eval_string(rb_vm_top_self(), rb_str_new2(arg->str), Qnil, arg->filename, 1);
1363 }
1364 
1365 VALUE
1366 ruby_eval_string_from_file_protect(const char *str, const char *filename, int *state)
1367 {
1368  struct eval_string_from_file_arg arg;
1369  arg.str = str;
1370  arg.filename = filename;
1371  return rb_protect((VALUE (*)(VALUE))eval_string_from_file_helper, (VALUE)&arg, state);
1372 }
1373 
1386 VALUE
1387 rb_eval_string(const char *str)
1388 {
1389  return ruby_eval_string_from_file(str, "eval");
1390 }
1391 
1402 VALUE
1403 rb_eval_string_protect(const char *str, int *state)
1404 {
1405  return rb_protect((VALUE (*)(VALUE))rb_eval_string, (VALUE)str, state);
1406 }
1407 
1419 VALUE
1420 rb_eval_string_wrap(const char *str, int *state)
1421 {
1422  int status;
1423  rb_thread_t *th = GET_THREAD();
1424  VALUE self = th->top_self;
1425  VALUE wrapper = th->top_wrapper;
1426  VALUE val;
1427 
1428  th->top_wrapper = rb_module_new();
1431 
1432  val = rb_eval_string_protect(str, &status);
1433 
1434  th->top_self = self;
1435  th->top_wrapper = wrapper;
1436 
1437  if (state) {
1438  *state = status;
1439  }
1440  else if (status) {
1441  JUMP_TAG(status);
1442  }
1443  return val;
1444 }
1445 
1446 VALUE
1448 {
1449  int state;
1450  VALUE val = Qnil; /* OK */
1451  volatile int safe = rb_safe_level();
1452 
1453  if (OBJ_TAINTED(cmd)) {
1454  level = 4;
1455  }
1456 
1457  if (!RB_TYPE_P(cmd, T_STRING)) {
1458  PUSH_TAG();
1459  rb_set_safe_level_force(level);
1460  if ((state = EXEC_TAG()) == 0) {
1461  val = rb_funcall2(cmd, rb_intern("call"), RARRAY_LENINT(arg),
1462  RARRAY_PTR(arg));
1463  }
1464  POP_TAG();
1465 
1467 
1468  if (state)
1469  JUMP_TAG(state);
1470  return val;
1471  }
1472 
1473  PUSH_TAG();
1474  if ((state = EXEC_TAG()) == 0) {
1475  val = eval_string(rb_vm_top_self(), cmd, Qnil, 0, 0);
1476  }
1477  POP_TAG();
1478 
1480  if (state) JUMP_TAG(state);
1481  return val;
1482 }
1483 
1484 /* block eval under the class/module context */
1485 
1486 static VALUE
1487 yield_under(VALUE under, VALUE self, VALUE values)
1488 {
1489  rb_thread_t *th = GET_THREAD();
1490  rb_block_t block, *blockptr;
1491  NODE *cref;
1492 
1493  if ((blockptr = VM_CF_BLOCK_PTR(th->cfp)) != 0) {
1494  block = *blockptr;
1495  block.self = self;
1496  VM_CF_LEP(th->cfp)[0] = VM_ENVVAL_BLOCK_PTR(&block);
1497  }
1498  cref = vm_cref_push(th, under, NOEX_PUBLIC, blockptr);
1500 
1501  if (values == Qundef) {
1502  return vm_yield_with_cref(th, 1, &self, cref);
1503  }
1504  else {
1505  return vm_yield_with_cref(th, RARRAY_LENINT(values), RARRAY_PTR(values), cref);
1506  }
1507 }
1508 
1509 VALUE
1510 rb_yield_refine_block(VALUE refinement, VALUE refinements)
1511 {
1512  rb_thread_t *th = GET_THREAD();
1513  rb_block_t block, *blockptr;
1514  NODE *cref;
1515 
1516  if ((blockptr = VM_CF_BLOCK_PTR(th->cfp)) != 0) {
1517  block = *blockptr;
1518  block.self = refinement;
1519  VM_CF_LEP(th->cfp)[0] = VM_ENVVAL_BLOCK_PTR(&block);
1520  }
1521  cref = vm_cref_push(th, refinement, NOEX_PUBLIC, blockptr);
1523  cref->nd_refinements = refinements;
1524 
1525  return vm_yield_with_cref(th, 0, NULL, cref);
1526 }
1527 
1528 /* string eval under the class/module context */
1529 static VALUE
1530 eval_under(VALUE under, VALUE self, VALUE src, const char *file, int line)
1531 {
1532  NODE *cref = vm_cref_push(GET_THREAD(), under, NOEX_PUBLIC, NULL);
1533 
1534  if (SPECIAL_CONST_P(self) && !NIL_P(under)) {
1536  }
1537  if (rb_safe_level() >= 4) {
1538  StringValue(src);
1539  }
1540  else {
1541  SafeStringValue(src);
1542  }
1543 
1544  return eval_string_with_cref(self, src, Qnil, cref, file, line);
1545 }
1546 
1547 static VALUE
1548 specific_eval(int argc, VALUE *argv, VALUE klass, VALUE self)
1549 {
1550  if (rb_block_given_p()) {
1551  rb_check_arity(argc, 0, 0);
1552  return yield_under(klass, self, Qundef);
1553  }
1554  else {
1555  const char *file = "(eval)";
1556  int line = 1;
1557 
1558  rb_check_arity(argc, 1, 3);
1559  if (rb_safe_level() >= 4) {
1560  StringValue(argv[0]);
1561  }
1562  else {
1563  SafeStringValue(argv[0]);
1564  }
1565  if (argc > 2)
1566  line = NUM2INT(argv[2]);
1567  if (argc > 1) {
1568  file = StringValuePtr(argv[1]);
1569  }
1570  return eval_under(klass, self, argv[0], file, line);
1571  }
1572 }
1573 
1574 /*
1575  * call-seq:
1576  * obj.instance_eval(string [, filename [, lineno]] ) -> obj
1577  * obj.instance_eval {| | block } -> obj
1578  *
1579  * Evaluates a string containing Ruby source code, or the given block,
1580  * within the context of the receiver (_obj_). In order to set the
1581  * context, the variable +self+ is set to _obj_ while
1582  * the code is executing, giving the code access to _obj_'s
1583  * instance variables. In the version of <code>instance_eval</code>
1584  * that takes a +String+, the optional second and third
1585  * parameters supply a filename and starting line number that are used
1586  * when reporting compilation errors.
1587  *
1588  * class KlassWithSecret
1589  * def initialize
1590  * @secret = 99
1591  * end
1592  * end
1593  * k = KlassWithSecret.new
1594  * k.instance_eval { @secret } #=> 99
1595  */
1596 
1597 VALUE
1598 rb_obj_instance_eval(int argc, VALUE *argv, VALUE self)
1599 {
1600  VALUE klass;
1601 
1602  if (SPECIAL_CONST_P(self)) {
1603  klass = rb_special_singleton_class(self);
1604  }
1605  else {
1606  klass = rb_singleton_class(self);
1607  }
1608  return specific_eval(argc, argv, klass, self);
1609 }
1610 
1611 /*
1612  * call-seq:
1613  * obj.instance_exec(arg...) {|var...| block } -> obj
1614  *
1615  * Executes the given block within the context of the receiver
1616  * (_obj_). In order to set the context, the variable +self+ is set
1617  * to _obj_ while the code is executing, giving the code access to
1618  * _obj_'s instance variables. Arguments are passed as block parameters.
1619  *
1620  * class KlassWithSecret
1621  * def initialize
1622  * @secret = 99
1623  * end
1624  * end
1625  * k = KlassWithSecret.new
1626  * k.instance_exec(5) {|x| @secret+x } #=> 104
1627  */
1628 
1629 VALUE
1630 rb_obj_instance_exec(int argc, VALUE *argv, VALUE self)
1631 {
1632  VALUE klass;
1633 
1634  if (SPECIAL_CONST_P(self)) {
1635  klass = rb_special_singleton_class(self);
1636  }
1637  else {
1638  klass = rb_singleton_class(self);
1639  }
1640  return yield_under(klass, self, rb_ary_new4(argc, argv));
1641 }
1642 
1643 /*
1644  * call-seq:
1645  * mod.class_eval(string [, filename [, lineno]]) -> obj
1646  * mod.module_eval {|| block } -> obj
1647  *
1648  * Evaluates the string or block in the context of _mod_, except that when
1649  * a block is given, constant/class variable lookup is not affected. This
1650  * can be used to add methods to a class. <code>module_eval</code> returns
1651  * the result of evaluating its argument. The optional _filename_ and
1652  * _lineno_ parameters set the text for error messages.
1653  *
1654  * class Thing
1655  * end
1656  * a = %q{def hello() "Hello there!" end}
1657  * Thing.module_eval(a)
1658  * puts Thing.new.hello()
1659  * Thing.module_eval("invalid code", "dummy", 123)
1660  *
1661  * <em>produces:</em>
1662  *
1663  * Hello there!
1664  * dummy:123:in `module_eval': undefined local variable
1665  * or method `code' for Thing:Class
1666  */
1667 
1668 VALUE
1670 {
1671  return specific_eval(argc, argv, mod, mod);
1672 }
1673 
1674 /*
1675  * call-seq:
1676  * mod.module_exec(arg...) {|var...| block } -> obj
1677  * mod.class_exec(arg...) {|var...| block } -> obj
1678  *
1679  * Evaluates the given block in the context of the class/module.
1680  * The method defined in the block will belong to the receiver.
1681  *
1682  * class Thing
1683  * end
1684  * Thing.class_exec{
1685  * def hello() "Hello there!" end
1686  * }
1687  * puts Thing.new.hello()
1688  *
1689  * <em>produces:</em>
1690  *
1691  * Hello there!
1692  */
1693 
1694 VALUE
1696 {
1697  return yield_under(mod, mod, rb_ary_new4(argc, argv));
1698 }
1699 
1700 /*
1701  * call-seq:
1702  * throw(tag [, obj])
1703  *
1704  * Transfers control to the end of the active +catch+ block
1705  * waiting for _tag_. Raises +ArgumentError+ if there
1706  * is no +catch+ block for the _tag_. The optional second
1707  * parameter supplies a return value for the +catch+ block,
1708  * which otherwise defaults to +nil+. For examples, see
1709  * <code>Kernel::catch</code>.
1710  */
1711 
1712 static VALUE
1713 rb_f_throw(int argc, VALUE *argv)
1714 {
1715  VALUE tag, value;
1716 
1717  rb_scan_args(argc, argv, "11", &tag, &value);
1718  rb_throw_obj(tag, value);
1719  UNREACHABLE;
1720 }
1721 
1722 void
1724 {
1725  rb_thread_t *th = GET_THREAD();
1726  struct rb_vm_tag *tt = th->tag;
1727 
1728  while (tt) {
1729  if (tt->tag == tag) {
1730  tt->retval = value;
1731  break;
1732  }
1733  tt = tt->prev;
1734  }
1735  if (!tt) {
1736  VALUE desc = rb_inspect(tag);
1737  RB_GC_GUARD(desc);
1738  rb_raise(rb_eArgError, "uncaught throw %s", RSTRING_PTR(desc));
1739  }
1740  th->errinfo = NEW_THROW_OBJECT(tag, 0, TAG_THROW);
1741 
1743 }
1744 
1745 void
1746 rb_throw(const char *tag, VALUE val)
1747 {
1748  rb_throw_obj(ID2SYM(rb_intern(tag)), val);
1749 }
1750 
1751 static VALUE
1753 {
1754  return rb_yield_0(1, &tag);
1755 }
1756 
1757 /*
1758  * call-seq:
1759  * catch([arg]) {|tag| block } -> obj
1760  *
1761  * +catch+ executes its block. If a +throw+ is
1762  * executed, Ruby searches up its stack for a +catch+ block
1763  * with a tag corresponding to the +throw+'s
1764  * _tag_. If found, that block is terminated, and
1765  * +catch+ returns the value given to +throw+. If
1766  * +throw+ is not called, the block terminates normally, and
1767  * the value of +catch+ is the value of the last expression
1768  * evaluated. +catch+ expressions may be nested, and the
1769  * +throw+ call need not be in lexical scope.
1770  *
1771  * def routine(n)
1772  * puts n
1773  * throw :done if n <= 0
1774  * routine(n-1)
1775  * end
1776  *
1777  *
1778  * catch(:done) { routine(3) }
1779  *
1780  * <em>produces:</em>
1781  *
1782  * 3
1783  * 2
1784  * 1
1785  * 0
1786  *
1787  * when _arg_ is given, +catch+ yields it as is, or when no
1788  * _arg_ is given, +catch+ assigns a new unique object to
1789  * +throw+. this is useful for nested +catch+. _arg_ can
1790  * be an arbitrary object, not only Symbol.
1791  *
1792  */
1793 
1794 static VALUE
1795 rb_f_catch(int argc, VALUE *argv)
1796 {
1797  VALUE tag;
1798 
1799  if (argc == 0) {
1800  tag = rb_obj_alloc(rb_cObject);
1801  }
1802  else {
1803  rb_scan_args(argc, argv, "01", &tag);
1804  }
1805  return rb_catch_obj(tag, catch_i, 0);
1806 }
1807 
1808 VALUE
1809 rb_catch(const char *tag, VALUE (*func)(), VALUE data)
1810 {
1811  VALUE vtag = tag ? ID2SYM(rb_intern(tag)) : rb_obj_alloc(rb_cObject);
1812  return rb_catch_obj(vtag, func, data);
1813 }
1814 
1815 VALUE
1817 {
1818  int state;
1819  volatile VALUE val = Qnil; /* OK */
1820  rb_thread_t *th = GET_THREAD();
1821  rb_control_frame_t *saved_cfp = th->cfp;
1822 
1823  TH_PUSH_TAG(th);
1824 
1825  th->tag->tag = tag;
1826 
1827  if ((state = TH_EXEC_TAG()) == 0) {
1828  /* call with argc=1, argv = [tag], block = Qnil to insure compatibility */
1829  val = (*func)(tag, data, 1, &tag, Qnil);
1830  }
1831  else if (state == TAG_THROW && RNODE(th->errinfo)->u1.value == tag) {
1832  th->cfp = saved_cfp;
1833  val = th->tag->retval;
1834  th->errinfo = Qnil;
1835  state = 0;
1836  }
1837  TH_POP_TAG();
1838  if (state)
1839  JUMP_TAG(state);
1840 
1841  return val;
1842 }
1843 
1844 /*
1845  * call-seq:
1846  * local_variables -> array
1847  *
1848  * Returns the names of the current local variables.
1849  *
1850  * fred = 1
1851  * for i in 1..10
1852  * # ...
1853  * end
1854  * local_variables #=> [:fred, :i]
1855  */
1856 
1857 static VALUE
1859 {
1860  VALUE ary = rb_ary_new();
1861  rb_thread_t *th = GET_THREAD();
1862  rb_control_frame_t *cfp =
1864  int i;
1865 
1866  while (cfp) {
1867  if (cfp->iseq) {
1868  for (i = 0; i < cfp->iseq->local_table_size; i++) {
1869  ID lid = cfp->iseq->local_table[i];
1870  if (lid) {
1871  const char *vname = rb_id2name(lid);
1872  /* should skip temporary variable */
1873  if (vname) {
1874  rb_ary_push(ary, ID2SYM(lid));
1875  }
1876  }
1877  }
1878  }
1879  if (!VM_EP_LEP_P(cfp->ep)) {
1880  /* block */
1881  VALUE *ep = VM_CF_PREV_EP(cfp);
1882 
1883  if (vm_collect_local_variables_in_heap(th, ep, ary)) {
1884  break;
1885  }
1886  else {
1887  while (cfp->ep != ep) {
1888  cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
1889  }
1890  }
1891  }
1892  else {
1893  break;
1894  }
1895  }
1896  return ary;
1897 }
1898 
1899 /*
1900  * call-seq:
1901  * block_given? -> true or false
1902  * iterator? -> true or false
1903  *
1904  * Returns <code>true</code> if <code>yield</code> would execute a
1905  * block in the current context. The <code>iterator?</code> form
1906  * is mildly deprecated.
1907  *
1908  * def try
1909  * if block_given?
1910  * yield
1911  * else
1912  * "no block"
1913  * end
1914  * end
1915  * try #=> "no block"
1916  * try { "hello" } #=> "hello"
1917  * try do "hello" end #=> "hello"
1918  */
1919 
1920 
1921 VALUE
1923 {
1924  rb_thread_t *th = GET_THREAD();
1925  rb_control_frame_t *cfp = th->cfp;
1927 
1928  if (cfp != 0 && VM_CF_BLOCK_PTR(cfp)) {
1929  return Qtrue;
1930  }
1931  else {
1932  return Qfalse;
1933  }
1934 }
1935 
1936 VALUE
1938 {
1939  rb_thread_t *th = GET_THREAD();
1940  rb_control_frame_t *cfp = th->cfp;
1942  if (cfp != 0) return cfp->iseq->location.absolute_path;
1943  return Qnil;
1944 }
1945 
1946 void
1948 {
1949  rb_define_global_function("eval", rb_f_eval, -1);
1950  rb_define_global_function("local_variables", rb_f_local_variables, 0);
1952  rb_define_global_function("block_given?", rb_f_block_given_p, 0);
1953 
1954  rb_define_global_function("catch", rb_f_catch, -1);
1955  rb_define_global_function("throw", rb_f_throw, -1);
1956 
1958 
1959  rb_define_method(rb_cBasicObject, "instance_eval", rb_obj_instance_eval, -1);
1960  rb_define_method(rb_cBasicObject, "instance_exec", rb_obj_instance_exec, -1);
1962 
1963 #if 1
1965  VM_METHOD_TYPE_OPTIMIZED, (void *)OPTIMIZED_METHOD_TYPE_SEND, 0);
1967  VM_METHOD_TYPE_OPTIMIZED, (void *)OPTIMIZED_METHOD_TYPE_SEND, 0);
1968 #else
1969  rb_define_method(rb_cBasicObject, "__send__", rb_f_send, -1);
1970  rb_define_method(rb_mKernel, "send", rb_f_send, -1);
1971 #endif
1972  rb_define_method(rb_mKernel, "public_send", rb_f_public_send, -1);
1973 
1974  rb_define_method(rb_cModule, "module_exec", rb_mod_module_exec, -1);
1975  rb_define_method(rb_cModule, "class_exec", rb_mod_module_exec, -1);
1976  rb_define_method(rb_cModule, "module_eval", rb_mod_module_eval, -1);
1977  rb_define_method(rb_cModule, "class_eval", rb_mod_module_eval, -1);
1978 }
VALUE rb_f_public_send(int argc, VALUE *argv, VALUE recv)
Definition: vm_eval.c:920
const rb_block_t * passed_block
Definition: vm_core.h:511
rb_control_frame_t * cfp
Definition: vm_core.h:500
#define T_SYMBOL
Definition: ruby.h:502
#define T_OBJECT
Definition: ruby.h:485
struct rb_block_struct * blockptr
Definition: vm_core.h:163
VALUE rb_ary_unshift(VALUE ary, VALUE item)
Definition: array.c:1084
#define UNDEFINED_METHOD_ENTRY_P(me)
Definition: method.h:108
VALUE rb_vm_call(rb_thread_t *th, VALUE recv, VALUE id, int argc, const VALUE *argv, const rb_method_entry_t *me, VALUE defined_class)
Definition: vm_eval.c:243
#define RUBY_VM_CHECK_INTS(th)
Definition: vm_core.h:948
static int check_funcall_respond_to(rb_thread_t *th, VALUE klass, VALUE recv, ID mid)
Definition: vm_eval.c:355
VALUE rb_ary_new4(long n, const VALUE *elts)
Definition: array.c:451
static int vm_collect_local_variables_in_heap(rb_thread_t *th, VALUE *dfp, VALUE ary)
#define RARRAY_LEN(a)
Definition: ruby.h:899
#define RUBY_EVENT_C_RETURN
Definition: ruby.h:1587
void rb_bug(const char *fmt,...)
Definition: error.c:290
rb_method_type_t type
Definition: method.h:77
VALUE * argv
Definition: vm_eval.c:1118
#define FALSE
Definition: nkf.h:174
static NODE * vm_cref_push(rb_thread_t *th, VALUE klass, int noex, rb_block_t *blockptr)
rb_method_attr_t attr
Definition: method.h:82
static VALUE iterate_method(VALUE obj)
Definition: vm_eval.c:1122
static VALUE rb_call0(VALUE recv, ID mid, int argc, const VALUE *argv, call_type scope, VALUE self)
Definition: vm_eval.c:311
static rb_control_frame_t * vm_get_ruby_level_caller_cfp(rb_thread_t *th, rb_control_frame_t *cfp)
Definition: vm.c:213
int i
Definition: win32ole.c:784
VALUE rb_current_realfilepath(void)
Definition: vm_eval.c:1937
VALUE rb_mod_module_eval(int argc, VALUE *argv, VALUE mod)
Definition: vm_eval.c:1669
#define T_FIXNUM
Definition: ruby.h:497
#define VM_FRAME_FLAG_FINISH
Definition: vm_core.h:740
VALUE rb_yield_values(int n,...)
Definition: vm_eval.c:945
#define T_MATCH
Definition: ruby.h:501
static void stack_check(void)
Definition: vm_eval.c:280
const char * filename
Definition: vm_eval.c:1355
static VALUE * VM_CF_PREV_EP(rb_control_frame_t *cfp)
Definition: vm.c:48
#define NUM2INT(x)
Definition: ruby.h:622
#define TAG_THROW
Definition: eval_intern.h:141
#define VM_FRAME_MAGIC_CFUNC
Definition: vm_core.h:728
static VALUE send_internal(int argc, const VALUE *argv, VALUE recv, call_type scope)
Definition: vm_eval.c:851
void rb_throw(const char *tag, VALUE val)
Definition: vm_eval.c:1746
#define RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp)
Definition: vm_core.h:787
#define GetProcPtr(obj, ptr)
Definition: vm_core.h:665
rb_method_flag_t flag
Definition: method.h:96
#define NEW_IFUNC(f, c)
Definition: node.h:362
VALUE rb_eval_string_protect(const char *str, int *state)
Evaluates the given string in an isolated binding.
Definition: vm_eval.c:1403
VALUE rb_yield_splat(VALUE values)
Definition: vm_eval.c:973
VALUE rb_ary_subseq(VALUE ary, long beg, long len)
Definition: array.c:1110
#define CLASS_OF(v)
Definition: ruby.h:448
rb_block_t block
Definition: vm_core.h:686
#define T_MODULE
Definition: ruby.h:488
VALUE rb_str_cat(VALUE, const char *, long)
Definition: string.c:1963
VALUE rb_call_super(int argc, const VALUE *argv)
Definition: vm_eval.c:273
#define Qtrue
Definition: ruby.h:434
rb_iseq_t * iseq
Definition: vm_core.h:446
#define TAG_BREAK
Definition: eval_intern.h:136
static void vm_set_eval_stack(rb_thread_t *th, VALUE iseqval, const NODE *cref, rb_block_t *base_block)
#define GET_THROWOBJ_CATCH_POINT(obj)
Definition: eval_intern.h:153
struct rb_method_entry_struct * orig_me
Definition: method.h:90
void rb_check_funcall_hook(int, VALUE, ID, int, VALUE *, VALUE)
Definition: internal.h:329
const int id
Definition: nkf.c:209
#define new_args(f, o, r, p, t)
Definition: ripper.c:467
static void raise_method_missing(rb_thread_t *th, int argc, const VALUE *argv, VALUE obj, int last_call_status)
Definition: vm_eval.c:659
void rb_define_private_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1356
ID rb_frame_this_func(void)
Definition: eval.c:902
#define sysstack_error
Definition: vm_core.h:861
VALUE rb_eTypeError
Definition: error.c:511
VALUE rb_f_eval(int argc, VALUE *argv, VALUE self)
Definition: vm_eval.c:1317
VALUE rb_name_err_mesg_new(VALUE obj, VALUE mesg, VALUE recv, VALUE method)
Definition: error.c:1027
#define TH_JUMP_TAG(th, st)
Definition: eval_intern.h:116
#define T_RATIONAL
Definition: ruby.h:503
#define UNREACHABLE
Definition: ruby.h:40
static VALUE check_funcall_failed(struct rescue_funcall_args *args, VALUE e)
Definition: vm_eval.c:346
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:822
SSL_METHOD *(* func)(void)
Definition: ossl_ssl.c:108
#define SYM2ID(x)
Definition: ruby.h:364
VALUE rb_ary_tmp_new(long capa)
Definition: array.c:465
VALUE rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE absolute_path, VALUE line, rb_block_t *base_block, VALUE opt)
Definition: iseq.c:589
VALUE rb_each(VALUE obj)
Definition: vm_eval.c:1166
#define RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp)
Definition: vm_core.h:800
#define VM_ENVVAL_BLOCK_PTR(v)
Definition: vm_core.h:775
VALUE rb_catch_obj(VALUE tag, VALUE(*func)(), VALUE data)
Definition: vm_eval.c:1816
int local_table_size
Definition: vm_core.h:226
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *state)
Definition: eval.c:771
union rb_method_definition_struct::@90 body
static VALUE vm_call0_cfunc_with_frame(rb_thread_t *th, rb_call_info_t *ci, const VALUE *argv)
Definition: vm_eval.c:94
#define PRIxVALUE
Definition: ruby.h:145
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1780
#define VM_FRAME_TYPE(cfp)
Definition: vm_core.h:736
static VALUE rb_yield_0(int argc, const VALUE *argv)
Definition: vm_eval.c:928
void rb_str_update(VALUE, long, long, VALUE)
Definition: string.c:3451
VALUE rb_ary_clear(VALUE ary)
Definition: array.c:3220
ID called_id
Definition: method.h:99
#define TH_EXEC_TAG()
Definition: eval_intern.h:111
#define RB_GC_GUARD(v)
Definition: ruby.h:530
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Definition: object.c:582
#define T_HASH
Definition: ruby.h:493
#define VM_PROFILE_UP(x)
size_t stack_max
Definition: vm_core.h:278
VALUE rb_eSecurityError
Definition: error.c:520
void Init_vm_eval(void)
Definition: vm_eval.c:1947
static VALUE vm_yield(rb_thread_t *th, int argc, const VALUE *argv)
VALUE rb_catch(const char *tag, VALUE(*func)(), VALUE data)
Definition: vm_eval.c:1809
static VALUE catch_i(VALUE tag, VALUE data)
Definition: vm_eval.c:1752
#define T_ARRAY
Definition: ruby.h:492
#define TAG_RAISE
Definition: eval_intern.h:140
#define GetEnvPtr(obj, ptr)
Definition: vm_core.h:678
#define PUSH_TAG()
Definition: eval_intern.h:108
void rb_define_global_function(const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a global function.
Definition: class.c:1526
VALUE rb_vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, int argc, const VALUE *argv, const rb_block_t *blockptr)
Definition: vm.c:712
static VALUE * VM_CF_LEP(rb_control_frame_t *cfp)
Definition: vm.c:42
VALUE env
Definition: vm_core.h:693
ID rb_check_id(volatile VALUE *namep)
Returns ID for the given name if it is interned already, or 0.
Definition: ripper.c:17099
VALUE rb_eval_string_wrap(const char *str, int *state)
Evaluates the given string under a module binding in an isolated binding.
Definition: vm_eval.c:1420
#define NOEX_OK
Definition: vm_eval.c:293
VALUE ruby_eval_string_from_file(const char *str, const char *filename)
Definition: vm_eval.c:1348
#define T_UNDEF
Definition: ruby.h:505
static int check_funcall_callable(rb_thread_t *th, const rb_method_entry_t *me)
Definition: vm_eval.c:382
int ruby_stack_check(void)
Definition: gc.c:2307
#define OBJ_TAINTED(x)
Definition: ruby.h:1153
const char * rb_obj_classname(VALUE)
Definition: variable.c:396
#define RUBY_DTRACE_CMETHOD_ENTRY_HOOK(th, klass, id)
Definition: probes_helper.h:61
static VALUE check_funcall_missing(rb_thread_t *th, VALUE klass, VALUE recv, ID mid, int argc, VALUE *argv)
Definition: vm_eval.c:388
Definition: node.h:239
VALUE rb_check_funcall(VALUE recv, ID mid, int argc, VALUE *argv)
Definition: vm_eval.c:408
void rb_exc_raise(VALUE mesg)
Definition: eval.c:527
static VALUE vm_call0_cfunc(rb_thread_t *th, rb_call_info_t *ci, const VALUE *argv)
Definition: vm_eval.c:132
int args
Definition: win32ole.c:785
VALUE rb_singleton_class(VALUE obj)
Returns the singleton class of obj.
Definition: class.c:1470
#define RB_TYPE_P(obj, type)
Definition: ruby.h:1537
VALUE rb_eNameError
Definition: error.c:516
#define TH_POP_TAG()
Definition: eval_intern.h:101
rb_method_cfunc_t cfunc
Definition: method.h:81
RUBY_EXTERN VALUE rb_cBinding
Definition: ruby.h:1429
unsigned short first_lineno
Definition: vm_core.h:695
static VALUE make_no_method_exception(VALUE exc, const char *format, VALUE obj, int argc, const VALUE *argv)
Definition: vm_eval.c:635
VALUE rb_class_new_instance(int, VALUE *, VALUE)
Definition: object.c:1775
static VALUE rb_f_local_variables(void)
Definition: vm_eval.c:1858
union rb_call_info_struct::@129 aux
int rb_block_given_p(void)
Definition: eval.c:672
#define EXEC_TAG()
Definition: eval_intern.h:113
static VALUE rb_f_catch(int argc, VALUE *argv)
Definition: vm_eval.c:1795
rb_control_frame_t * rb_vm_get_ruby_level_next_cfp(rb_thread_t *th, const rb_control_frame_t *cfp)
Definition: vm.c:201
#define val
VALUE rb_mod_module_exec(int argc, VALUE *argv, VALUE mod)
Definition: vm_eval.c:1695
void rb_raise_method_missing(rb_thread_t *th, int argc, VALUE *argv, VALUE obj, int call_status)
Definition: vm_eval.c:729
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:1426
VALUE rb_eRuntimeError
Definition: error.c:510
VALUE rb_special_singleton_class(VALUE obj)
Definition: class.c:1391
#define T_NIL
Definition: ruby.h:484
#define GetBindingPtr(obj, ptr)
Definition: vm_core.h:689
RUBY_EXTERN VALUE rb_cBasicObject
Definition: ruby.h:1425
VALUE rb_funcall(VALUE recv, ID mid, int n,...)
Calls a method.
Definition: vm_eval.c:774
VALUE rb_funcall2(VALUE recv, ID mid, int argc, const VALUE *argv)
Calls a method.
Definition: vm_eval.c:805
VALUE rb_ary_new(void)
Definition: array.c:424
#define T_TRUE
Definition: ruby.h:498
static int rb_method_call_status(rb_thread_t *th, const rb_method_entry_t *me, call_type scope, VALUE self)
Definition: vm_eval.c:527
#define NOEX_MISSING
Definition: vm_eval.c:632
RUBY_EXTERN VALUE rb_mKernel
Definition: ruby.h:1414
#define JUMP_TAG(st)
Definition: eval_intern.h:120
rb_iseq_t * iseq
Definition: vm_core.h:428
#define NIL_P(v)
Definition: ruby.h:446
#define PASS_PASSED_BLOCK()
Definition: eval_intern.h:12
#define UNLIKELY(x)
Definition: vm_core.h:115
static VALUE iterate_check_method(VALUE obj)
Definition: vm_eval.c:1144
VALUE rb_eNoMethodError
Definition: error.c:519
VALUE rb_get_backtrace(VALUE info)
Definition: eval_error.c:53
VALUE tag
Definition: vm_core.h:469
#define OBJ_FROZEN(x)
Definition: ruby.h:1163
static const char * rb_type_str(enum ruby_value_type type)
Definition: vm_eval.c:449
VALUE top_self
Definition: vm_core.h:520
#define T_FLOAT
Definition: ruby.h:489
int rb_method_entry_arity(const rb_method_entry_t *me)
Definition: proc.c:1743
int argc
Definition: ruby.c:130
#define Qfalse
Definition: ruby.h:433
#define rb_sourcefile()
Definition: tcltklib.c:97
#define ALLOCA_N(type, n)
Definition: ruby.h:1227
#define RUBY_DTRACE_CMETHOD_RETURN_HOOK(th, klass, id)
Definition: probes_helper.h:64
Definition: method.h:95
RUBY_EXTERN VALUE rb_cModule
Definition: ruby.h:1445
#define T_BIGNUM
Definition: ruby.h:495
#define MEMCPY(p1, p2, type, n)
Definition: ruby.h:1242
#define T_NODE
Definition: ruby.h:506
VALUE rb_obj_alloc(VALUE)
Definition: object.c:1721
#define RNODE(obj)
Definition: node.h:266
int err
Definition: win32.c:87
#define RUBY_EVENT_C_CALL
Definition: ruby.h:1586
VALUE rb_vm_make_env_object(rb_thread_t *th, rb_control_frame_t *cfp)
Definition: vm.c:495
#define OBJ_FREEZE(x)
Definition: ruby.h:1164
static VALUE rb_f_loop(VALUE self)
Definition: vm_eval.c:1019
#define POP_TAG()
Definition: eval_intern.h:109
#define T_COMPLEX
Definition: ruby.h:504
void rb_throw_obj(VALUE tag, VALUE value)
Definition: vm_eval.c:1723
ID * local_table
Definition: vm_core.h:225
static rb_control_frame_t * vm_push_frame(rb_thread_t *th, const rb_iseq_t *iseq, VALUE type, VALUE self, VALUE klass, VALUE specval, const VALUE *pc, VALUE *sp, int local_size, const rb_method_entry_t *me)
Definition: vm_insnhelper.c:34
rb_method_entry_t * rb_method_entry(VALUE klass, ID id, VALUE *define_class_ptr)
Definition: vm_method.c:551
VALUE rb_vm_top_self()
Definition: vm.c:2427
VALUE klass
Definition: method.h:100
VALUE rb_const_get(VALUE, ID)
Definition: variable.c:1876
#define RSTRING_LEN(str)
Definition: ruby.h:862
static rb_block_t * VM_CF_BLOCK_PTR(rb_control_frame_t *cfp)
Definition: vm.c:54
VALUE(* invoker)(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
Definition: method.h:65
#define TRUE
Definition: nkf.h:175
#define T_DATA
Definition: ruby.h:500
static VALUE vm_exec(rb_thread_t *th)
rb_method_entry_t * rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *option, rb_method_flag_t noex)
Definition: vm_method.c:402
VALUE(* func)(ANYARGS)
Definition: method.h:64
VALUE rb_eval_string(const char *str)
Evaluates the given string in an isolated binding.
Definition: vm_eval.c:1387
VALUE rb_iterate(VALUE(*it_proc)(VALUE), VALUE data1, VALUE(*bl_proc)(ANYARGS), VALUE data2)
Definition: vm_eval.c:1032
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1570
#define rb_thread_raised_set(th, f)
Definition: eval_intern.h:170
VALUE rb_ivar_set(VALUE, ID, VALUE)
Definition: variable.c:1128
VALUE rb_f_send(int argc, VALUE *argv, VALUE recv)
Definition: vm_eval.c:903
unsigned long ID
Definition: ruby.h:105
#define T_STRUCT
Definition: ruby.h:494
#define Qnil
Definition: ruby.h:435
static VALUE eval_under(VALUE under, VALUE self, VALUE src, const char *file, int line)
Definition: vm_eval.c:1530
VALUE rb_eStopIteration
Definition: enumerator.c:111
int type
Definition: tcltklib.c:111
#define BUILTIN_TYPE(x)
Definition: ruby.h:510
unsigned long VALUE
Definition: ruby.h:104
static VALUE result
Definition: nkf.c:40
static VALUE rb_f_throw(int argc, VALUE *argv)
Definition: vm_eval.c:1713
static void vm_pop_frame(rb_thread_t *th)
Definition: vm_insnhelper.c:99
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn)
Definition: intern.h:215
#define RBASIC(obj)
Definition: ruby.h:1094
VALUE rb_funcall3(VALUE recv, ID mid, int argc, const VALUE *argv)
Calls a method.
Definition: vm_eval.c:820
void rb_extend_object(VALUE obj, VALUE module)
Definition: eval.c:1234
VALUE rb_check_funcall_with_hook(VALUE recv, ID mid, int argc, VALUE *argv, rb_check_funcall_hook *hook, VALUE arg)
Definition: vm_eval.c:427
VALUE rb_obj_instance_eval(int argc, VALUE *argv, VALUE self)
Definition: vm_eval.c:1598
static VALUE vm_yield_with_cref(rb_thread_t *th, int argc, const VALUE *argv, const NODE *cref)
static VALUE vm_call_super(rb_thread_t *th, int argc, const VALUE *argv)
Definition: vm_eval.c:250
VALUE rb_rescue2(VALUE(*b_proc)(ANYARGS), VALUE data1, VALUE(*r_proc)(ANYARGS), VALUE data2,...)
Definition: eval.c:701
rb_iseq_location_t location
Definition: vm_core.h:213
#define TH_PUSH_TAG(th)
Definition: eval_intern.h:94
#define INFINITY
Definition: missing.h:138
VALUE rb_str_new_cstr(const char *)
Definition: string.c:447
static VALUE vm_call_bmethod_body(rb_thread_t *th, rb_call_info_t *ci, const VALUE *argv)
#define RARRAY_LENINT(ary)
Definition: ruby.h:908
VALUE flags
Definition: node.h:240
VALUE rb_str_dup(VALUE)
Definition: string.c:946
call_type
Definition: vm_eval.c:25
ruby_value_type
Definition: ruby.h:450
VALUE rb_block_call(VALUE obj, ID mid, int argc, VALUE *argv, VALUE(*bl_proc)(ANYARGS), VALUE data2)
Definition: vm_eval.c:1131
static VALUE vm_call0(rb_thread_t *th, VALUE recv, ID id, int argc, const VALUE *argv, const rb_method_entry_t *me, VALUE defined_class)
Definition: vm_eval.c:37
VALUE rb_yield_refine_block(VALUE refinement, VALUE refinements)
Definition: vm_eval.c:1510
#define NEW_THROW_OBJECT(val, pt, st)
Definition: eval_intern.h:145
int rb_respond_to(VALUE, ID)
Definition: vm_method.c:1564
#define IMMEDIATE_P(x)
Definition: ruby.h:360
void rb_set_safe_level_force(int)
Definition: safe.c:34
#define RSTRING_PTR(str)
Definition: ruby.h:866
#define va_init_list(a, b)
Definition: tcltklib.c:61
static VALUE loop_i(void)
Definition: vm_eval.c:985
static VALUE eval_string_from_file_helper(void *data)
Definition: vm_eval.c:1359
#define rb_check_arity(argc, min, max)
Definition: intern.h:277
#define INT2FIX(i)
Definition: ruby.h:241
VALUE top_wrapper
Definition: vm_core.h:521
#define RCLASS_SUPER(c)
Definition: classext.h:16
int rb_sourceline(void)
Definition: vm.c:816
VALUE rb_obj_instance_exec(int argc, VALUE *argv, VALUE self)
Definition: vm_eval.c:1630
rb_block_t block
Definition: vm_core.h:669
VALUE rb_module_new(void)
Definition: class.c:596
int mild_compile_error
Thread-local state of compiling context.
Definition: vm_core.h:576
VALUE rb_funcall_with_block(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE pass_procval)
Definition: vm_eval.c:834
rb_method_definition_t * def
Definition: method.h:98
#define ANYARGS
Definition: defines.h:57
const rb_method_entry_t * me
Definition: vm_core.h:435
VALUE rb_check_array_type(VALUE ary)
Definition: array.c:557
static VALUE eval_string_with_cref(VALUE self, VALUE src, VALUE scope, NODE *cref, const char *volatile file, volatile int line)
Definition: vm_eval.c:1172
#define RARRAY_PTR(a)
Definition: ruby.h:904
static VALUE yield_under(VALUE under, VALUE self, VALUE values)
Definition: vm_eval.c:1487
VALUE ruby_eval_string_from_file_protect(const char *str, const char *filename, int *state)
Definition: vm_eval.c:1366
#define RTEST(v)
Definition: ruby.h:445
#define T_STRING
Definition: ruby.h:490
int rb_method_basic_definition_p(VALUE, ID)
Definition: vm_method.c:1498
v
Definition: win32ole.c:798
#define T_FALSE
Definition: ruby.h:499
#define T_FILE
Definition: ruby.h:496
static VALUE eval_string(VALUE self, VALUE src, VALUE scope, const char *file, int line)
Definition: vm_eval.c:1293
VALUE rb_apply(VALUE recv, ID mid, VALUE args)
Calls a method.
Definition: vm_eval.c:745
static VALUE vm_call_iseq_setup(rb_thread_t *th, rb_control_frame_t *cfp, rb_call_info_t *ci)
static VALUE rb_call(VALUE recv, ID mid, int argc, const VALUE *argv, call_type scope)
Definition: vm_eval.c:582
VALUE rb_yield_values2(int argc, const VALUE *argv)
Definition: vm_eval.c:967
VALUE rb_funcall_passing_block(VALUE recv, ID mid, int argc, const VALUE *argv)
Definition: vm_eval.c:826
#define NOEX_SAFE(n)
Definition: method.h:39
static VALUE specific_eval(int argc, VALUE *argv, VALUE klass, VALUE self)
Definition: vm_eval.c:1548
#define rb_thread_raised_p(th, f)
Definition: eval_intern.h:172
#define SafeStringValue(v)
Definition: ruby.h:552
VALUE rb_eNotImpError
Definition: error.c:521
VALUE rb_f_block_given_p(void)
Definition: vm_eval.c:1922
#define T_CLASS
Definition: ruby.h:486
#define rb_safe_level()
Definition: tcltklib.c:94
rb_call_info_t * passed_ci
Definition: vm_core.h:517
#define EXEC_EVENT_HOOK(th_, flag_, self_, id_, klass_, data_)
Definition: vm_core.h:993
NORETURN(static void raise_method_missing(rb_thread_t *th, int argc, const VALUE *argv, VALUE obj, int call_status))
#define ID2SYM(x)
Definition: ruby.h:363
#define GetISeqPtr(obj, ptr)
Definition: vm_core.h:183
VALUE rb_yield(VALUE val)
Definition: vm_eval.c:934
const char * rb_id2name(ID id)
Definition: ripper.c:17005
static VALUE rb_f_loop_size(VALUE self, VALUE args)
Definition: vm_eval.c:994
#define StringValuePtr(v)
Definition: ruby.h:547
struct rb_vm_tag * tag
Definition: vm_core.h:561
VALUE rb_inspect(VALUE)
Definition: object.c:402
static rb_method_entry_t * rb_search_method_entry(VALUE recv, ID mid, VALUE *defined_class_ptr)
Definition: vm_eval.c:484
struct rb_vm_tag * prev
Definition: vm_core.h:472
#define PASS_PASSED_BLOCK_TH(th)
Definition: eval_intern.h:7
static VALUE rb_method_missing(int argc, const VALUE *argv, VALUE obj)
Definition: vm_eval.c:625
VALUE retval
Definition: vm_core.h:470
#define CONST_ID(var, str)
Definition: ruby.h:1318
VALUE vm_backtrace_str_ary(rb_thread_t *th, int lev, int n)
#define SPECIAL_CONST_P(x)
Definition: ruby.h:1143
#define CHECK_VM_STACK_OVERFLOW(cfp, margin)
Definition: vm_core.h:863
#define rb_intern(str)
#define T_ZOMBIE
Definition: ruby.h:507
#define SYMBOL_P(x)
Definition: ruby.h:362
#define mod(x, y)
Definition: date_strftime.c:28
#define T_NONE
Definition: ruby.h:483
VALUE path
Definition: vm_core.h:694
#define env
VALUE rb_eval_cmd(VALUE cmd, VALUE arg, int level)
Definition: vm_eval.c:1447
#define NULL
Definition: _sdbm.c:103
#define Qundef
Definition: ruby.h:436
#define T_ICLASS
Definition: ruby.h:487
int method_missing_reason
Definition: vm_core.h:612
enum rb_method_definition_struct::@90::method_optimized_type optimize_type
#define VM_EP_LEP_P(ep)
Definition: vm_core.h:782
static rb_thread_t * GET_THREAD(void)
Definition: vm_core.h:883
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1344
VALUE rb_str_append(VALUE, VALUE)
Definition: string.c:2121
VALUE rb_iseq_disasm(VALUE self)
Definition: iseq.c:1354
VALUE rb_str_new2(const char *)
static VALUE method_missing(VALUE obj, ID id, int argc, const VALUE *argv, int call_status)
Definition: vm_eval.c:695
#define GET_THROWOBJ_VAL(obj)
Definition: eval_intern.h:152
ID rb_to_id(VALUE)
Definition: string.c:8154
VALUE rb_check_block_call(VALUE obj, ID mid, int argc, VALUE *argv, VALUE(*bl_proc)(ANYARGS), VALUE data2)
Definition: vm_eval.c:1153
VALUE rb_eArgError
Definition: error.c:512
#define T_REGEXP
Definition: ruby.h:491
VALUE rb_obj_clone(VALUE)
Definition: object.c:296
static VALUE check_funcall_exec(struct rescue_funcall_args *args)
Definition: vm_eval.c:335
static VALUE vm_call0_body(rb_thread_t *th, rb_call_info_t *ci, const VALUE *argv)
Definition: vm_eval.c:140
VALUE rb_attr_get(VALUE, ID)
Definition: variable.c:1122
#define type_case(t)
const rb_method_entry_t * me
Definition: vm_core.h:158
char ** argv
Definition: ruby.c:131
#define DBL2NUM(dbl)
Definition: ruby.h:837
#define TAG_RETRY
Definition: eval_intern.h:138
#define StringValue(v)
Definition: ruby.h:546
int parse_in_eval
Thread-local state of evaluation context.
Definition: vm_core.h:570
void rb_ary_set_len(VALUE ary, long len)
Definition: array.c:1490
#define NODE_FL_CREF_PUSHED_BY_EVAL
Definition: node.h:270