Ruby  2.5.0dev(2017-10-22revision60238)
vm_eval.c
Go to the documentation of this file.
1 /**********************************************************************
2 
3  vm_eval.c -
4 
5  $Author$
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 
16 };
17 
18 static inline VALUE method_missing(VALUE obj, ID id, int argc, const VALUE *argv, enum method_missing_reason call_status);
19 static inline VALUE vm_yield_with_cref(rb_thread_t *th, int argc, const VALUE *argv, const rb_cref_t *cref, int is_lambda);
20 static inline VALUE vm_yield(rb_thread_t *th, int argc, const VALUE *argv);
21 static inline VALUE vm_yield_with_block(rb_thread_t *th, int argc, const VALUE *argv, VALUE block_handler);
22 static inline VALUE vm_yield_force_blockarg(rb_thread_t *th, VALUE args);
23 static VALUE vm_exec(rb_thread_t *th);
24 static void vm_set_eval_stack(rb_thread_t * th, const rb_iseq_t *iseq, const rb_cref_t *cref, const struct rb_block *base_block);
25 static int vm_collect_local_variables_in_heap(rb_thread_t *th, const VALUE *dfp, const struct local_var_list *vars);
26 
27 static VALUE rb_eUncaughtThrow;
28 static ID id_result, id_tag, id_value;
29 #define id_mesg idMesg
30 
31 typedef enum call_type {
36 } call_type;
37 
38 static VALUE send_internal(int argc, const VALUE *argv, VALUE recv, call_type scope);
39 
40 static VALUE vm_call0_body(rb_thread_t* th, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc, const VALUE *argv);
41 
42 static VALUE
43 vm_call0(rb_thread_t* th, VALUE recv, ID id, int argc, const VALUE *argv, const rb_callable_method_entry_t *me)
44 {
45  struct rb_calling_info calling_entry, *calling;
46  struct rb_call_info ci_entry;
47  struct rb_call_cache cc_entry;
48 
49  calling = &calling_entry;
50 
51  ci_entry.flag = 0;
52  ci_entry.mid = id;
53 
54  cc_entry.me = me;
55 
56  calling->recv = recv;
57  calling->argc = argc;
58 
59  return vm_call0_body(th, calling, &ci_entry, &cc_entry, argv);
60 }
61 
62 static VALUE
63 vm_call0_cfunc_with_frame(rb_thread_t* th, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc, const VALUE *argv)
64 {
65  VALUE val;
66  const rb_callable_method_entry_t *me = cc->me;
67  const rb_method_cfunc_t *cfunc = &me->def->body.cfunc;
68  int len = cfunc->argc;
69  VALUE recv = calling->recv;
70  int argc = calling->argc;
71  ID mid = ci->mid;
72  VALUE block_handler = calling->block_handler;
73 
74  RUBY_DTRACE_CMETHOD_ENTRY_HOOK(th, me->owner, me->def->original_id);
75  EXEC_EVENT_HOOK(th, RUBY_EVENT_C_CALL, recv, me->def->original_id, mid, me->owner, Qnil);
76  {
77  rb_control_frame_t *reg_cfp = th->ec.cfp;
78 
79  vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC | VM_FRAME_FLAG_CFRAME | VM_ENV_FLAG_LOCAL, recv,
80  block_handler, (VALUE)me,
81  0, reg_cfp->sp, 0, 0);
82 
83  if (len >= 0) rb_check_arity(argc, len, len);
84 
85  VM_PROFILE_UP(C2C_CALL);
86  val = (*cfunc->invoker)(cfunc->func, recv, argc, argv);
87 
88  CHECK_CFP_CONSISTENCY("vm_call0_cfunc_with_frame");
89  VM_PROFILE_UP(C2C_POPF);
90  rb_vm_pop_frame(th);
91  }
92  EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, recv, me->def->original_id, mid, me->owner, val);
93  RUBY_DTRACE_CMETHOD_RETURN_HOOK(th, me->owner, me->def->original_id);
94 
95  return val;
96 }
97 
98 static VALUE
99 vm_call0_cfunc(rb_thread_t* th, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc, const VALUE *argv)
100 {
101  return vm_call0_cfunc_with_frame(th, calling, ci, cc, argv);
102 }
103 
104 /* `ci' should point temporal value (on stack value) */
105 static VALUE
106 vm_call0_body(rb_thread_t* th, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc, const VALUE *argv)
107 {
108  VALUE ret;
109 
110  calling->block_handler = vm_passed_block_handler(th);
111 
112  again:
113  switch (cc->me->def->type) {
114  case VM_METHOD_TYPE_ISEQ:
115  {
116  rb_control_frame_t *reg_cfp = th->ec.cfp;
117  int i;
118 
119  CHECK_VM_STACK_OVERFLOW(reg_cfp, calling->argc + 1);
120 
121  *reg_cfp->sp++ = calling->recv;
122  for (i = 0; i < calling->argc; i++) {
123  *reg_cfp->sp++ = argv[i];
124  }
125 
126  vm_call_iseq_setup(th, reg_cfp, calling, ci, cc);
127  VM_ENV_FLAGS_SET(th->ec.cfp->ep, VM_FRAME_FLAG_FINISH);
128  return vm_exec(th); /* CHECK_INTS in this function */
129  }
132  ret = vm_call0_cfunc(th, calling, ci, cc, argv);
133  goto success;
135  rb_check_arity(calling->argc, 1, 1);
136  ret = rb_ivar_set(calling->recv, cc->me->def->body.attr.id, argv[0]);
137  goto success;
138  case VM_METHOD_TYPE_IVAR:
139  rb_check_arity(calling->argc, 0, 0);
140  ret = rb_attr_get(calling->recv, cc->me->def->body.attr.id);
141  goto success;
143  ret = vm_call_bmethod_body(th, calling, ci, cc, argv);
144  goto success;
147  {
148  const rb_method_type_t type = cc->me->def->type;
149  VALUE super_class = cc->me->defined_class;
150 
151  if (type == VM_METHOD_TYPE_ZSUPER) {
152  super_class = RCLASS_ORIGIN(super_class);
153  }
154  else if (cc->me->def->body.refined.orig_me) {
155  cc->me = refined_method_callable_without_refinement(cc->me);
156  goto again;
157  }
158 
159  super_class = RCLASS_SUPER(super_class);
160 
161  if (!super_class || !(cc->me = rb_callable_method_entry(super_class, ci->mid))) {
163  ret = method_missing(calling->recv, ci->mid, calling->argc, argv, ex);
164  goto success;
165  }
166  RUBY_VM_CHECK_INTS(th);
167  goto again;
168  }
170  cc->me = aliased_callable_method_entry(cc->me);
171  goto again;
173  {
174  vm_passed_block_handler_set(th, calling->block_handler);
175  return method_missing(calling->recv, ci->mid, calling->argc,
176  argv, MISSING_NOENTRY);
177  }
179  switch (cc->me->def->body.optimize_type) {
181  ret = send_internal(calling->argc, argv, calling->recv, CALL_FCALL);
182  goto success;
184  {
185  rb_proc_t *proc;
186  GetProcPtr(calling->recv, proc);
187  ret = rb_vm_invoke_proc(th, proc, calling->argc, argv, calling->block_handler);
188  goto success;
189  }
190  default:
191  rb_bug("vm_call0: unsupported optimized method type (%d)", cc->me->def->body.optimize_type);
192  }
193  break;
195  break;
196  }
197  rb_bug("vm_call0: unsupported method type (%d)", cc->me->def->type);
198  return Qundef;
199 
200  success:
201  RUBY_VM_CHECK_INTS(th);
202  return ret;
203 }
204 
205 VALUE
206 rb_vm_call(rb_thread_t *th, VALUE recv, VALUE id, int argc, const VALUE *argv, const rb_callable_method_entry_t *me)
207 {
208  return vm_call0(th, recv, id, argc, argv, me);
209 }
210 
211 static inline VALUE
212 vm_call_super(rb_thread_t *th, int argc, const VALUE *argv)
213 {
214  VALUE recv = th->ec.cfp->self;
215  VALUE klass;
216  ID id;
217  rb_control_frame_t *cfp = th->ec.cfp;
219 
220  if (VM_FRAME_RUBYFRAME_P(cfp)) {
221  rb_bug("vm_call_super: should not be reached");
222  }
223 
224  klass = RCLASS_ORIGIN(me->defined_class);
225  klass = RCLASS_SUPER(klass);
226  id = me->def->original_id;
227  me = rb_callable_method_entry(klass, id);
228 
229  if (!me) {
230  return method_missing(recv, id, argc, argv, MISSING_SUPER);
231  }
232  else {
233  return vm_call0(th, recv, id, argc, argv, me);
234  }
235 }
236 
237 VALUE
238 rb_call_super(int argc, const VALUE *argv)
239 {
240  rb_thread_t *th = GET_THREAD();
242  return vm_call_super(th, argc, argv);
243 }
244 
245 VALUE
247 {
248  rb_thread_t *th = GET_THREAD();
249  rb_control_frame_t *cfp;
250  if (!th || !(cfp = th->ec.cfp))
251  rb_raise(rb_eRuntimeError, "no self, no life");
252  return cfp->self;
253 }
254 
255 static inline void
256 stack_check(rb_thread_t *th)
257 {
262  }
263 }
264 
265 static inline const rb_callable_method_entry_t *rb_search_method_entry(VALUE recv, ID mid);
266 static inline enum method_missing_reason rb_method_call_status(rb_thread_t *th, const rb_callable_method_entry_t *me, call_type scope, VALUE self);
267 
283 static inline VALUE
284 rb_call0(VALUE recv, ID mid, int argc, const VALUE *argv,
285  call_type scope, VALUE self)
286 {
287  const rb_callable_method_entry_t *me = rb_search_method_entry(recv, mid);
288  rb_thread_t *th = GET_THREAD();
289  enum method_missing_reason call_status = rb_method_call_status(th, me, scope, self);
290 
291  if (call_status != MISSING_NONE) {
292  return method_missing(recv, mid, argc, argv, call_status);
293  }
294  stack_check(th);
295  return vm_call0(th, recv, mid, argc, argv, me);
296 }
297 
304  unsigned int respond: 1;
305  unsigned int respond_to_missing: 1;
306  int argc;
307  const VALUE *argv;
308 };
309 
310 static VALUE
311 check_funcall_exec(struct rescue_funcall_args *args)
312 {
313  return call_method_entry(args->th, args->defined_class,
314  args->recv, idMethodMissing,
315  args->me, args->argc, args->argv);
316 }
317 
318 static VALUE
319 check_funcall_failed(struct rescue_funcall_args *args, VALUE e)
320 {
321  int ret = args->respond;
322  if (!ret) {
323  switch (rb_method_boundp(args->defined_class, args->mid,
325  case 2:
326  ret = TRUE;
327  break;
328  case 0:
329  ret = args->respond_to_missing;
330  break;
331  default:
332  ret = FALSE;
333  break;
334  }
335  }
336  if (ret) {
337  rb_exc_raise(e);
338  }
339  return Qundef;
340 }
341 
342 static int
343 check_funcall_respond_to(rb_thread_t *th, VALUE klass, VALUE recv, ID mid)
344 {
345  return vm_respond_to(th, klass, recv, mid, TRUE);
346 }
347 
348 static int
349 check_funcall_callable(rb_thread_t *th, const rb_callable_method_entry_t *me)
350 {
351  return rb_method_call_status(th, me, CALL_FCALL, th->ec.cfp->self) == MISSING_NONE;
352 }
353 
354 static VALUE
355 check_funcall_missing(rb_thread_t *th, VALUE klass, VALUE recv, ID mid, int argc, const VALUE *argv, int respond, VALUE def)
356 {
357  struct rescue_funcall_args args;
358  const rb_method_entry_t *me;
359  VALUE ret = Qundef;
360 
361  ret = basic_obj_respond_to_missing(th, klass, recv,
362  ID2SYM(mid), Qtrue);
363  if (!RTEST(ret)) return def;
364  args.respond = respond > 0;
365  args.respond_to_missing = (ret != Qundef);
366  ret = def;
367  me = method_entry_get(klass, idMethodMissing, &args.defined_class);
368  if (me && !METHOD_ENTRY_BASIC(me)) {
369  VALUE argbuf, *new_args = ALLOCV_N(VALUE, argbuf, argc+1);
370 
371  new_args[0] = ID2SYM(mid);
372  MEMCPY(new_args+1, argv, VALUE, argc);
374  args.th = th;
375  args.recv = recv;
376  args.me = me;
377  args.mid = mid;
378  args.argc = argc + 1;
379  args.argv = new_args;
380  ret = rb_rescue2(check_funcall_exec, (VALUE)&args,
381  check_funcall_failed, (VALUE)&args,
383  ALLOCV_END(argbuf);
384  }
385  return ret;
386 }
387 
388 VALUE
389 rb_check_funcall(VALUE recv, ID mid, int argc, const VALUE *argv)
390 {
391  return rb_check_funcall_default(recv, mid, argc, argv, Qundef);
392 }
393 
394 VALUE
395 rb_check_funcall_default(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE def)
396 {
397  VALUE klass = CLASS_OF(recv);
399  rb_thread_t *th = GET_THREAD();
400  int respond = check_funcall_respond_to(th, klass, recv, mid);
401 
402  if (!respond)
403  return def;
404 
405  me = rb_search_method_entry(recv, mid);
406  if (!check_funcall_callable(th, me)) {
407  VALUE ret = check_funcall_missing(th, klass, recv, mid, argc, argv,
408  respond, def);
409  if (ret == Qundef) ret = def;
410  return ret;
411  }
412  stack_check(th);
413  return vm_call0(th, recv, mid, argc, argv, me);
414 }
415 
416 VALUE
417 rb_check_funcall_with_hook(VALUE recv, ID mid, int argc, const VALUE *argv,
418  rb_check_funcall_hook *hook, VALUE arg)
419 {
420  VALUE klass = CLASS_OF(recv);
422  rb_thread_t *th = GET_THREAD();
423  int respond = check_funcall_respond_to(th, klass, recv, mid);
424 
425  if (!respond) {
426  (*hook)(FALSE, recv, mid, argc, argv, arg);
427  return Qundef;
428  }
429 
430  me = rb_search_method_entry(recv, mid);
431  if (!check_funcall_callable(th, me)) {
432  VALUE ret = check_funcall_missing(th, klass, recv, mid, argc, argv,
433  respond, Qundef);
434  (*hook)(ret != Qundef, recv, mid, argc, argv, arg);
435  return ret;
436  }
437  stack_check(th);
438  (*hook)(TRUE, recv, mid, argc, argv, arg);
439  return vm_call0(th, recv, mid, argc, argv, me);
440 }
441 
442 static const char *
443 rb_type_str(enum ruby_value_type type)
444 {
445 #define type_case(t) case t: return #t;
446  switch (type) {
473  default: return NULL;
474  }
475 #undef type_case
476 }
477 
478 static inline const rb_callable_method_entry_t *
479 rb_search_method_entry(VALUE recv, ID mid)
480 {
481  VALUE klass = CLASS_OF(recv);
482 
483  if (!klass) {
484  VALUE flags;
485  if (SPECIAL_CONST_P(recv)) {
487  "method `%"PRIsVALUE"' called on unexpected immediate object (%p)",
488  rb_id2str(mid), (void *)recv);
489  }
490  flags = RBASIC(recv)->flags;
491  if (flags == 0) {
493  "method `%"PRIsVALUE"' called on terminated object"
494  " (%p flags=0x%"PRIxVALUE")",
495  rb_id2str(mid), (void *)recv, flags);
496  }
497  else {
498  int type = BUILTIN_TYPE(recv);
499  const char *typestr = rb_type_str(type);
500  if (typestr && T_OBJECT <= type && type < T_NIL)
502  "method `%"PRIsVALUE"' called on hidden %s object"
503  " (%p flags=0x%"PRIxVALUE")",
504  rb_id2str(mid), typestr, (void *)recv, flags);
505  if (typestr)
507  "method `%"PRIsVALUE"' called on unexpected %s object"
508  " (%p flags=0x%"PRIxVALUE")",
509  rb_id2str(mid), typestr, (void *)recv, flags);
510  else
512  "method `%"PRIsVALUE"' called on broken T_???" "(0x%02x) object"
513  " (%p flags=0x%"PRIxVALUE")",
514  rb_id2str(mid), type, (void *)recv, flags);
515  }
516  }
517  return rb_callable_method_entry(klass, mid);
518 }
519 
520 static inline enum method_missing_reason
521 rb_method_call_status(rb_thread_t *th, const rb_callable_method_entry_t *me, call_type scope, VALUE self)
522 {
523  VALUE klass;
524  ID oid;
526 
527  if (UNDEFINED_METHOD_ENTRY_P(me)) {
528  undefined:
529  return scope == CALL_VCALL ? MISSING_VCALL : MISSING_NOENTRY;
530  }
531  if (me->def->type == VM_METHOD_TYPE_REFINED) {
533  if (UNDEFINED_METHOD_ENTRY_P(me)) goto undefined;
534  }
535 
536  klass = me->owner;
537  oid = me->def->original_id;
538  visi = METHOD_ENTRY_VISI(me);
539 
540  if (oid != idMethodMissing) {
541  /* receiver specified form for private method */
542  if (UNLIKELY(visi != METHOD_VISI_PUBLIC)) {
543  if (visi == METHOD_VISI_PRIVATE && scope == CALL_PUBLIC) {
544  return MISSING_PRIVATE;
545  }
546 
547  /* self must be kind of a specified form for protected method */
548  if (visi == METHOD_VISI_PROTECTED && scope == CALL_PUBLIC) {
549  VALUE defined_class = klass;
550 
551  if (RB_TYPE_P(defined_class, T_ICLASS)) {
552  defined_class = RBASIC(defined_class)->klass;
553  }
554 
555  if (self == Qundef || !rb_obj_is_kind_of(self, defined_class)) {
556  return MISSING_PROTECTED;
557  }
558  }
559  }
560  }
561 
562  return MISSING_NONE;
563 }
564 
565 
577 static inline VALUE
578 rb_call(VALUE recv, ID mid, int argc, const VALUE *argv, call_type scope)
579 {
580  rb_thread_t *th = GET_THREAD();
581  return rb_call0(recv, mid, argc, argv, scope, th->ec.cfp->self);
582 }
583 
584 NORETURN(static void raise_method_missing(rb_thread_t *th, int argc, const VALUE *argv,
585  VALUE obj, enum method_missing_reason call_status));
586 
587 /*
588  * call-seq:
589  * obj.method_missing(symbol [, *args] ) -> result
590  *
591  * Invoked by Ruby when <i>obj</i> is sent a message it cannot handle.
592  * <i>symbol</i> is the symbol for the method called, and <i>args</i>
593  * are any arguments that were passed to it. By default, the interpreter
594  * raises an error when this method is called. However, it is possible
595  * to override the method to provide more dynamic behavior.
596  * If it is decided that a particular method should not be handled, then
597  * <i>super</i> should be called, so that ancestors can pick up the
598  * missing method.
599  * The example below creates
600  * a class <code>Roman</code>, which responds to methods with names
601  * consisting of roman numerals, returning the corresponding integer
602  * values.
603  *
604  * class Roman
605  * def roman_to_int(str)
606  * # ...
607  * end
608  * def method_missing(methId)
609  * str = methId.id2name
610  * roman_to_int(str)
611  * end
612  * end
613  *
614  * r = Roman.new
615  * r.iv #=> 4
616  * r.xxiii #=> 23
617  * r.mm #=> 2000
618  */
619 
620 static VALUE
621 rb_method_missing(int argc, const VALUE *argv, VALUE obj)
622 {
623  rb_thread_t *th = GET_THREAD();
624  raise_method_missing(th, argc, argv, obj, th->method_missing_reason);
625  UNREACHABLE;
626 }
627 
628 static VALUE
629 make_no_method_exception(VALUE exc, VALUE format, VALUE obj,
630  int argc, const VALUE *argv, int priv)
631 {
632  int n = 0;
633  enum {
634  arg_mesg,
635  arg_name,
636  arg_args,
637  arg_priv,
638  args_size
639  };
640  VALUE args[args_size];
641 
642  if (!format) {
643  format = rb_fstring_cstr("undefined method `%s' for %s%s%s");
644  }
645  args[n++] = rb_name_err_mesg_new(format, obj, argv[0]);
646  args[n++] = argv[0];
647  if (exc == rb_eNoMethodError) {
648  args[n++] = rb_ary_new4(argc - 1, argv + 1);
649  args[n++] = priv ? Qtrue : Qfalse;
650  }
651  return rb_class_new_instance(n, args, exc);
652 }
653 
654 static void
655 raise_method_missing(rb_thread_t *th, int argc, const VALUE *argv, VALUE obj,
656  enum method_missing_reason last_call_status)
657 {
658  VALUE exc = rb_eNoMethodError;
659  VALUE format = 0;
660 
661  if (UNLIKELY(argc == 0)) {
662  rb_raise(rb_eArgError, "no method name given");
663  }
664  else if (UNLIKELY(!SYMBOL_P(argv[0]))) {
665  const VALUE e = rb_eArgError; /* TODO: TypeError? */
666  rb_raise(e, "method name must be a Symbol but %"PRIsVALUE" is given",
667  rb_obj_class(argv[0]));
668  }
669 
670  stack_check(th);
671 
672  if (last_call_status & MISSING_PRIVATE) {
673  format = rb_fstring_cstr("private method `%s' called for %s%s%s");
674  }
675  else if (last_call_status & MISSING_PROTECTED) {
676  format = rb_fstring_cstr("protected method `%s' called for %s%s%s");
677  }
678  else if (last_call_status & MISSING_VCALL) {
679  format = rb_fstring_cstr("undefined local variable or method `%s' for %s%s%s");
680  exc = rb_eNameError;
681  }
682  else if (last_call_status & MISSING_SUPER) {
683  format = rb_fstring_cstr("super: no superclass method `%s' for %s%s%s");
684  }
685 
686  {
687  exc = make_no_method_exception(exc, format, obj, argc, argv,
688  last_call_status & (MISSING_FCALL|MISSING_VCALL));
689  if (!(last_call_status & MISSING_MISSING)) {
691  }
692  rb_exc_raise(exc);
693  }
694 }
695 
696 static inline VALUE
697 method_missing(VALUE obj, ID id, int argc, const VALUE *argv, enum method_missing_reason call_status)
698 {
699  VALUE *nargv, result, work, klass;
700  rb_thread_t *th = GET_THREAD();
701  VALUE block_handler = vm_passed_block_handler(th);
703 
704  th->method_missing_reason = call_status;
705 
706  if (id == idMethodMissing) {
707  missing:
708  raise_method_missing(th, argc, argv, obj, call_status | MISSING_MISSING);
709  }
710 
711  nargv = ALLOCV_N(VALUE, work, argc + 1);
712  nargv[0] = ID2SYM(id);
713  MEMCPY(nargv + 1, argv, VALUE, argc);
714  ++argc;
715  argv = nargv;
716 
717  klass = CLASS_OF(obj);
718  if (!klass) goto missing;
719  me = rb_callable_method_entry(klass, idMethodMissing);
720  if (!me || METHOD_ENTRY_BASIC(me)) goto missing;
721  vm_passed_block_handler_set(th, block_handler);
722  result = vm_call0(th, obj, idMethodMissing, argc, argv, me);
723  if (work) ALLOCV_END(work);
724  return result;
725 }
726 
727 void
728 rb_raise_method_missing(rb_thread_t *th, int argc, const VALUE *argv,
729  VALUE obj, int call_status)
730 {
731  vm_passed_block_handler_set(th, VM_BLOCK_HANDLER_NONE);
732  raise_method_missing(th, argc, argv, obj, call_status | MISSING_MISSING);
733 }
734 
743 VALUE
744 rb_apply(VALUE recv, ID mid, VALUE args)
745 {
746  int argc;
747  VALUE *argv, ret;
748 
749  argc = RARRAY_LENINT(args);
750  if (argc >= 0x100) {
751  args = rb_ary_subseq(args, 0, argc);
752  RBASIC_CLEAR_CLASS(args);
753  OBJ_FREEZE(args);
754  ret = rb_call(recv, mid, argc, RARRAY_CONST_PTR(args), CALL_FCALL);
755  RB_GC_GUARD(args);
756  return ret;
757  }
758  argv = ALLOCA_N(VALUE, argc);
759  MEMCPY(argv, RARRAY_CONST_PTR(args), VALUE, argc);
760  return rb_call(recv, mid, argc, argv, CALL_FCALL);
761 }
762 
763 #undef rb_funcall
764 
773 VALUE
774 rb_funcall(VALUE recv, ID mid, int n, ...)
775 {
776  VALUE *argv;
777  va_list ar;
778 
779  if (n > 0) {
780  long i;
781 
782  va_init_list(ar, n);
783 
784  argv = ALLOCA_N(VALUE, n);
785 
786  for (i = 0; i < n; i++) {
787  argv[i] = va_arg(ar, VALUE);
788  }
789  va_end(ar);
790  }
791  else {
792  argv = 0;
793  }
794  return rb_call(recv, mid, n, argv, CALL_FCALL);
795 }
796 
804 VALUE
805 rb_funcallv(VALUE recv, ID mid, int argc, const VALUE *argv)
806 {
807  return rb_call(recv, mid, argc, argv, CALL_FCALL);
808 }
809 
819 VALUE
820 rb_funcallv_public(VALUE recv, ID mid, int argc, const VALUE *argv)
821 {
822  return rb_call(recv, mid, argc, argv, CALL_PUBLIC);
823 }
824 
825 VALUE
826 rb_funcall_passing_block(VALUE recv, ID mid, int argc, const VALUE *argv)
827 {
829  return rb_call(recv, mid, argc, argv, CALL_PUBLIC);
830 }
831 
832 VALUE
833 rb_funcall_with_block(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE passed_procval)
834 {
835  if (!NIL_P(passed_procval)) {
836  rb_thread_t *th = GET_THREAD();
837  vm_passed_block_handler_set(th, passed_procval);
838  }
839 
840  return rb_call(recv, mid, argc, argv, CALL_PUBLIC);
841 }
842 
843 static VALUE *
844 current_vm_stack_arg(rb_thread_t *th, const VALUE *argv)
845 {
847  if (RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, prev_cfp)) return NULL;
848  if (prev_cfp->sp + 1 != argv) return NULL;
849  return prev_cfp->sp + 1;
850 }
851 
852 static VALUE
853 send_internal(int argc, const VALUE *argv, VALUE recv, call_type scope)
854 {
855  ID id;
856  VALUE vid;
857  VALUE self;
858  VALUE ret, vargv = 0;
859  rb_thread_t *th = GET_THREAD();
860 
861  if (scope == CALL_PUBLIC) {
862  self = Qundef;
863  }
864  else {
865  self = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->ec.cfp)->self;
866  }
867 
868  if (argc == 0) {
869  rb_raise(rb_eArgError, "no method name given");
870  }
871 
872  vid = *argv;
873 
874  id = rb_check_id(&vid);
875  if (!id) {
876  if (rb_method_basic_definition_p(CLASS_OF(recv), idMethodMissing)) {
877  VALUE exc = make_no_method_exception(rb_eNoMethodError, 0,
878  recv, argc, argv,
879  scope != CALL_PUBLIC);
880  rb_exc_raise(exc);
881  }
882  if (!SYMBOL_P(*argv)) {
883  VALUE *tmp_argv = current_vm_stack_arg(th, argv);
884  vid = rb_str_intern(vid);
885  if (tmp_argv) {
886  tmp_argv[0] = vid;
887  }
888  else if (argc > 1) {
889  tmp_argv = ALLOCV_N(VALUE, vargv, argc);
890  tmp_argv[0] = vid;
891  MEMCPY(tmp_argv+1, argv+1, VALUE, argc-1);
892  argv = tmp_argv;
893  }
894  else {
895  argv = &vid;
896  }
897  }
898  id = idMethodMissing;
900  }
901  else {
902  argv++; argc--;
903  }
905  ret = rb_call0(recv, id, argc, argv, scope, self);
906  ALLOCV_END(vargv);
907  return ret;
908 }
909 
910 /*
911  * call-seq:
912  * foo.send(symbol [, args...]) -> obj
913  * foo.__send__(symbol [, args...]) -> obj
914  * foo.send(string [, args...]) -> obj
915  * foo.__send__(string [, args...]) -> obj
916  *
917  * Invokes the method identified by _symbol_, passing it any
918  * arguments specified. You can use <code>__send__</code> if the name
919  * +send+ clashes with an existing method in _obj_.
920  * When the method is identified by a string, the string is converted
921  * to a symbol.
922  *
923  * class Klass
924  * def hello(*args)
925  * "Hello " + args.join(' ')
926  * end
927  * end
928  * k = Klass.new
929  * k.send :hello, "gentle", "readers" #=> "Hello gentle readers"
930  */
931 
932 VALUE
933 rb_f_send(int argc, VALUE *argv, VALUE recv)
934 {
935  return send_internal(argc, argv, recv, CALL_FCALL);
936 }
937 
938 /*
939  * call-seq:
940  * obj.public_send(symbol [, args...]) -> obj
941  * obj.public_send(string [, args...]) -> obj
942  *
943  * Invokes the method identified by _symbol_, passing it any
944  * arguments specified. Unlike send, public_send calls public
945  * methods only.
946  * When the method is identified by a string, the string is converted
947  * to a symbol.
948  *
949  * 1.public_send(:puts, "hello") # causes NoMethodError
950  */
951 
952 VALUE
953 rb_f_public_send(int argc, VALUE *argv, VALUE recv)
954 {
955  return send_internal(argc, argv, recv, CALL_PUBLIC);
956 }
957 
958 /* yield */
959 
960 static inline VALUE
961 rb_yield_0(int argc, const VALUE * argv)
962 {
963  return vm_yield(GET_THREAD(), argc, argv);
964 }
965 
966 VALUE
968 {
969  return rb_yield_0(1, &val);
970 }
971 
972 VALUE
974 {
975  if (val == Qundef) {
976  return rb_yield_0(0, 0);
977  }
978  else {
979  return rb_yield_1(val);
980  }
981 }
982 
983 #undef rb_yield_values
984 VALUE
985 rb_yield_values(int n, ...)
986 {
987  if (n == 0) {
988  return rb_yield_0(0, 0);
989  }
990  else {
991  int i;
992  VALUE *argv;
993  va_list args;
994  argv = ALLOCA_N(VALUE, n);
995 
996  va_init_list(args, n);
997  for (i=0; i<n; i++) {
998  argv[i] = va_arg(args, VALUE);
999  }
1000  va_end(args);
1001 
1002  return rb_yield_0(n, argv);
1003  }
1004 }
1005 
1006 VALUE
1007 rb_yield_values2(int argc, const VALUE *argv)
1008 {
1009  return rb_yield_0(argc, argv);
1010 }
1011 
1012 VALUE
1014 {
1015  VALUE tmp = rb_check_array_type(values);
1016  VALUE v;
1017  if (NIL_P(tmp)) {
1018  rb_raise(rb_eArgError, "not an array");
1019  }
1020  v = rb_yield_0(RARRAY_LENINT(tmp), RARRAY_CONST_PTR(tmp));
1021  RB_GC_GUARD(tmp);
1022  return v;
1023 }
1024 
1025 VALUE
1027 {
1028  return vm_yield_force_blockarg(GET_THREAD(), values);
1029 }
1030 
1031 VALUE
1032 rb_yield_block(VALUE val, VALUE arg, int argc, const VALUE *argv, VALUE blockarg)
1033 {
1034  return vm_yield_with_block(GET_THREAD(), argc, argv,
1035  NIL_P(blockarg) ? VM_BLOCK_HANDLER_NONE : blockarg);
1036 }
1037 
1038 static VALUE
1039 loop_i(void)
1040 {
1041  for (;;) {
1042  rb_yield_0(0, 0);
1043  }
1044  return Qnil;
1045 }
1046 
1047 static VALUE
1048 loop_stop(VALUE dummy, VALUE exc)
1049 {
1050  return rb_attr_get(exc, id_result);
1051 }
1052 
1053 static VALUE
1054 rb_f_loop_size(VALUE self, VALUE args, VALUE eobj)
1055 {
1056  return DBL2NUM(INFINITY);
1057 }
1058 
1059 /*
1060  * call-seq:
1061  * loop { block }
1062  * loop -> an_enumerator
1063  *
1064  * Repeatedly executes the block.
1065  *
1066  * If no block is given, an enumerator is returned instead.
1067  *
1068  * loop do
1069  * print "Input: "
1070  * line = gets
1071  * break if !line or line =~ /^qQ/
1072  * # ...
1073  * end
1074  *
1075  * StopIteration raised in the block breaks the loop. In this case,
1076  * loop returns the "result" value stored in the exception.
1077  *
1078  * enum = Enumerator.new { |y|
1079  * y << "one"
1080  * y << "two"
1081  * :ok
1082  * }
1083  *
1084  * result = loop {
1085  * puts enum.next
1086  * } #=> :ok
1087  */
1088 
1089 static VALUE
1090 rb_f_loop(VALUE self)
1091 {
1092  RETURN_SIZED_ENUMERATOR(self, 0, 0, rb_f_loop_size);
1093  return rb_rescue2(loop_i, (VALUE)0, loop_stop, (VALUE)0, rb_eStopIteration, (VALUE)0);
1094 }
1095 
1096 #if VMDEBUG
1097 static const char *
1098 vm_frametype_name(const rb_control_frame_t *cfp);
1099 #endif
1100 
1101 static VALUE
1102 rb_iterate0(VALUE (* it_proc) (VALUE), VALUE data1,
1103  const struct vm_ifunc *const ifunc,
1104  rb_thread_t *const th)
1105 {
1106  enum ruby_tag_type state;
1107  volatile VALUE retval = Qnil;
1108  rb_control_frame_t *const cfp = th->ec.cfp;
1109 
1110  TH_PUSH_TAG(th);
1111  state = TH_EXEC_TAG();
1112  if (state == 0) {
1113  iter_retry:
1114  {
1115  VALUE block_handler;
1116 
1117  if (ifunc) {
1118  struct rb_captured_block *captured = VM_CFP_TO_CAPTURED_BLOCK(cfp);
1119  captured->code.ifunc = ifunc;
1120  block_handler = VM_BH_FROM_IFUNC_BLOCK(captured);
1121  }
1122  else {
1123  block_handler = VM_CF_BLOCK_HANDLER(cfp);
1124  }
1125  vm_passed_block_handler_set(th, block_handler);
1126  }
1127  retval = (*it_proc) (data1);
1128  }
1129  else if (state == TAG_BREAK || state == TAG_RETRY) {
1130  const struct vm_throw_data *const err = (struct vm_throw_data *)th->ec.errinfo;
1131  const rb_control_frame_t *const escape_cfp = THROW_DATA_CATCH_FRAME(err);
1132 
1133  if (cfp == escape_cfp) {
1134  rb_vm_rewind_cfp(th, cfp);
1135 
1136  state = 0;
1137  th->ec.tag->state = TAG_NONE;
1138  th->ec.errinfo = Qnil;
1139 
1140  if (state == TAG_RETRY) goto iter_retry;
1141  retval = THROW_DATA_VAL(err);
1142  }
1143  else if (0) {
1144  SDR(); fprintf(stderr, "%p, %p\n", cfp, escape_cfp);
1145  }
1146  }
1147  TH_POP_TAG();
1148 
1149  if (state) {
1150  TH_JUMP_TAG(th, state);
1151  }
1152  return retval;
1153 }
1154 
1155 VALUE
1156 rb_iterate(VALUE (* it_proc)(VALUE), VALUE data1,
1157  VALUE (* bl_proc)(ANYARGS), VALUE data2)
1158 {
1159  return rb_iterate0(it_proc, data1,
1160  bl_proc ? rb_vm_ifunc_proc_new(bl_proc, (void *)data2) : 0,
1161  GET_THREAD());
1162 }
1163 
1167  int argc;
1168  const VALUE *argv;
1169 };
1170 
1171 static VALUE
1172 iterate_method(VALUE obj)
1173 {
1174  const struct iter_method_arg * arg =
1175  (struct iter_method_arg *) obj;
1176 
1177  return rb_call(arg->obj, arg->mid, arg->argc, arg->argv, CALL_FCALL);
1178 }
1179 
1180 VALUE
1181 rb_block_call(VALUE obj, ID mid, int argc, const VALUE * argv,
1182  VALUE (*bl_proc) (ANYARGS), VALUE data2)
1183 {
1184  struct iter_method_arg arg;
1185 
1186  arg.obj = obj;
1187  arg.mid = mid;
1188  arg.argc = argc;
1189  arg.argv = argv;
1190  return rb_iterate(iterate_method, (VALUE)&arg, bl_proc, data2);
1191 }
1192 
1193 VALUE
1194 rb_lambda_call(VALUE obj, ID mid, int argc, const VALUE *argv,
1195  rb_block_call_func_t bl_proc, int min_argc, int max_argc,
1196  VALUE data2)
1197 {
1198  struct iter_method_arg arg;
1199  struct vm_ifunc *block;
1200 
1201  if (!bl_proc) rb_raise(rb_eArgError, "NULL lambda function");
1202  arg.obj = obj;
1203  arg.mid = mid;
1204  arg.argc = argc;
1205  arg.argv = argv;
1206  block = rb_vm_ifunc_new(bl_proc, (void *)data2, min_argc, max_argc);
1207  return rb_iterate0(iterate_method, (VALUE)&arg, block, GET_THREAD());
1208 }
1209 
1210 static VALUE
1211 iterate_check_method(VALUE obj)
1212 {
1213  const struct iter_method_arg * arg =
1214  (struct iter_method_arg *) obj;
1215 
1216  return rb_check_funcall(arg->obj, arg->mid, arg->argc, arg->argv);
1217 }
1218 
1219 VALUE
1220 rb_check_block_call(VALUE obj, ID mid, int argc, const VALUE *argv,
1221  VALUE (*bl_proc) (ANYARGS), VALUE data2)
1222 {
1223  struct iter_method_arg arg;
1224 
1225  arg.obj = obj;
1226  arg.mid = mid;
1227  arg.argc = argc;
1228  arg.argv = argv;
1229  return rb_iterate(iterate_check_method, (VALUE)&arg, bl_proc, data2);
1230 }
1231 
1232 VALUE
1234 {
1235  return rb_call(obj, idEach, 0, 0, CALL_FCALL);
1236 }
1237 
1238 static VALUE
1239 adjust_backtrace_in_eval(rb_thread_t *th, VALUE errinfo)
1240 {
1241  VALUE errat = rb_get_backtrace(errinfo);
1242  VALUE mesg = rb_attr_get(errinfo, id_mesg);
1243  if (RB_TYPE_P(errat, T_ARRAY)) {
1244  VALUE bt2 = rb_threadptr_backtrace_str_ary(th, 0, 0);
1245  if (RARRAY_LEN(bt2) > 0) {
1246  if (RB_TYPE_P(mesg, T_STRING) && !RSTRING_LEN(mesg)) {
1247  rb_ivar_set(errinfo, id_mesg, RARRAY_AREF(errat, 0));
1248  }
1249  RARRAY_ASET(errat, 0, RARRAY_AREF(bt2, 0));
1250  }
1251  }
1252  return errinfo;
1253 }
1254 
1255 static VALUE
1256 eval_string_with_cref(VALUE self, VALUE src, VALUE scope, rb_cref_t *const cref_arg,
1257  VALUE filename, int lineno)
1258 {
1259  int state;
1260  VALUE result = Qundef;
1261  rb_thread_t *volatile th = GET_THREAD();
1262  struct rb_block block;
1263  const struct rb_block *base_block;
1264  volatile VALUE file;
1265  volatile int line;
1266 
1267  file = filename ? filename : rb_source_location(&lineno);
1268  line = lineno;
1269 
1270  {
1271  rb_cref_t *cref = cref_arg;
1272  rb_binding_t *bind = 0;
1273  const rb_iseq_t *iseq;
1274  VALUE realpath = Qnil;
1275  VALUE fname;
1276 
1277  if (file != Qundef) {
1278  realpath = file;
1279  }
1280 
1281  if (!NIL_P(scope)) {
1282  bind = Check_TypedStruct(scope, &ruby_binding_data_type);
1283 
1284  if (NIL_P(realpath)) {
1285  file = pathobj_path(bind->pathobj);
1286  realpath = pathobj_realpath(bind->pathobj);
1287  line = bind->first_lineno;
1288  }
1289  base_block = &bind->block;
1290  }
1291  else {
1293 
1294  if (cfp != 0) {
1295  block.as.captured = *VM_CFP_TO_CAPTURED_BLOCK(cfp);
1296  block.as.captured.self = self;
1297  block.as.captured.code.iseq = cfp->iseq;
1298  block.type = block_type_iseq;
1299  base_block = &block;
1300  }
1301  else {
1302  rb_raise(rb_eRuntimeError, "Can't eval on top of Fiber or Thread");
1303  }
1304  }
1305 
1306  if ((fname = file) == Qundef) {
1307  fname = rb_usascii_str_new_cstr("(eval)");
1308  }
1309 
1310  /* make eval iseq */
1311  iseq = rb_iseq_compile_with_option(src, fname, realpath, INT2FIX(line), base_block, Qnil);
1312 
1313  if (!iseq) {
1314  rb_exc_raise(adjust_backtrace_in_eval(th, th->ec.errinfo));
1315  }
1316 
1317  /* TODO: what the code checking? */
1318  if (!cref && base_block->as.captured.code.val) {
1319  if (NIL_P(scope)) {
1320  rb_cref_t *orig_cref = rb_vm_get_cref(vm_block_ep(base_block));
1321  cref = vm_cref_dup(orig_cref);
1322  }
1323  else {
1324  cref = NULL; /* use stacked CREF */
1325  }
1326  }
1327  vm_set_eval_stack(th, iseq, cref, base_block);
1328 
1329  if (0) { /* for debug */
1330  VALUE disasm = rb_iseq_disasm(iseq);
1331  printf("%s\n", StringValuePtr(disasm));
1332  }
1333 
1334  /* save new env */
1335  if (bind && iseq->body->local_table_size > 0) {
1336  vm_bind_update_env(scope, bind, vm_make_env_object(th, th->ec.cfp));
1337  }
1338  }
1339 
1340  if (file != Qundef) {
1341  /* kick */
1342  return vm_exec(th);
1343  }
1344 
1345  TH_PUSH_TAG(th);
1346  if ((state = TH_EXEC_TAG()) == TAG_NONE) {
1347  result = vm_exec(th);
1348  }
1349  TH_POP_TAG();
1350 
1351  if (state) {
1352  if (state == TAG_RAISE) {
1353  adjust_backtrace_in_eval(th, th->ec.errinfo);
1354  }
1355  TH_JUMP_TAG(th, state);
1356  }
1357  return result;
1358 }
1359 
1360 static VALUE
1361 eval_string(VALUE self, VALUE src, VALUE scope, VALUE file, int line)
1362 {
1363  return eval_string_with_cref(self, src, scope, 0, file, line);
1364 }
1365 
1366 /*
1367  * call-seq:
1368  * eval(string [, binding [, filename [,lineno]]]) -> obj
1369  *
1370  * Evaluates the Ruby expression(s) in <em>string</em>. If
1371  * <em>binding</em> is given, which must be a <code>Binding</code>
1372  * object, the evaluation is performed in its context. If the
1373  * optional <em>filename</em> and <em>lineno</em> parameters are
1374  * present, they will be used when reporting syntax errors.
1375  *
1376  * def get_binding(str)
1377  * return binding
1378  * end
1379  * str = "hello"
1380  * eval "str + ' Fred'" #=> "hello Fred"
1381  * eval "str + ' Fred'", get_binding("bye") #=> "bye Fred"
1382  */
1383 
1384 VALUE
1385 rb_f_eval(int argc, const VALUE *argv, VALUE self)
1386 {
1387  VALUE src, scope, vfile, vline;
1388  VALUE file = Qundef;
1389  int line = 1;
1390 
1391  rb_scan_args(argc, argv, "13", &src, &scope, &vfile, &vline);
1392  SafeStringValue(src);
1393  if (argc >= 3) {
1394  StringValue(vfile);
1395  }
1396  if (argc >= 4) {
1397  line = NUM2INT(vline);
1398  }
1399 
1400  if (!NIL_P(vfile))
1401  file = vfile;
1402  return eval_string(self, src, scope, file, line);
1403 }
1404 
1406 VALUE
1407 ruby_eval_string_from_file(const char *str, const char *filename)
1408 {
1409  VALUE file = filename ? rb_str_new_cstr(filename) : 0;
1410  return eval_string(rb_vm_top_self(), rb_str_new2(str), Qnil, file, 1);
1411 }
1412 
1416 };
1417 
1418 static VALUE
1419 eval_string_from_file_helper(VALUE data)
1420 {
1421  const struct eval_string_from_file_arg *const arg = (struct eval_string_from_file_arg*)data;
1422  return eval_string(rb_vm_top_self(), arg->str, Qnil, arg->filename, 1);
1423 }
1424 
1425 VALUE
1426 ruby_eval_string_from_file_protect(const char *str, const char *filename, int *state)
1427 {
1428  struct eval_string_from_file_arg arg;
1429  arg.str = rb_str_new_cstr(str);
1430  arg.filename = filename ? rb_str_new_cstr(filename) : 0;
1431  return rb_protect(eval_string_from_file_helper, (VALUE)&arg, state);
1432 }
1433 
1446 VALUE
1447 rb_eval_string(const char *str)
1448 {
1449  return ruby_eval_string_from_file(str, "eval");
1450 }
1451 
1462 VALUE
1463 rb_eval_string_protect(const char *str, int *pstate)
1464 {
1465  return rb_protect((VALUE (*)(VALUE))rb_eval_string, (VALUE)str, pstate);
1466 }
1467 
1479 VALUE
1480 rb_eval_string_wrap(const char *str, int *pstate)
1481 {
1482  int state;
1483  rb_thread_t *th = GET_THREAD();
1484  VALUE self = th->top_self;
1485  VALUE wrapper = th->top_wrapper;
1486  VALUE val;
1487 
1488  th->top_wrapper = rb_module_new();
1491 
1492  val = rb_eval_string_protect(str, &state);
1493 
1494  th->top_self = self;
1495  th->top_wrapper = wrapper;
1496 
1497  if (pstate) {
1498  *pstate = state;
1499  }
1500  else if (state != TAG_NONE) {
1501  TH_JUMP_TAG(th, state);
1502  }
1503  return val;
1504 }
1505 
1506 VALUE
1508 {
1509  enum ruby_tag_type state;
1510  volatile VALUE val = Qnil; /* OK */
1511  const int VAR_NOCLOBBERED(safe) = rb_safe_level();
1512  rb_thread_t *const VAR_NOCLOBBERED(th) = GET_THREAD();
1513 
1514  if (OBJ_TAINTED(cmd)) {
1515  level = RUBY_SAFE_LEVEL_MAX;
1516  }
1517 
1518  TH_PUSH_TAG(th);
1519  rb_set_safe_level_force(level);
1520  if ((state = TH_EXEC_TAG()) == TAG_NONE) {
1521  if (!RB_TYPE_P(cmd, T_STRING)) {
1522  val = rb_funcallv(cmd, idCall, RARRAY_LENINT(arg),
1523  RARRAY_CONST_PTR(arg));
1524  }
1525  else {
1526  val = eval_string(rb_vm_top_self(), cmd, Qnil, 0, 0);
1527  }
1528  }
1529  TH_POP_TAG();
1530 
1532  if (state) TH_JUMP_TAG(th, state);
1533  return val;
1534 }
1535 
1536 /* block eval under the class/module context */
1537 
1538 static VALUE
1539 yield_under(VALUE under, VALUE self, int argc, const VALUE *argv)
1540 {
1541  rb_thread_t *th = GET_THREAD();
1542  rb_control_frame_t *cfp = th->ec.cfp;
1543  VALUE block_handler = VM_CF_BLOCK_HANDLER(cfp);
1544  VALUE new_block_handler = 0;
1545  const struct rb_captured_block *captured = NULL;
1546  struct rb_captured_block new_captured;
1547  const VALUE *ep = NULL;
1548  rb_cref_t *cref;
1549  int is_lambda = FALSE;
1550 
1551  if (block_handler != VM_BLOCK_HANDLER_NONE) {
1552  again:
1553  switch (vm_block_handler_type(block_handler)) {
1555  captured = VM_BH_TO_CAPT_BLOCK(block_handler);
1556  new_captured = *captured;
1557  new_block_handler = VM_BH_FROM_ISEQ_BLOCK(&new_captured);
1558  break;
1560  captured = VM_BH_TO_CAPT_BLOCK(block_handler);
1561  new_captured = *captured;
1562  new_block_handler = VM_BH_FROM_IFUNC_BLOCK(&new_captured);
1563  break;
1565  is_lambda = rb_proc_lambda_p(block_handler) != Qfalse;
1566  block_handler = vm_proc_to_block_handler(VM_BH_TO_PROC(block_handler));
1567  goto again;
1569  return rb_sym_proc_call(SYM2ID(VM_BH_TO_SYMBOL(block_handler)),
1570  argc, argv, VM_BLOCK_HANDLER_NONE);
1571  }
1572 
1573  new_captured.self = self;
1574  ep = captured->ep;
1575 
1576  VM_FORCE_WRITE_SPECIAL_CONST(&VM_CF_LEP(th->ec.cfp)[VM_ENV_DATA_INDEX_SPECVAL], new_block_handler);
1577  }
1578 
1579  cref = vm_cref_push(th, under, ep, TRUE);
1580  return vm_yield_with_cref(th, argc, argv, cref, is_lambda);
1581 }
1582 
1583 VALUE
1584 rb_yield_refine_block(VALUE refinement, VALUE refinements)
1585 {
1586  rb_thread_t *th = GET_THREAD();
1587  VALUE block_handler = VM_CF_BLOCK_HANDLER(th->ec.cfp);
1588 
1589  if (vm_block_handler_type(block_handler) != block_handler_type_iseq) {
1590  rb_bug("rb_yield_refine_block: an iseq block is required");
1591  }
1592  else {
1593  const struct rb_captured_block *captured = VM_BH_TO_ISEQ_BLOCK(block_handler);
1594  struct rb_captured_block new_captured = *captured;
1595  VALUE new_block_handler = VM_BH_FROM_ISEQ_BLOCK(&new_captured);
1596  const VALUE *ep = captured->ep;
1597  rb_cref_t *cref = vm_cref_push(th, refinement, ep, TRUE);
1598  CREF_REFINEMENTS_SET(cref, refinements);
1599  VM_FORCE_WRITE_SPECIAL_CONST(&VM_CF_LEP(th->ec.cfp)[VM_ENV_DATA_INDEX_SPECVAL], new_block_handler);
1600  new_captured.self = refinement;
1601  return vm_yield_with_cref(th, 0, NULL, cref, FALSE);
1602  }
1603 }
1604 
1605 /* string eval under the class/module context */
1606 static VALUE
1607 eval_under(VALUE under, VALUE self, VALUE src, VALUE file, int line)
1608 {
1609  rb_cref_t *cref = vm_cref_push(GET_THREAD(), under, NULL, SPECIAL_CONST_P(self) && !NIL_P(under));
1610  SafeStringValue(src);
1611  return eval_string_with_cref(self, src, Qnil, cref, file, line);
1612 }
1613 
1614 static VALUE
1615 specific_eval(int argc, const VALUE *argv, VALUE klass, VALUE self)
1616 {
1617  if (rb_block_given_p()) {
1618  rb_check_arity(argc, 0, 0);
1619  return yield_under(klass, self, 1, &self);
1620  }
1621  else {
1622  VALUE file = Qundef;
1623  int line = 1;
1624  VALUE code;
1625 
1626  rb_check_arity(argc, 1, 3);
1627  code = argv[0];
1628  SafeStringValue(code);
1629  if (argc > 2)
1630  line = NUM2INT(argv[2]);
1631  if (argc > 1) {
1632  file = argv[1];
1633  if (!NIL_P(file)) StringValue(file);
1634  }
1635  return eval_under(klass, self, code, file, line);
1636  }
1637 }
1638 
1639 static VALUE
1640 singleton_class_for_eval(VALUE self)
1641 {
1642  if (SPECIAL_CONST_P(self)) {
1643  return rb_special_singleton_class(self);
1644  }
1645  switch (BUILTIN_TYPE(self)) {
1646  case T_FLOAT: case T_BIGNUM: case T_SYMBOL:
1647  return Qnil;
1648  case T_STRING:
1649  if (FL_TEST_RAW(self, RSTRING_FSTR)) return Qnil;
1650  default:
1651  return rb_singleton_class(self);
1652  }
1653 }
1654 
1655 /*
1656  * call-seq:
1657  * obj.instance_eval(string [, filename [, lineno]] ) -> obj
1658  * obj.instance_eval {|obj| block } -> obj
1659  *
1660  * Evaluates a string containing Ruby source code, or the given block,
1661  * within the context of the receiver (_obj_). In order to set the
1662  * context, the variable +self+ is set to _obj_ while
1663  * the code is executing, giving the code access to _obj_'s
1664  * instance variables and private methods.
1665  *
1666  * When <code>instance_eval</code> is given a block, _obj_ is also
1667  * passed in as the block's only argument.
1668  *
1669  * When <code>instance_eval</code> is given a +String+, the optional
1670  * second and third parameters supply a filename and starting line number
1671  * that are used when reporting compilation errors.
1672  *
1673  * class KlassWithSecret
1674  * def initialize
1675  * @secret = 99
1676  * end
1677  * private
1678  * def the_secret
1679  * "Ssssh! The secret is #{@secret}."
1680  * end
1681  * end
1682  * k = KlassWithSecret.new
1683  * k.instance_eval { @secret } #=> 99
1684  * k.instance_eval { the_secret } #=> "Ssssh! The secret is 99."
1685  * k.instance_eval {|obj| obj == self } #=> true
1686  */
1687 
1688 VALUE
1689 rb_obj_instance_eval(int argc, const VALUE *argv, VALUE self)
1690 {
1691  VALUE klass = singleton_class_for_eval(self);
1692  return specific_eval(argc, argv, klass, self);
1693 }
1694 
1695 /*
1696  * call-seq:
1697  * obj.instance_exec(arg...) {|var...| block } -> obj
1698  *
1699  * Executes the given block within the context of the receiver
1700  * (_obj_). In order to set the context, the variable +self+ is set
1701  * to _obj_ while the code is executing, giving the code access to
1702  * _obj_'s instance variables. Arguments are passed as block parameters.
1703  *
1704  * class KlassWithSecret
1705  * def initialize
1706  * @secret = 99
1707  * end
1708  * end
1709  * k = KlassWithSecret.new
1710  * k.instance_exec(5) {|x| @secret+x } #=> 104
1711  */
1712 
1713 VALUE
1714 rb_obj_instance_exec(int argc, const VALUE *argv, VALUE self)
1715 {
1716  VALUE klass = singleton_class_for_eval(self);
1717  return yield_under(klass, self, argc, argv);
1718 }
1719 
1720 /*
1721  * call-seq:
1722  * mod.class_eval(string [, filename [, lineno]]) -> obj
1723  * mod.class_eval {|mod| block } -> obj
1724  * mod.module_eval(string [, filename [, lineno]]) -> obj
1725  * mod.module_eval {|mod| block } -> obj
1726  *
1727  * Evaluates the string or block in the context of _mod_, except that when
1728  * a block is given, constant/class variable lookup is not affected. This
1729  * can be used to add methods to a class. <code>module_eval</code> returns
1730  * the result of evaluating its argument. The optional _filename_ and
1731  * _lineno_ parameters set the text for error messages.
1732  *
1733  * class Thing
1734  * end
1735  * a = %q{def hello() "Hello there!" end}
1736  * Thing.module_eval(a)
1737  * puts Thing.new.hello()
1738  * Thing.module_eval("invalid code", "dummy", 123)
1739  *
1740  * <em>produces:</em>
1741  *
1742  * Hello there!
1743  * dummy:123:in `module_eval': undefined local variable
1744  * or method `code' for Thing:Class
1745  */
1746 
1747 VALUE
1748 rb_mod_module_eval(int argc, const VALUE *argv, VALUE mod)
1749 {
1750  return specific_eval(argc, argv, mod, mod);
1751 }
1752 
1753 /*
1754  * call-seq:
1755  * mod.module_exec(arg...) {|var...| block } -> obj
1756  * mod.class_exec(arg...) {|var...| block } -> obj
1757  *
1758  * Evaluates the given block in the context of the class/module.
1759  * The method defined in the block will belong to the receiver.
1760  * Any arguments passed to the method will be passed to the block.
1761  * This can be used if the block needs to access instance variables.
1762  *
1763  * class Thing
1764  * end
1765  * Thing.class_exec{
1766  * def hello() "Hello there!" end
1767  * }
1768  * puts Thing.new.hello()
1769  *
1770  * <em>produces:</em>
1771  *
1772  * Hello there!
1773  */
1774 
1775 VALUE
1776 rb_mod_module_exec(int argc, const VALUE *argv, VALUE mod)
1777 {
1778  return yield_under(mod, mod, argc, argv);
1779 }
1780 
1781 /*
1782  * Document-class: UncaughtThrowError
1783  *
1784  * Raised when +throw+ is called with a _tag_ which does not have
1785  * corresponding +catch+ block.
1786  *
1787  * throw "foo", "bar"
1788  *
1789  * <em>raises the exception:</em>
1790  *
1791  * UncaughtThrowError: uncaught throw "foo"
1792  */
1793 
1794 static VALUE
1795 uncaught_throw_init(int argc, const VALUE *argv, VALUE exc)
1796 {
1798  rb_call_super(argc - 2, argv + 2);
1799  rb_ivar_set(exc, id_tag, argv[0]);
1800  rb_ivar_set(exc, id_value, argv[1]);
1801  return exc;
1802 }
1803 
1804 /*
1805  * call-seq:
1806  * uncaught_throw.tag -> obj
1807  *
1808  * Return the tag object which was called for.
1809  */
1810 
1811 static VALUE
1812 uncaught_throw_tag(VALUE exc)
1813 {
1814  return rb_ivar_get(exc, id_tag);
1815 }
1816 
1817 /*
1818  * call-seq:
1819  * uncaught_throw.value -> obj
1820  *
1821  * Return the return value which was called for.
1822  */
1823 
1824 static VALUE
1825 uncaught_throw_value(VALUE exc)
1826 {
1827  return rb_ivar_get(exc, id_value);
1828 }
1829 
1830 /*
1831  * call-seq:
1832  * uncaught_throw.to_s -> string
1833  *
1834  * Returns formatted message with the inspected tag.
1835  */
1836 
1837 static VALUE
1838 uncaught_throw_to_s(VALUE exc)
1839 {
1840  VALUE mesg = rb_attr_get(exc, id_mesg);
1841  VALUE tag = uncaught_throw_tag(exc);
1842  return rb_str_format(1, &tag, mesg);
1843 }
1844 
1845 /*
1846  * call-seq:
1847  * throw(tag [, obj])
1848  *
1849  * Transfers control to the end of the active +catch+ block
1850  * waiting for _tag_. Raises +UncaughtThrowError+ if there
1851  * is no +catch+ block for the _tag_. The optional second
1852  * parameter supplies a return value for the +catch+ block,
1853  * which otherwise defaults to +nil+. For examples, see
1854  * <code>Kernel::catch</code>.
1855  */
1856 
1857 static VALUE
1858 rb_f_throw(int argc, VALUE *argv)
1859 {
1860  VALUE tag, value;
1861 
1862  rb_scan_args(argc, argv, "11", &tag, &value);
1863  rb_throw_obj(tag, value);
1864  UNREACHABLE;
1865 }
1866 
1867 void
1869 {
1870  rb_thread_t *th = GET_THREAD();
1871  struct rb_vm_tag *tt = th->ec.tag;
1872 
1873  while (tt) {
1874  if (tt->tag == tag) {
1875  tt->retval = value;
1876  break;
1877  }
1878  tt = tt->prev;
1879  }
1880  if (!tt) {
1881  VALUE desc[3];
1882  desc[0] = tag;
1883  desc[1] = value;
1884  desc[2] = rb_str_new_cstr("uncaught throw %p");
1885  rb_exc_raise(rb_class_new_instance(numberof(desc), desc, rb_eUncaughtThrow));
1886  }
1887 
1888  th->ec.errinfo = (VALUE)THROW_DATA_NEW(tag, NULL, TAG_THROW);
1889  TH_JUMP_TAG(th, TAG_THROW);
1890 }
1891 
1892 void
1893 rb_throw(const char *tag, VALUE val)
1894 {
1896 }
1897 
1898 static VALUE
1899 catch_i(VALUE tag, VALUE data)
1900 {
1901  return rb_yield_0(1, &tag);
1902 }
1903 
1904 /*
1905  * call-seq:
1906  * catch([tag]) {|tag| block } -> obj
1907  *
1908  * +catch+ executes its block. If +throw+ is not called, the block executes
1909  * normally, and +catch+ returns the value of the last expression evaluated.
1910  *
1911  * catch(1) { 123 } # => 123
1912  *
1913  * If <code>throw(tag2, val)</code> is called, Ruby searches up its stack for
1914  * a +catch+ block whose +tag+ has the same +object_id+ as _tag2_. When found,
1915  * the block stops executing and returns _val_ (or +nil+ if no second argument
1916  * was given to +throw+).
1917  *
1918  * catch(1) { throw(1, 456) } # => 456
1919  * catch(1) { throw(1) } # => nil
1920  *
1921  * When +tag+ is passed as the first argument, +catch+ yields it as the
1922  * parameter of the block.
1923  *
1924  * catch(1) {|x| x + 2 } # => 3
1925  *
1926  * When no +tag+ is given, +catch+ yields a new unique object (as from
1927  * +Object.new+) as the block parameter. This object can then be used as the
1928  * argument to +throw+, and will match the correct +catch+ block.
1929  *
1930  * catch do |obj_A|
1931  * catch do |obj_B|
1932  * throw(obj_B, 123)
1933  * puts "This puts is not reached"
1934  * end
1935  *
1936  * puts "This puts is displayed"
1937  * 456
1938  * end
1939  *
1940  * # => 456
1941  *
1942  * catch do |obj_A|
1943  * catch do |obj_B|
1944  * throw(obj_A, 123)
1945  * puts "This puts is still not reached"
1946  * end
1947  *
1948  * puts "Now this puts is also not reached"
1949  * 456
1950  * end
1951  *
1952  * # => 123
1953  */
1954 
1955 static VALUE
1956 rb_f_catch(int argc, VALUE *argv)
1957 {
1958  VALUE tag;
1959 
1960  if (argc == 0) {
1961  tag = rb_obj_alloc(rb_cObject);
1962  }
1963  else {
1964  rb_scan_args(argc, argv, "01", &tag);
1965  }
1966  return rb_catch_obj(tag, catch_i, 0);
1967 }
1968 
1969 VALUE
1970 rb_catch(const char *tag, VALUE (*func)(), VALUE data)
1971 {
1973  return rb_catch_obj(vtag, func, data);
1974 }
1975 
1976 static VALUE
1977 vm_catch_protect(VALUE tag, rb_block_call_func *func, VALUE data,
1978  enum ruby_tag_type *stateptr, rb_thread_t *volatile th)
1979 {
1980  enum ruby_tag_type state;
1981  VALUE val = Qnil; /* OK */
1982  rb_control_frame_t *volatile saved_cfp = th->ec.cfp;
1983 
1984  TH_PUSH_TAG(th);
1985 
1986  _tag.tag = tag;
1987 
1988  if ((state = TH_EXEC_TAG()) == TAG_NONE) {
1989  /* call with argc=1, argv = [tag], block = Qnil to insure compatibility */
1990  val = (*func)(tag, data, 1, (const VALUE *)&tag, Qnil);
1991  }
1992  else if (state == TAG_THROW && THROW_DATA_VAL((struct vm_throw_data *)th->ec.errinfo) == tag) {
1993  rb_vm_rewind_cfp(th, saved_cfp);
1994  val = th->ec.tag->retval;
1995  th->ec.errinfo = Qnil;
1996  state = 0;
1997  }
1998  TH_POP_TAG();
1999  if (stateptr)
2000  *stateptr = state;
2001 
2002  return val;
2003 }
2004 
2005 VALUE
2007 {
2008  return vm_catch_protect(t, func, data, stateptr, GET_THREAD());
2009 }
2010 
2011 VALUE
2012 rb_catch_obj(VALUE t, VALUE (*func)(), VALUE data)
2013 {
2014  enum ruby_tag_type state;
2015  rb_thread_t *th = GET_THREAD();
2016  VALUE val = vm_catch_protect(t, (rb_block_call_func *)func, data, &state, th);
2017  if (state) TH_JUMP_TAG(th, state);
2018  return val;
2019 }
2020 
2021 static void
2022 local_var_list_init(struct local_var_list *vars)
2023 {
2024  vars->tbl = rb_hash_new();
2025  RHASH(vars->tbl)->ntbl = st_init_numtable(); /* compare_by_identity */
2026  RBASIC_CLEAR_CLASS(vars->tbl);
2027 }
2028 
2029 static VALUE
2030 local_var_list_finish(struct local_var_list *vars)
2031 {
2032  /* TODO: not to depend on the order of st_table */
2033  VALUE ary = rb_hash_keys(vars->tbl);
2034  rb_hash_clear(vars->tbl);
2035  vars->tbl = 0;
2036  return ary;
2037 }
2038 
2039 static int
2040 local_var_list_update(st_data_t *key, st_data_t *value, st_data_t arg, int existing)
2041 {
2042  if (existing) return ST_STOP;
2043  *value = (st_data_t)Qtrue; /* INT2FIX(arg) */
2044  return ST_CONTINUE;
2045 }
2046 
2047 static void
2048 local_var_list_add(const struct local_var_list *vars, ID lid)
2049 {
2050  if (lid && rb_is_local_id(lid)) {
2051  /* should skip temporary variable */
2052  st_table *tbl = RHASH_TBL_RAW(vars->tbl);
2053  st_data_t idx = 0; /* tbl->num_entries */
2054  st_update(tbl, ID2SYM(lid), local_var_list_update, idx);
2055  }
2056 }
2057 
2058 /*
2059  * call-seq:
2060  * local_variables -> array
2061  *
2062  * Returns the names of the current local variables.
2063  *
2064  * fred = 1
2065  * for i in 1..10
2066  * # ...
2067  * end
2068  * local_variables #=> [:fred, :i]
2069  */
2070 
2071 static VALUE
2072 rb_f_local_variables(void)
2073 {
2074  struct local_var_list vars;
2075  rb_thread_t *th = GET_THREAD();
2076  rb_control_frame_t *cfp =
2077  vm_get_ruby_level_caller_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(th->ec.cfp));
2078  unsigned int i;
2079 
2080  local_var_list_init(&vars);
2081  while (cfp) {
2082  if (cfp->iseq) {
2083  for (i = 0; i < cfp->iseq->body->local_table_size; i++) {
2084  local_var_list_add(&vars, cfp->iseq->body->local_table[i]);
2085  }
2086  }
2087  if (!VM_ENV_LOCAL_P(cfp->ep)) {
2088  /* block */
2089  const VALUE *ep = VM_CF_PREV_EP(cfp);
2090 
2091  if (vm_collect_local_variables_in_heap(th, ep, &vars)) {
2092  break;
2093  }
2094  else {
2095  while (cfp->ep != ep) {
2096  cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
2097  }
2098  }
2099  }
2100  else {
2101  break;
2102  }
2103  }
2104  return local_var_list_finish(&vars);
2105 }
2106 
2107 /*
2108  * call-seq:
2109  * block_given? -> true or false
2110  * iterator? -> true or false
2111  *
2112  * Returns <code>true</code> if <code>yield</code> would execute a
2113  * block in the current context. The <code>iterator?</code> form
2114  * is mildly deprecated.
2115  *
2116  * def try
2117  * if block_given?
2118  * yield
2119  * else
2120  * "no block"
2121  * end
2122  * end
2123  * try #=> "no block"
2124  * try { "hello" } #=> "hello"
2125  * try do "hello" end #=> "hello"
2126  */
2127 
2128 
2129 VALUE
2131 {
2132  rb_thread_t *th = GET_THREAD();
2133  rb_control_frame_t *cfp = th->ec.cfp;
2134  cfp = vm_get_ruby_level_caller_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
2135 
2136  if (cfp != NULL && VM_CF_BLOCK_HANDLER(cfp) != VM_BLOCK_HANDLER_NONE) {
2137  return Qtrue;
2138  }
2139  else {
2140  return Qfalse;
2141  }
2142 }
2143 
2144 VALUE
2146 {
2147  rb_thread_t *th = GET_THREAD();
2148  rb_control_frame_t *cfp = th->ec.cfp;
2149  cfp = vm_get_ruby_level_caller_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
2150  if (cfp != 0) return rb_iseq_realpath(cfp->iseq);
2151  return Qnil;
2152 }
2153 
2154 void
2156 {
2157  rb_define_global_function("eval", rb_f_eval, -1);
2158  rb_define_global_function("local_variables", rb_f_local_variables, 0);
2160  rb_define_global_function("block_given?", rb_f_block_given_p, 0);
2161 
2162  rb_define_global_function("catch", rb_f_catch, -1);
2163  rb_define_global_function("throw", rb_f_throw, -1);
2164 
2165  rb_define_global_function("loop", rb_f_loop, 0);
2166 
2167  rb_define_method(rb_cBasicObject, "instance_eval", rb_obj_instance_eval, -1);
2168  rb_define_method(rb_cBasicObject, "instance_exec", rb_obj_instance_exec, -1);
2169  rb_define_private_method(rb_cBasicObject, "method_missing", rb_method_missing, -1);
2170 
2171 #if 1
2175  VM_METHOD_TYPE_OPTIMIZED, (void *)OPTIMIZED_METHOD_TYPE_SEND, METHOD_VISI_PUBLIC);
2176 #else
2177  rb_define_method(rb_cBasicObject, "__send__", rb_f_send, -1);
2178  rb_define_method(rb_mKernel, "send", rb_f_send, -1);
2179 #endif
2180  rb_define_method(rb_mKernel, "public_send", rb_f_public_send, -1);
2181 
2182  rb_define_method(rb_cModule, "module_exec", rb_mod_module_exec, -1);
2183  rb_define_method(rb_cModule, "class_exec", rb_mod_module_exec, -1);
2184  rb_define_method(rb_cModule, "module_eval", rb_mod_module_eval, -1);
2185  rb_define_method(rb_cModule, "class_eval", rb_mod_module_eval, -1);
2186 
2187  rb_eUncaughtThrow = rb_define_class("UncaughtThrowError", rb_eArgError);
2188  rb_define_method(rb_eUncaughtThrow, "initialize", uncaught_throw_init, -1);
2189  rb_define_method(rb_eUncaughtThrow, "tag", uncaught_throw_tag, 0);
2190  rb_define_method(rb_eUncaughtThrow, "value", uncaught_throw_value, 0);
2191  rb_define_method(rb_eUncaughtThrow, "to_s", uncaught_throw_to_s, 0);
2192 
2193  id_result = rb_intern_const("result");
2194  id_tag = rb_intern_const("tag");
2195  id_value = rb_intern_const("value");
2196 }
VALUE rb_f_public_send(int argc, VALUE *argv, VALUE recv)
Definition: vm_eval.c:953
#define RBASIC_CLEAR_CLASS(obj)
Definition: internal.h:1469
#define T_SYMBOL
Definition: ruby.h:508
#define T_OBJECT
Definition: ruby.h:491
rb_control_frame_t * rb_vm_get_ruby_level_next_cfp(const rb_thread_t *th, const rb_control_frame_t *cfp)
Definition: vm.c:498
wrapper for method_missing(id)
Definition: method.h:112
#define UNDEFINED_METHOD_ENTRY_P(me)
Definition: method.h:175
ID rb_check_id(volatile VALUE *)
Returns ID for the given name if it is interned already, or 0.
Definition: symbol.c:915
#define RUBY_VM_CHECK_INTS(th)
Definition: vm_core.h:1627
const VALUE * ep
Definition: vm_core.h:667
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *pstate)
Protects a function call from potential global escapes from the function.
Definition: eval.c:992
void rb_bug(const char *fmt,...)
Definition: error.c:521
#define RARRAY_LEN(a)
Definition: ruby.h:1019
#define RUBY_EVENT_C_RETURN
Definition: ruby.h:2086
VALUE rb_eNameError
Definition: error.c:806
#define FALSE
Definition: nkf.h:174
ruby_tag_type
Definition: vm_core.h:151
VALUE(* rb_block_call_func_t)(ANYARGS)
Definition: ruby.h:1858
#define va_init_list(a, b)
Definition: win32ole.h:34
rb_iseq_t * rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE realpath, VALUE line, const struct rb_block *base_block, VALUE opt)
Definition: iseq.c:632
VALUE rb_current_realfilepath(void)
Definition: vm_eval.c:2145
#define T_FIXNUM
Definition: ruby.h:503
Definition: st.h:79
Definition: st.h:99
VALUE rb_yield_values(int n,...)
Definition: vm_eval.c:985
const rb_callable_method_entry_t * me
Definition: vm_core.h:248
#define T_MATCH
Definition: ruby.h:507
#define NUM2INT(x)
Definition: ruby.h:684
enum ruby_tag_type state
Definition: vm_core.h:701
VALUE rb_obj_instance_exec(int argc, const VALUE *argv, VALUE self)
Definition: vm_eval.c:1714
const VALUE owner
Definition: method.h:64
rb_control_frame_t * cfp
Definition: vm_core.h:744
#define id_mesg
Definition: vm_eval.c:29
#define VAR_NOCLOBBERED(var)
Definition: eval_intern.h:157
void rb_throw(const char *tag, VALUE val)
Definition: vm_eval.c:1893
#define RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp)
Definition: vm_core.h:1238
#define TAG_NONE
Definition: vm_core.h:164
#define GetProcPtr(obj, ptr)
Definition: vm_core.h:907
int rb_block_given_p(void)
Determines if the current method is given a block.
Definition: eval.c:835
VALUE rb_yield_splat(VALUE values)
Definition: vm_eval.c:1013
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:417
VALUE rb_ary_subseq(VALUE ary, long beg, long len)
Definition: array.c:1231
#define CLASS_OF(v)
Definition: ruby.h:453
VALUE rb_fstring_cstr(const char *str)
Definition: string.c:388
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2284
#define T_MODULE
Definition: ruby.h:494
VALUE rb_call_super(int argc, const VALUE *argv)
Definition: vm_eval.c:238
struct vm_ifunc * rb_vm_ifunc_new(VALUE(*func)(ANYARGS), const void *data, int min_argc, int max_argc)
Definition: proc.c:640
enum method_missing_reason method_missing_reason
Definition: vm_core.h:856
#define Qtrue
Definition: ruby.h:437
VALUE rb_vm_call(rb_thread_t *th, VALUE recv, VALUE id, int argc, const VALUE *argv, const rb_callable_method_entry_t *me)
Definition: vm_eval.c:206
struct rb_method_definition_struct *const def
Definition: method.h:62
#define CHECK_CFP_CONSISTENCY(func)
#define rb_id2str(id)
Definition: vm_backtrace.c:29
Definition: st.h:99
#define OBJ_FREEZE(x)
Definition: ruby.h:1306
const int id
Definition: nkf.c:209
const rb_callable_method_entry_t * rb_vm_frame_method_entry(const rb_control_frame_t *cfp)
#define new_args(f, o, r, p, t)
Definition: ripper.c:713
VALUE rb_mod_module_eval(int argc, const VALUE *argv, VALUE mod)
Definition: vm_eval.c:1748
void rb_define_private_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1527
Ruby method.
Definition: method.h:102
#define TH_JUMP_TAG(th, st)
Definition: eval_intern.h:204
#define T_RATIONAL
Definition: ruby.h:509
#define rb_check_arity
Definition: intern.h:298
VALUE rb_vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, int argc, const VALUE *argv, VALUE passed_block_handler)
Definition: vm.c:1172
#define UNREACHABLE
Definition: ruby.h:46
const ID * local_table
Definition: vm_core.h:391
#define VM_BLOCK_HANDLER_NONE
Definition: vm_core.h:1135
VALUE rb_check_funcall_default(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE def)
Definition: vm_eval.c:395
VALUE rb_eval_string_protect(const char *str, int *pstate)
Evaluates the given string in an isolated binding.
Definition: vm_eval.c:1463
#define SYM2ID(x)
Definition: ruby.h:384
struct rb_iseq_constant_body * body
Definition: vm_core.h:423
VALUE rb_each(VALUE obj)
Definition: vm_eval.c:1233
#define PRIxVALUE
Definition: ruby.h:133
VALUE rb_ivar_get(VALUE, ID)
Definition: variable.c:1210
VALUE rb_check_funcall(VALUE recv, ID mid, int argc, const VALUE *argv)
Definition: vm_eval.c:389
#define TH_EXEC_TAG()
Definition: eval_intern.h:198
#define RB_GC_GUARD(v)
Definition: ruby.h:552
#define T_HASH
Definition: ruby.h:499
VALUE rb_obj_alloc(VALUE)
Allocates an instance of klass.
Definition: object.c:2121
#define VM_PROFILE_UP(x)
void Init_vm_eval(void)
Definition: vm_eval.c:2155
#define SDR()
Definition: vm_core.h:1473
#define FL_TEST_RAW(x, f)
Definition: ruby.h:1281
VALUE rb_catch(const char *tag, VALUE(*func)(), VALUE data)
Definition: vm_eval.c:1970
#define RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp)
Definition: vm_core.h:1244
#define T_ARRAY
Definition: ruby.h:498
int st_update(st_table *table, st_data_t key, st_update_callback_func *func, st_data_t arg)
Definition: st.c:1393
VALUE rb_name_err_mesg_new(VALUE mesg, VALUE recv, VALUE method)
Definition: error.c:1394
void rb_define_global_function(const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a global function.
Definition: class.c:1745
unsigned int respond
Definition: vm_eval.c:304
VALUE rb_threadptr_backtrace_str_ary(rb_thread_t *th, long lev, long n)
Definition: vm_backtrace.c:653
VALUE ruby_eval_string_from_file(const char *str, const char *filename)
Definition: vm_eval.c:1407
#define T_UNDEF
Definition: ruby.h:512
VALUE rb_rescue2(VALUE(*b_proc)(ANYARGS), VALUE data1, VALUE(*r_proc)(ANYARGS), VALUE data2,...)
An equivalent of rescue clause.
Definition: eval.c:895
refinement
Definition: method.h:113
VALUE rb_catch_obj(VALUE t, VALUE(*func)(), VALUE data)
Definition: vm_eval.c:2012
#define RUBY_DTRACE_CMETHOD_ENTRY_HOOK(th, klass, id)
Definition: probes_helper.h:37
const VALUE * ep
Definition: vm_core.h:631
VALUE rb_obj_instance_eval(int argc, const VALUE *argv, VALUE self)
Definition: vm_eval.c:1689
#define GET_THREAD()
Definition: vm_core.h:1583
VALUE rb_eArgError
Definition: error.c:802
VALUE rb_hash_keys(VALUE hash)
Definition: hash.c:2131
RUBY_SYMBOL_EXPORT_BEGIN typedef unsigned long st_data_t
Definition: st.h:22
const VALUE * argv
Definition: vm_eval.c:307
VALUE rb_eNoMethodError
Definition: error.c:809
#define RHASH(obj)
Definition: internal.h:663
VALUE rb_singleton_class(VALUE obj)
Returns the singleton class of obj.
Definition: class.c:1689
VALUE rb_obj_class(VALUE)
call-seq: obj.class -> class
Definition: object.c:277
#define RB_TYPE_P(obj, type)
Definition: ruby.h:527
VALUE rb_obj_is_kind_of(VALUE, VALUE)
call-seq: obj.is_a?(class) -> true or false obj.kind_of?(class) -> true or false
Definition: object.c:842
VALUE rb_check_block_call(VALUE obj, ID mid, int argc, const VALUE *argv, VALUE(*bl_proc)(ANYARGS), VALUE data2)
Definition: vm_eval.c:1220
#define TH_POP_TAG()
Definition: eval_intern.h:138
VALUE rb_catch_protect(VALUE t, rb_block_call_func *func, VALUE data, enum ruby_tag_type *stateptr)
Definition: vm_eval.c:2006
#define UNLIKELY(x)
Definition: internal.h:43
VALUE rb_block_call_func(RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg))
Definition: ruby.h:1853
const rb_iseq_t * iseq
Definition: vm_core.h:665
unsigned short first_lineno
Definition: vm_core.h:933
#define RUBY_SAFE_LEVEL_MAX
Definition: ruby.h:599
unsigned int local_table_size
Definition: vm_core.h:410
#define val
#define PASS_PASSED_BLOCK_HANDLER_TH(th)
Definition: eval_intern.h:23
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:1893
VALUE rb_special_singleton_class(VALUE obj)
Definition: class.c:1579
#define T_NIL
Definition: ruby.h:490
RUBY_EXTERN VALUE rb_cBasicObject
Definition: ruby.h:1892
VALUE rb_funcall(VALUE recv, ID mid, int n,...)
Calls a method.
Definition: vm_eval.c:774
VALUE rb_sym_proc_call(ID mid, int argc, const VALUE *argv, VALUE passed_proc)
Definition: string.c:10206
#define T_TRUE
Definition: ruby.h:504
RUBY_EXTERN VALUE rb_mKernel
Definition: ruby.h:1881
VALUE rb_funcall_with_block(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE passed_procval)
Definition: vm_eval.c:833
#define RCLASS_ORIGIN(c)
Definition: internal.h:794
void rb_check_funcall_hook(int, VALUE, ID, int, const VALUE *, VALUE)
Definition: internal.h:1777
#define NIL_P(v)
Definition: ruby.h:451
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:646
rb_method_visibility_t
Definition: method.h:26
VALUE rb_f_eval(int argc, const VALUE *argv, VALUE self)
Definition: vm_eval.c:1385
VALUE tag
Definition: vm_core.h:697
THROW_DATA.
Definition: internal.h:895
#define BOUND_RESPONDS
Definition: vm_method.c:1065
VALUE top_self
Definition: vm_core.h:804
#define T_FLOAT
Definition: ruby.h:495
int argc
Definition: ruby.c:187
#define Qfalse
Definition: ruby.h:436
const rb_data_type_t ruby_binding_data_type
Definition: proc.c:289
#define undefined
Definition: vm_method.c:36
#define ALLOCV_N(type, v, n)
Definition: ruby.h:1657
#define ALLOCA_N(type, n)
Definition: ruby.h:1593
const VALUE defined_class
Definition: method.h:61
#define RUBY_DTRACE_CMETHOD_RETURN_HOOK(th, klass, id)
Definition: probes_helper.h:40
Definition: method.h:51
union rb_captured_block::@141 code
RUBY_EXTERN VALUE rb_cModule
Definition: ruby.h:1916
#define T_BIGNUM
Definition: ruby.h:501
Definition: method.h:59
#define MEMCPY(p1, p2, type, n)
Definition: ruby.h:1661
#define T_NODE
Definition: ruby.h:513
#define rb_ary_new4
Definition: intern.h:92
#define rb_str_new2
Definition: intern.h:835
int err
Definition: win32.c:135
#define RUBY_EVENT_C_CALL
Definition: ruby.h:2085
#define T_COMPLEX
Definition: ruby.h:510
void rb_throw_obj(VALUE tag, VALUE value)
Definition: vm_eval.c:1868
#define ALLOCV_END(v)
Definition: ruby.h:1658
const VALUE * argv
Definition: vm_eval.c:1168
const rb_callable_method_entry_t * rb_resolve_refined_method_callable(VALUE refinements, const rb_callable_method_entry_t *me)
Definition: vm_method.c:946
VALUE rb_funcallv(VALUE recv, ID mid, int argc, const VALUE *argv)
Calls a method.
Definition: vm_eval.c:805
#define VM_ENV_DATA_INDEX_SPECVAL
Definition: vm_core.h:1050
#define numberof(array)
Definition: etc.c:618
rb_method_type_t
Definition: method.h:101
rb_thread_t * th
Definition: vm_eval.c:299
void rb_threadptr_stack_overflow(rb_thread_t *th, int crit)
Definition: vm_insnhelper.c:57
VALUE rb_lambda_call(VALUE obj, ID mid, int argc, const VALUE *argv, rb_block_call_func_t bl_proc, int min_argc, int max_argc, VALUE data2)
Definition: vm_eval.c:1194
attr_writer or attr_accessor
Definition: method.h:104
void rb_vm_pop_frame(rb_thread_t *th)
#define RSTRING_LEN(str)
Definition: ruby.h:971
const VALUE pathobj
Definition: vm_core.h:932
#define RARRAY_CONST_PTR(a)
Definition: ruby.h:1021
VALUE tbl
Definition: vm_eval.c:15
VALUE(* invoker)(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
Definition: method.h:130
union rb_block::@142 as
#define TRUE
Definition: nkf.h:175
#define T_DATA
Definition: ruby.h:506
VALUE rb_str_format(int, const VALUE *, VALUE)
Definition: sprintf.c:464
const rb_callable_method_entry_t * rb_callable_method_entry(VALUE klass, ID id)
Definition: vm_method.c:833
NORETURN(static void raise_method_missing(rb_thread_t *th, int argc, const VALUE *argv, VALUE obj, enum method_missing_reason call_status))
void rb_raise_method_missing(rb_thread_t *th, int argc, const VALUE *argv, VALUE obj, int call_status)
Definition: vm_eval.c:728
VALUE(* func)(ANYARGS)
Definition: method.h:129
VALUE rb_eval_string(const char *str)
Evaluates the given string in an isolated binding.
Definition: vm_eval.c:1447
VALUE rb_hash_new(void)
Definition: hash.c:424
VALUE rb_iterate(VALUE(*it_proc)(VALUE), VALUE data1, VALUE(*bl_proc)(ANYARGS), VALUE data2)
Definition: vm_eval.c:1156
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1908
#define rb_thread_raised_set(th, f)
Definition: eval_intern.h:285
VALUE rb_ivar_set(VALUE, ID, VALUE)
Definition: variable.c:1315
VALUE rb_f_send(int argc, VALUE *argv, VALUE recv)
Definition: vm_eval.c:933
void rb_vm_pop_cfunc_frame(void)
Definition: vm.c:532
#define T_IMEMO
Definition: ruby.h:511
#define PRIsVALUE
Definition: ruby.h:135
unsigned long ID
Definition: ruby.h:86
#define T_STRUCT
Definition: ruby.h:500
#define Qnil
Definition: ruby.h:438
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
Definition: eval.c:615
VALUE rb_eStopIteration
Definition: enumerator.c:109
IFUNC (Internal FUNCtion)
Definition: internal.h:917
#define METHOD_ENTRY_VISI(me)
Definition: method.h:67
#define BUILTIN_TYPE(x)
Definition: ruby.h:518
unsigned long VALUE
Definition: ruby.h:85
VALUE rb_vm_top_self(void)
Definition: vm.c:3166
#define OBJ_TAINTED(x)
Definition: ruby.h:1296
method_missing_reason
Definition: vm_core.h:205
#define EXEC_EVENT_HOOK(th_, flag_, self_, id_, called_id_, klass_, data_)
Definition: vm_core.h:1686
VALUE rb_hash_clear(VALUE hash)
Definition: hash.c:1519
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn)
Definition: intern.h:234
#define RBASIC(obj)
Definition: ruby.h:1197
VALUE rb_eNotImpError
Definition: error.c:811
#define TH_PUSH_TAG(th)
Definition: eval_intern.h:131
#define INFINITY
Definition: missing.h:149
const struct vm_ifunc * ifunc
Definition: vm_core.h:634
CREF (Class REFerence)
Definition: method.h:41
VALUE rb_str_new_cstr(const char *)
Definition: string.c:771
VALUE rb_proc_lambda_p(VALUE)
Definition: proc.c:254
#define RARRAY_LENINT(ary)
Definition: ruby.h:1020
const rb_method_entry_t * me
Definition: vm_eval.c:303
call_type
Definition: vm_eval.c:31
ruby_value_type
Definition: ruby.h:455
Kernel::send, Proc::call, etc.
Definition: method.h:111
VALUE rb_sym_intern_ascii_cstr(const char *ptr)
Definition: symbol.c:1042
struct rb_captured_block captured
Definition: vm_core.h:655
VALUE rb_yield_refine_block(VALUE refinement, VALUE refinements)
Definition: vm_eval.c:1584
register unsigned int len
Definition: zonetab.h:51
void rb_set_safe_level_force(int)
Definition: safe.c:41
VALUE rb_mod_module_exec(int argc, const VALUE *argv, VALUE mod)
Definition: vm_eval.c:1776
VALUE rb_iseq_realpath(const rb_iseq_t *iseq)
Definition: iseq.c:698
#define RARRAY_ASET(a, i, v)
Definition: ruby.h:1034
VALUE rb_iseq_disasm(const rb_iseq_t *iseq)
Definition: iseq.c:1515
#define TAG_RETRY
Definition: vm_core.h:168
VALUE rb_get_backtrace(VALUE exc)
Definition: error.c:1004
#define INT2FIX(i)
Definition: ruby.h:232
VALUE top_wrapper
Definition: vm_core.h:805
#define UNLIMITED_ARGUMENTS
Definition: intern.h:44
#define TAG_THROW
Definition: vm_core.h:171
#define RCLASS_SUPER(c)
Definition: classext.h:16
int rb_safe_level(void)
Definition: safe.c:35
VALUE rb_module_new(void)
Definition: class.c:749
#define RARRAY_AREF(a, i)
Definition: ruby.h:1033
#define METHOD_ENTRY_BASIC(me)
Definition: method.h:68
VALUE rb_eval_string_wrap(const char *str, int *pstate)
Evaluates the given string under a module binding in an isolated binding.
Definition: vm_eval.c:1480
#define st_init_numtable
Definition: regint.h:178
unsigned int respond_to_missing
Definition: vm_eval.c:305
#define ANYARGS
Definition: defines.h:173
VALUE rb_eRuntimeError
Definition: error.c:800
VALUE rb_check_array_type(VALUE ary)
Definition: array.c:651
VALUE block_handler
Definition: vm_core.h:234
struct rb_vm_tag * tag
Definition: vm_core.h:746
void rb_extend_object(VALUE obj, VALUE module)
Extend the object with the module.
Definition: eval.c:1596
#define RHASH_TBL_RAW(h)
Definition: internal.h:1268
VALUE ruby_eval_string_from_file_protect(const char *str, const char *filename, int *state)
Definition: vm_eval.c:1426
#define RTEST(v)
Definition: ruby.h:450
#define T_STRING
Definition: ruby.h:496
rb_method_entry_t * rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *option, rb_method_visibility_t visi)
Definition: vm_method.c:625
VALUE rb_class_new_instance(int, const VALUE *, VALUE)
Allocates and initializes an instance of klass.
Definition: object.c:2170
int rb_method_basic_definition_p(VALUE, ID)
Definition: vm_method.c:1879
#define T_FALSE
Definition: ruby.h:505
#define T_FILE
Definition: ruby.h:502
VALUE rb_apply(VALUE recv, ID mid, VALUE args)
Calls a method.
Definition: vm_eval.c:744
VALUE rb_yield_values2(int argc, const VALUE *argv)
Definition: vm_eval.c:1007
VALUE rb_funcall_passing_block(VALUE recv, ID mid, int argc, const VALUE *argv)
Definition: vm_eval.c:826
int rb_is_local_id(ID id)
Definition: symbol.c:850
#define rb_thread_raised_p(th, f)
Definition: eval_intern.h:287
const rb_iseq_t * iseq
Definition: vm_core.h:633
#define SafeStringValue(v)
Definition: ruby.h:574
VALUE rb_funcallv_public(VALUE recv, ID mid, int argc, const VALUE *argv)
Calls a method.
Definition: vm_eval.c:820
VALUE rb_f_block_given_p(void)
Definition: vm_eval.c:2130
#define T_CLASS
Definition: ruby.h:492
rb_execution_context_t ec
Definition: vm_core.h:790
#define ID2SYM(x)
Definition: ruby.h:383
VALUE rb_yield(VALUE val)
Definition: vm_eval.c:973
#define StringValuePtr(v)
Definition: ruby.h:570
enum rb_block_type type
Definition: vm_core.h:659
VALUE rb_source_location(int *pline)
Definition: vm.c:1297
struct rb_vm_tag * prev
Definition: vm_core.h:700
void rb_vm_rewind_cfp(rb_thread_t *th, rb_control_frame_t *cfp)
Definition: vm.c:544
VALUE retval
Definition: vm_core.h:698
C method.
Definition: method.h:103
VALUE rb_str_intern(VALUE)
Definition: symbol.c:661
#define rb_intern_const(str)
Definition: ruby.h:1777
#define TAG_BREAK
Definition: vm_core.h:166
#define SPECIAL_CONST_P(x)
Definition: ruby.h:1242
int rb_threadptr_stack_check(rb_thread_t *th)
Definition: gc.c:4047
#define CHECK_VM_STACK_OVERFLOW(cfp, margin)
Definition: vm_core.h:1565
#define rb_intern(str)
int rb_method_boundp(VALUE, ID, int)
Definition: vm_method.c:1068
#define T_ZOMBIE
Definition: ruby.h:514
#define SYMBOL_P(x)
Definition: ruby.h:382
#define mod(x, y)
Definition: date_strftime.c:28
#define T_NONE
Definition: ruby.h:489
#define TAG_RAISE
Definition: vm_core.h:170
VALUE rb_yield_1(VALUE val)
Definition: vm_eval.c:967
VALUE rb_eval_cmd(VALUE cmd, VALUE arg, int level)
Definition: vm_eval.c:1507
#define NULL
Definition: _sdbm.c:102
#define BOUND_PRIVATE
Definition: vm_method.c:1064
#define Qundef
Definition: ruby.h:439
#define T_ICLASS
Definition: ruby.h:493
const struct rb_block block
Definition: vm_core.h:931
attr_reader or attr_accessor
Definition: method.h:105
VALUE rb_block_call(VALUE obj, ID mid, int argc, const VALUE *argv, VALUE(*bl_proc)(ANYARGS), VALUE data2)
Definition: vm_eval.c:1181
VALUE rb_obj_clone(VALUE)
:nodoc Almost same as Object::clone ++
Definition: object.c:475
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1515
VALUE rb_yield_block(VALUE val, VALUE arg, int argc, const VALUE *argv, VALUE blockarg)
Definition: vm_eval.c:1032
#define Check_TypedStruct(v, t)
Definition: ruby.h:1131
#define T_REGEXP
Definition: ruby.h:497
VALUE rb_attr_get(VALUE, ID)
Definition: variable.c:1224
VALUE rb_usascii_str_new_cstr(const char *)
Definition: string.c:778
#define type_case(t)
char ** argv
Definition: ruby.c:188
#define DBL2NUM(dbl)
Definition: ruby.h:934
VALUE rb_yield_force_blockarg(VALUE values)
Definition: vm_eval.c:1026
#define StringValue(v)
Definition: ruby.h:569
#define PASS_PASSED_BLOCK_HANDLER()
Definition: eval_intern.h:24
VALUE rb_current_receiver(void)
Definition: vm_eval.c:246