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