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