Ruby  1.9.3p392(2013-02-22revision39386)
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 rb_vm_set_finish_env(rb_thread_t * th);
16 static inline VALUE vm_yield_with_cref(rb_thread_t *th, int argc, const VALUE *argv, const NODE *cref);
17 static inline VALUE vm_yield(rb_thread_t *th, int argc, const VALUE *argv);
18 static inline VALUE vm_backtrace(rb_thread_t *th, int lev);
19 static int vm_backtrace_each(rb_thread_t *th, int lev, void (*init)(void *), rb_backtrace_iter_func *iter, void *arg);
20 static NODE *vm_cref_push(rb_thread_t *th, VALUE klass, int noex, rb_block_t *blockptr);
21 static VALUE vm_exec(rb_thread_t *th);
22 static void vm_set_eval_stack(rb_thread_t * th, VALUE iseqval, const NODE *cref);
24 
25 typedef enum call_type {
30 } call_type;
31 
32 static VALUE send_internal(int argc, const VALUE *argv, VALUE recv, call_type scope);
33 
34 static inline VALUE
35 vm_call0(rb_thread_t* th, VALUE recv, VALUE id, int argc, const VALUE *argv,
36  const rb_method_entry_t *me)
37 {
38  const rb_method_definition_t *def = me->def;
39  VALUE val;
40  VALUE klass = me->klass;
41  const rb_block_t *blockptr = 0;
42 
43  if (!def) return Qnil;
44  if (th->passed_block) {
45  blockptr = th->passed_block;
46  th->passed_block = 0;
47  }
48 
49  again:
50  switch (def->type) {
51  case VM_METHOD_TYPE_ISEQ: {
52  rb_control_frame_t *reg_cfp;
53  int i;
54 
56  reg_cfp = th->cfp;
57 
58  CHECK_STACK_OVERFLOW(reg_cfp, argc + 1);
59 
60  *reg_cfp->sp++ = recv;
61  for (i = 0; i < argc; i++) {
62  *reg_cfp->sp++ = argv[i];
63  }
64 
65  vm_setup_method(th, reg_cfp, recv, argc, blockptr, 0 /* flag */, me);
66  val = vm_exec(th);
67  break;
68  }
70  case VM_METHOD_TYPE_CFUNC: {
71  EXEC_EVENT_HOOK(th, RUBY_EVENT_C_CALL, recv, id, klass);
72  {
73  rb_control_frame_t *reg_cfp = th->cfp;
74  rb_control_frame_t *cfp =
76  recv, (VALUE)blockptr, 0, reg_cfp->sp, 0, 1);
77 
78  cfp->me = me;
79  val = call_cfunc(def->body.cfunc.func, recv, def->body.cfunc.argc, argc, argv);
80 
81  if (reg_cfp != th->cfp + 1) {
82  rb_bug("cfp consistency error - call0");
83  }
84  vm_pop_frame(th);
85  }
86  EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, recv, id, klass);
87  break;
88  }
90  if (argc != 1) {
91  rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc);
92  }
93  val = rb_ivar_set(recv, def->body.attr.id, argv[0]);
94  break;
95  }
96  case VM_METHOD_TYPE_IVAR: {
97  if (argc != 0) {
98  rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", argc);
99  }
100  val = rb_attr_get(recv, def->body.attr.id);
101  break;
102  }
103  case VM_METHOD_TYPE_BMETHOD: {
104  val = vm_call_bmethod(th, recv, argc, argv, blockptr, me);
105  break;
106  }
107  case VM_METHOD_TYPE_ZSUPER: {
108  klass = RCLASS_SUPER(klass);
109  if (!klass || !(me = rb_method_entry(klass, id))) {
110  return method_missing(recv, id, argc, argv, NOEX_SUPER);
111  }
113  if (!(def = me->def)) return Qnil;
114  goto again;
115  }
116  case VM_METHOD_TYPE_MISSING: {
117  VALUE new_args = rb_ary_new4(argc, argv);
118 
119  RB_GC_GUARD(new_args);
120  rb_ary_unshift(new_args, ID2SYM(id));
121  th->passed_block = blockptr;
122  return rb_funcall2(recv, idMethodMissing,
123  argc+1, RARRAY_PTR(new_args));
124  }
126  switch (def->body.optimize_type) {
127  case OPTIMIZED_METHOD_TYPE_SEND:
128  val = send_internal(argc, argv, recv, CALL_FCALL);
129  break;
130  case OPTIMIZED_METHOD_TYPE_CALL: {
131  rb_proc_t *proc;
132  GetProcPtr(recv, proc);
133  val = rb_vm_invoke_proc(th, proc, proc->block.self, argc, argv, blockptr);
134  break;
135  }
136  default:
137  rb_bug("vm_call0: unsupported optimized method type (%d)", def->body.optimize_type);
138  val = Qundef;
139  break;
140  }
141  break;
142  }
143  default:
144  rb_bug("vm_call0: unsupported method type (%d)", def->type);
145  val = Qundef;
146  }
148  return val;
149 }
150 
151 VALUE
152 rb_vm_call(rb_thread_t *th, VALUE recv, VALUE id, int argc, const VALUE *argv,
153  const rb_method_entry_t *me)
154 {
155  return vm_call0(th, recv, id, argc, argv, me);
156 }
157 
158 static inline VALUE
160 {
161  VALUE recv = th->cfp->self;
162  VALUE klass;
163  ID id;
164  rb_method_entry_t *me;
165  rb_control_frame_t *cfp = th->cfp;
166 
167  if (!cfp->iseq) {
168  klass = cfp->me->klass;
169  klass = RCLASS_SUPER(klass);
170 
171  if (klass == 0) {
172  klass = vm_search_normal_superclass(cfp->me->klass, recv);
173  }
174  id = cfp->me->def->original_id;
175  }
176  else {
177  rb_bug("vm_call_super: should not be reached");
178  }
179 
180  me = rb_method_entry(klass, id);
181  if (!me) {
182  return method_missing(recv, id, argc, argv, NOEX_SUPER);
183  }
184 
185  return vm_call0(th, recv, id, argc, argv, me);
186 }
187 
188 VALUE
190 {
192  return vm_call_super(GET_THREAD(), argc, argv);
193 }
194 
195 static inline void
197 {
198  rb_thread_t *th = GET_THREAD();
199 
203  }
204 }
205 
206 static inline rb_method_entry_t *rb_search_method_entry(VALUE recv, ID mid);
207 static inline int rb_method_call_status(rb_thread_t *th, const rb_method_entry_t *me, call_type scope, VALUE self);
208 #define NOEX_OK NOEX_NOSUPER
209 
224 static inline VALUE
225 rb_call0(VALUE recv, ID mid, int argc, const VALUE *argv,
226  call_type scope, VALUE self)
227 {
228  rb_method_entry_t *me = rb_search_method_entry(recv, mid);
229  rb_thread_t *th = GET_THREAD();
230  int call_status = rb_method_call_status(th, me, scope, self);
231 
232  if (call_status != NOEX_OK) {
233  return method_missing(recv, mid, argc, argv, call_status);
234  }
235  stack_check();
236  return vm_call0(th, recv, mid, argc, argv, me);
237 }
238 
242  int argc;
244 };
245 
246 static VALUE
248 {
249  VALUE new_args = rb_ary_new4(args->argc, args->argv);
250 
251  RB_GC_GUARD(new_args);
252  rb_ary_unshift(new_args, args->sym);
253  return rb_funcall2(args->recv, idMethodMissing,
254  args->argc+1, RARRAY_PTR(new_args));
255 }
256 
257 static VALUE
259 {
260  if (rb_respond_to(args->recv, SYM2ID(args->sym))) {
261  rb_exc_raise(e);
262  }
263  return Qundef;
264 }
265 
266 static VALUE
267 check_funcall(VALUE recv, ID mid, int argc, VALUE *argv)
268 {
269  VALUE klass = CLASS_OF(recv);
270  const rb_method_entry_t *me;
271  rb_thread_t *th = GET_THREAD();
272  int call_status;
273 
274  me = rb_method_entry(klass, idRespond_to);
275  if (me && !(me->flag & NOEX_BASIC)) {
276  VALUE args[2];
277  int arity = rb_method_entry_arity(me);
278 
279  if (arity < 1 || arity > 3) arity = 2;
280 
281  args[0] = ID2SYM(mid);
282  args[1] = Qtrue;
283  if (!RTEST(vm_call0(th, recv, idRespond_to, arity, args, me))) {
284  return Qundef;
285  }
286  }
287 
288  me = rb_search_method_entry(recv, mid);
289  call_status = rb_method_call_status(th, me, CALL_FCALL, Qundef);
290  if (call_status != NOEX_OK) {
291  if (rb_method_basic_definition_p(klass, idMethodMissing)) {
292  return Qundef;
293  }
294  else {
295  struct rescue_funcall_args args;
296 
297  th->method_missing_reason = 0;
298  args.recv = recv;
299  args.sym = ID2SYM(mid);
300  args.argc = argc;
301  args.argv = argv;
302  return rb_rescue2(check_funcall_exec, (VALUE)&args,
303  check_funcall_failed, (VALUE)&args,
305  }
306  }
307  stack_check();
308  return vm_call0(th, recv, mid, argc, argv, me);
309 }
310 
311 VALUE
313 {
314  return check_funcall(recv, mid, argc, argv);
315 }
316 
317 static const char *
319 {
320 #define type_case(t) case t: return #t;
321  switch (type) {
347  default: return NULL;
348  }
349 #undef type_case
350 }
351 
352 static inline rb_method_entry_t *
354 {
355  VALUE klass = CLASS_OF(recv);
356 
357  if (!klass) {
358  VALUE flags, klass;
359  if (IMMEDIATE_P(recv)) {
361  "method `%s' called on unexpected immediate object (%p)",
362  rb_id2name(mid), (void *)recv);
363  }
364  flags = RBASIC(recv)->flags;
365  klass = RBASIC(recv)->klass;
366  if (flags == 0) {
368  "method `%s' called on terminated object"
369  " (%p flags=0x%"PRIxVALUE" klass=0x%"PRIxVALUE")",
370  rb_id2name(mid), (void *)recv, flags, klass);
371  }
372  else {
373  int type = BUILTIN_TYPE(recv);
374  const char *typestr = rb_type_str(type);
375  if (typestr && T_OBJECT <= type && type < T_NIL)
377  "method `%s' called on hidden %s object"
378  " (%p flags=0x%"PRIxVALUE" klass=0x%"PRIxVALUE")",
379  rb_id2name(mid), typestr, (void *)recv, flags, klass);
380  if (typestr)
382  "method `%s' called on unexpected %s object"
383  " (%p flags=0x%"PRIxVALUE" klass=0x%"PRIxVALUE")",
384  rb_id2name(mid), typestr, (void *)recv, flags, klass);
385  else
387  "method `%s' called on broken T_???" "(0x%02x) object"
388  " (%p flags=0x%"PRIxVALUE" klass=0x%"PRIxVALUE")",
389  rb_id2name(mid), type, (void *)recv, flags, klass);
390  }
391  }
392  return rb_method_entry(klass, mid);
393 }
394 
395 static inline int
397 {
398  VALUE klass;
399  ID oid;
400  int noex;
401 
402  if (UNDEFINED_METHOD_ENTRY_P(me)) {
403  return scope == CALL_VCALL ? NOEX_VCALL : 0;
404  }
405  klass = me->klass;
406  oid = me->def->original_id;
407  noex = me->flag;
408 
409  if (oid != idMethodMissing) {
410  /* receiver specified form for private method */
411  if (UNLIKELY(noex)) {
412  if (((noex & NOEX_MASK) & NOEX_PRIVATE) && scope == CALL_PUBLIC) {
413  return NOEX_PRIVATE;
414  }
415 
416  /* self must be kind of a specified form for protected method */
417  if (((noex & NOEX_MASK) & NOEX_PROTECTED) && scope == CALL_PUBLIC) {
418  VALUE defined_class = klass;
419 
420  if (TYPE(defined_class) == T_ICLASS) {
421  defined_class = RBASIC(defined_class)->klass;
422  }
423 
424  if (self == Qundef) {
425  self = th->cfp->self;
426  }
427  if (!rb_obj_is_kind_of(self, defined_class)) {
428  return NOEX_PROTECTED;
429  }
430  }
431 
432  if (NOEX_SAFE(noex) > th->safe_level) {
433  rb_raise(rb_eSecurityError, "calling insecure method: %s",
434  rb_id2name(me->called_id));
435  }
436  }
437  }
438  return NOEX_OK;
439 }
440 
441 
453 static inline VALUE
454 rb_call(VALUE recv, ID mid, int argc, const VALUE *argv, call_type scope)
455 {
456  return rb_call0(recv, mid, argc, argv, scope, Qundef);
457 }
458 
459 NORETURN(static void raise_method_missing(rb_thread_t *th, int argc, const VALUE *argv,
460  VALUE obj, int call_status));
461 
462 /*
463  * call-seq:
464  * obj.method_missing(symbol [, *args] ) -> result
465  *
466  * Invoked by Ruby when <i>obj</i> is sent a message it cannot handle.
467  * <i>symbol</i> is the symbol for the method called, and <i>args</i>
468  * are any arguments that were passed to it. By default, the interpreter
469  * raises an error when this method is called. However, it is possible
470  * to override the method to provide more dynamic behavior.
471  * If it is decided that a particular method should not be handled, then
472  * <i>super</i> should be called, so that ancestors can pick up the
473  * missing method.
474  * The example below creates
475  * a class <code>Roman</code>, which responds to methods with names
476  * consisting of roman numerals, returning the corresponding integer
477  * values.
478  *
479  * class Roman
480  * def roman_to_int(str)
481  * # ...
482  * end
483  * def method_missing(methId)
484  * str = methId.id2name
485  * roman_to_int(str)
486  * end
487  * end
488  *
489  * r = Roman.new
490  * r.iv #=> 4
491  * r.xxiii #=> 23
492  * r.mm #=> 2000
493  */
494 
495 static VALUE
497 {
498  rb_thread_t *th = GET_THREAD();
499  raise_method_missing(th, argc, argv, obj, th->method_missing_reason);
500  return Qnil; /* not reached */
501 }
502 
503 #define NOEX_MISSING 0x80
504 
505 static void
507  int last_call_status)
508 {
509  ID id;
510  VALUE exc = rb_eNoMethodError;
511  const char *format = 0;
512 
513  if (argc == 0 || !SYMBOL_P(argv[0])) {
514  rb_raise(rb_eArgError, "no id given");
515  }
516 
517  stack_check();
518 
519  id = SYM2ID(argv[0]);
520 
521  if (last_call_status & NOEX_PRIVATE) {
522  format = "private method `%s' called for %s";
523  }
524  else if (last_call_status & NOEX_PROTECTED) {
525  format = "protected method `%s' called for %s";
526  }
527  else if (last_call_status & NOEX_VCALL) {
528  format = "undefined local variable or method `%s' for %s";
529  exc = rb_eNameError;
530  }
531  else if (last_call_status & NOEX_SUPER) {
532  format = "super: no superclass method `%s' for %s";
533  }
534  if (!format) {
535  format = "undefined method `%s' for %s";
536  }
537 
538  {
539  int n = 0;
540  VALUE mesg;
541  VALUE args[3];
542 
543  mesg = rb_const_get(exc, rb_intern("message"));
544  if (rb_method_basic_definition_p(CLASS_OF(mesg), '!')) {
545  args[n++] = rb_name_err_mesg_new(mesg, rb_str_new2(format), obj, argv[0]);
546  }
547  else {
548  args[n++] = rb_funcall(mesg, '!', 3, rb_str_new2(format), obj, argv[0]);
549  }
550  args[n++] = argv[0];
551  if (exc == rb_eNoMethodError) {
552  args[n++] = rb_ary_new4(argc - 1, argv + 1);
553  }
554  exc = rb_class_new_instance(n, args, exc);
555 
556  if (!(last_call_status & NOEX_MISSING)) {
558  }
559  rb_exc_raise(exc);
560  }
561 }
562 
563 static inline VALUE
564 method_missing(VALUE obj, ID id, int argc, const VALUE *argv, int call_status)
565 {
566  VALUE *nargv, result, argv_ary = 0;
567  rb_thread_t *th = GET_THREAD();
568  const rb_block_t *blockptr = th->passed_block;
569 
570  th->method_missing_reason = call_status;
571  th->passed_block = 0;
572 
573  if (id == idMethodMissing) {
574  raise_method_missing(th, argc, argv, obj, call_status | NOEX_MISSING);
575  }
576  else if (id == ID_ALLOCATOR) {
577  rb_raise(rb_eTypeError, "allocator undefined for %s",
578  rb_class2name(obj));
579  }
580 
581  if (argc < 0x100) {
582  nargv = ALLOCA_N(VALUE, argc + 1);
583  }
584  else {
585  argv_ary = rb_ary_tmp_new(argc + 1);
586  nargv = RARRAY_PTR(argv_ary);
587  }
588  nargv[0] = ID2SYM(id);
589  MEMCPY(nargv + 1, argv, VALUE, argc);
590 
591  if (rb_method_basic_definition_p(CLASS_OF(obj) , idMethodMissing)) {
592  raise_method_missing(th, argc+1, nargv, obj, call_status | NOEX_MISSING);
593  }
594  th->passed_block = blockptr;
595  result = rb_funcall2(obj, idMethodMissing, argc + 1, nargv);
596  if (argv_ary) rb_ary_clear(argv_ary);
597  return result;
598 }
599 
600 void
602  VALUE obj, int call_status)
603 {
604  th->passed_block = 0;
605  raise_method_missing(th, argc, argv, obj, call_status | NOEX_MISSING);
606 }
607 
616 VALUE
618 {
619  int argc;
620  VALUE *argv;
621 
622  argc = RARRAY_LENINT(args);
623  argv = ALLOCA_N(VALUE, argc);
624  MEMCPY(argv, RARRAY_PTR(args), VALUE, argc);
625  return rb_call(recv, mid, argc, argv, CALL_FCALL);
626 }
627 
637 VALUE
638 rb_funcall(VALUE recv, ID mid, int n, ...)
639 {
640  VALUE *argv;
641  va_list ar;
642 
643  if (n > 0) {
644  long i;
645 
646  va_init_list(ar, n);
647 
648  argv = ALLOCA_N(VALUE, n);
649 
650  for (i = 0; i < n; i++) {
651  argv[i] = va_arg(ar, VALUE);
652  }
653  va_end(ar);
654  }
655  else {
656  argv = 0;
657  }
658  return rb_call(recv, mid, n, argv, CALL_FCALL);
659 }
660 
668 VALUE
669 rb_funcall2(VALUE recv, ID mid, int argc, const VALUE *argv)
670 {
671  return rb_call(recv, mid, argc, argv, CALL_FCALL);
672 }
673 
683 VALUE
684 rb_funcall3(VALUE recv, ID mid, int argc, const VALUE *argv)
685 {
686  return rb_call(recv, mid, argc, argv, CALL_PUBLIC);
687 }
688 
689 VALUE
691 {
693 
694  return rb_call(recv, mid, argc, argv, CALL_PUBLIC);
695 }
696 
697 static VALUE
699 {
700  VALUE vid;
701  VALUE self = RUBY_VM_PREVIOUS_CONTROL_FRAME(GET_THREAD()->cfp)->self;
702  rb_thread_t *th = GET_THREAD();
703 
704  if (argc == 0) {
705  rb_raise(rb_eArgError, "no method name given");
706  }
707 
708  vid = *argv++; argc--;
710 
711  return rb_call0(recv, rb_to_id(vid), argc, argv, scope, self);
712 }
713 
714 /*
715  * call-seq:
716  * obj.send(symbol [, args...]) -> obj
717  * obj.__send__(symbol [, args...]) -> obj
718  *
719  * Invokes the method identified by _symbol_, passing it any
720  * arguments specified. You can use <code>__send__</code> if the name
721  * +send+ clashes with an existing method in _obj_.
722  *
723  * class Klass
724  * def hello(*args)
725  * "Hello " + args.join(' ')
726  * end
727  * end
728  * k = Klass.new
729  * k.send :hello, "gentle", "readers" #=> "Hello gentle readers"
730  */
731 
732 VALUE
734 {
735  return send_internal(argc, argv, recv, CALL_FCALL);
736 }
737 
738 /*
739  * call-seq:
740  * obj.public_send(symbol [, args...]) -> obj
741  *
742  * Invokes the method identified by _symbol_, passing it any
743  * arguments specified. Unlike send, public_send calls public
744  * methods only.
745  *
746  * 1.public_send(:puts, "hello") # causes NoMethodError
747  */
748 
749 VALUE
751 {
752  return send_internal(argc, argv, recv, CALL_PUBLIC);
753 }
754 
755 /* yield */
756 
757 static inline VALUE
758 rb_yield_0(int argc, const VALUE * argv)
759 {
760  return vm_yield(GET_THREAD(), argc, argv);
761 }
762 
763 VALUE
765 {
766  if (val == Qundef) {
767  return rb_yield_0(0, 0);
768  }
769  else {
770  return rb_yield_0(1, &val);
771  }
772 }
773 
774 VALUE
775 rb_yield_values(int n, ...)
776 {
777  if (n == 0) {
778  return rb_yield_0(0, 0);
779  }
780  else {
781  int i;
782  VALUE *argv;
783  va_list args;
784  argv = ALLOCA_N(VALUE, n);
785 
786  va_init_list(args, n);
787  for (i=0; i<n; i++) {
788  argv[i] = va_arg(args, VALUE);
789  }
790  va_end(args);
791 
792  return rb_yield_0(n, argv);
793  }
794 }
795 
796 VALUE
798 {
799  return rb_yield_0(argc, argv);
800 }
801 
802 VALUE
804 {
805  VALUE tmp = rb_check_array_type(values);
806  volatile VALUE v;
807  if (NIL_P(tmp)) {
808  rb_raise(rb_eArgError, "not an array");
809  }
810  v = rb_yield_0(RARRAY_LENINT(tmp), RARRAY_PTR(tmp));
811  return v;
812 }
813 
814 static VALUE
815 loop_i(void)
816 {
817  for (;;) {
818  rb_yield_0(0, 0);
819  }
820  return Qnil;
821 }
822 
823 /*
824  * call-seq:
825  * loop { block }
826  * loop -> an_enumerator
827  *
828  * Repeatedly executes the block.
829  *
830  * If no block is given, an enumerator is returned instead.
831  *
832  * loop do
833  * print "Input: "
834  * line = gets
835  * break if !line or line =~ /^qQ/
836  * # ...
837  * end
838  *
839  * StopIteration raised in the block breaks the loop.
840  */
841 
842 static VALUE
844 {
845  RETURN_ENUMERATOR(self, 0, 0);
847  return Qnil; /* dummy */
848 }
849 
850 #if VMDEBUG
851 static const char *
852 vm_frametype_name(const rb_control_frame_t *cfp);
853 #endif
854 
855 VALUE
856 rb_iterate(VALUE (* it_proc) (VALUE), VALUE data1,
857  VALUE (* bl_proc) (ANYARGS), VALUE data2)
858 {
859  int state;
860  volatile VALUE retval = Qnil;
861  NODE *node = NEW_IFUNC(bl_proc, data2);
862  rb_thread_t *th = GET_THREAD();
863  rb_control_frame_t *volatile cfp = th->cfp;
864 
865  node->nd_aid = rb_frame_this_func();
866  TH_PUSH_TAG(th);
867  state = TH_EXEC_TAG();
868  if (state == 0) {
869  iter_retry:
870  {
871  rb_block_t *blockptr;
872  if (bl_proc) {
873  blockptr = RUBY_VM_GET_BLOCK_PTR_IN_CFP(th->cfp);
874  blockptr->iseq = (void *)node;
875  blockptr->proc = 0;
876  }
877  else {
878  blockptr = GC_GUARDED_PTR_REF(th->cfp->lfp[0]);
879  }
880  th->passed_block = blockptr;
881  }
882  retval = (*it_proc) (data1);
883  }
884  else {
885  VALUE err = th->errinfo;
886  if (state == TAG_BREAK) {
887  VALUE *escape_dfp = GET_THROWOBJ_CATCH_POINT(err);
888  VALUE *cdfp = cfp->dfp;
889 
890  if (cdfp == escape_dfp) {
891  state = 0;
892  th->state = 0;
893  th->errinfo = Qnil;
894 
895  /* check skipped frame */
896  while (th->cfp != cfp) {
897 #if VMDEBUG
898  printf("skipped frame: %s\n", vm_frametype_name(th->cfp));
899 #endif
901  const rb_method_entry_t *me = th->cfp->me;
903  }
904 
906  }
907  }
908  else{
909  /* SDR(); printf("%p, %p\n", cdfp, escape_dfp); */
910  }
911  }
912  else if (state == TAG_RETRY) {
913  VALUE *escape_dfp = GET_THROWOBJ_CATCH_POINT(err);
914  VALUE *cdfp = cfp->dfp;
915 
916  if (cdfp == escape_dfp) {
917  state = 0;
918  th->state = 0;
919  th->errinfo = Qnil;
920  th->cfp = cfp;
921  goto iter_retry;
922  }
923  }
924  }
925  TH_POP_TAG();
926 
927  switch (state) {
928  case 0:
929  break;
930  default:
931  TH_JUMP_TAG(th, state);
932  }
933  return retval;
934 }
935 
939  int argc;
941 };
942 
943 static VALUE
945 {
946  const struct iter_method_arg * arg =
947  (struct iter_method_arg *) obj;
948 
949  return rb_call(arg->obj, arg->mid, arg->argc, arg->argv, CALL_FCALL);
950 }
951 
952 VALUE
954  VALUE (*bl_proc) (ANYARGS), VALUE data2)
955 {
956  struct iter_method_arg arg;
957 
958  arg.obj = obj;
959  arg.mid = mid;
960  arg.argc = argc;
961  arg.argv = argv;
962  return rb_iterate(iterate_method, (VALUE)&arg, bl_proc, data2);
963 }
964 
965 VALUE
967 {
968  return rb_call(obj, idEach, 0, 0, CALL_FCALL);
969 }
970 
971 static VALUE
972 eval_string_with_cref(VALUE self, VALUE src, VALUE scope, NODE *cref, const char *volatile file, volatile int line)
973 {
974  int state;
975  VALUE result = Qundef;
976  VALUE envval;
977  rb_binding_t *bind = 0;
978  rb_thread_t *th = GET_THREAD();
979  rb_env_t *env = NULL;
980  rb_block_t block;
981  volatile int parse_in_eval;
982  volatile int mild_compile_error;
983 
984  if (file == 0) {
985  file = rb_sourcefile();
986  line = rb_sourceline();
987  }
988 
989  parse_in_eval = th->parse_in_eval;
990  mild_compile_error = th->mild_compile_error;
991  PUSH_TAG();
992  if ((state = EXEC_TAG()) == 0) {
993  rb_iseq_t *iseq;
994  volatile VALUE iseqval;
995 
996  if (scope != Qnil) {
997  if (rb_obj_is_kind_of(scope, rb_cBinding)) {
998  GetBindingPtr(scope, bind);
999  envval = bind->env;
1000  if (strcmp(file, "(eval)") == 0 && bind->filename != Qnil) {
1001  file = RSTRING_PTR(bind->filename);
1002  line = bind->line_no;
1003  }
1004  }
1005  else {
1007  "wrong argument type %s (expected Binding)",
1008  rb_obj_classname(scope));
1009  }
1010  GetEnvPtr(envval, env);
1011  th->base_block = &env->block;
1012  }
1013  else {
1015 
1016  if (cfp != 0) {
1017  block = *RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp);
1018  th->base_block = &block;
1019  th->base_block->self = self;
1020  th->base_block->iseq = cfp->iseq; /* TODO */
1021  }
1022  else {
1023  rb_raise(rb_eRuntimeError, "Can't eval on top of Fiber or Thread");
1024  }
1025  }
1026 
1027  /* make eval iseq */
1028  th->parse_in_eval++;
1029  th->mild_compile_error++;
1030  iseqval = rb_iseq_compile(src, rb_str_new2(file), INT2FIX(line));
1031  th->mild_compile_error--;
1032  th->parse_in_eval--;
1033 
1034  vm_set_eval_stack(th, iseqval, cref);
1035  th->base_block = 0;
1036 
1037  if (0) { /* for debug */
1038  VALUE disasm = rb_iseq_disasm(iseqval);
1039  printf("%s\n", StringValuePtr(disasm));
1040  }
1041 
1042  /* save new env */
1043  GetISeqPtr(iseqval, iseq);
1044  if (bind && iseq->local_table_size > 0) {
1045  bind->env = rb_vm_make_env_object(th, th->cfp);
1046  }
1047 
1048  /* kick */
1049  CHECK_STACK_OVERFLOW(th->cfp, iseq->stack_max);
1050  result = vm_exec(th);
1051  }
1052  POP_TAG();
1053  th->mild_compile_error = mild_compile_error;
1054  th->parse_in_eval = parse_in_eval;
1055 
1056  if (state) {
1057  if (state == TAG_RAISE) {
1058  VALUE errinfo = th->errinfo;
1059  if (strcmp(file, "(eval)") == 0) {
1060  VALUE mesg, errat, bt2;
1061  ID id_mesg;
1062 
1063  CONST_ID(id_mesg, "mesg");
1064  errat = rb_get_backtrace(errinfo);
1065  mesg = rb_attr_get(errinfo, id_mesg);
1066  if (!NIL_P(errat) && TYPE(errat) == T_ARRAY &&
1067  (bt2 = vm_backtrace(th, -2), RARRAY_LEN(bt2) > 0)) {
1068  if (!NIL_P(mesg) && TYPE(mesg) == T_STRING && !RSTRING_LEN(mesg)) {
1069  if (OBJ_FROZEN(mesg)) {
1070  VALUE m = rb_str_cat(rb_str_dup(RARRAY_PTR(errat)[0]), ": ", 2);
1071  rb_ivar_set(errinfo, id_mesg, rb_str_append(m, mesg));
1072  }
1073  else {
1074  rb_str_update(mesg, 0, 0, rb_str_new2(": "));
1075  rb_str_update(mesg, 0, 0, RARRAY_PTR(errat)[0]);
1076  }
1077  }
1078  RARRAY_PTR(errat)[0] = RARRAY_PTR(bt2)[0];
1079  }
1080  }
1081  rb_exc_raise(errinfo);
1082  }
1083  JUMP_TAG(state);
1084  }
1085  return result;
1086 }
1087 
1088 static VALUE
1089 eval_string(VALUE self, VALUE src, VALUE scope, const char *file, int line)
1090 {
1091  return eval_string_with_cref(self, src, scope, 0, file, line);
1092 }
1093 
1094 /*
1095  * call-seq:
1096  * eval(string [, binding [, filename [,lineno]]]) -> obj
1097  *
1098  * Evaluates the Ruby expression(s) in <em>string</em>. If
1099  * <em>binding</em> is given, which must be a <code>Binding</code>
1100  * object, the evaluation is performed in its context. If the
1101  * optional <em>filename</em> and <em>lineno</em> parameters are
1102  * present, they will be used when reporting syntax errors.
1103  *
1104  * def get_binding(str)
1105  * return binding
1106  * end
1107  * str = "hello"
1108  * eval "str + ' Fred'" #=> "hello Fred"
1109  * eval "str + ' Fred'", get_binding("bye") #=> "bye Fred"
1110  */
1111 
1112 VALUE
1113 rb_f_eval(int argc, VALUE *argv, VALUE self)
1114 {
1115  VALUE src, scope, vfile, vline;
1116  const char *file = "(eval)";
1117  int line = 1;
1118 
1119  rb_scan_args(argc, argv, "13", &src, &scope, &vfile, &vline);
1120  if (rb_safe_level() >= 4) {
1121  StringValue(src);
1122  if (!NIL_P(scope) && !OBJ_TAINTED(scope)) {
1124  "Insecure: can't modify trusted binding");
1125  }
1126  }
1127  else {
1128  SafeStringValue(src);
1129  }
1130  if (argc >= 3) {
1131  StringValue(vfile);
1132  }
1133  if (argc >= 4) {
1134  line = NUM2INT(vline);
1135  }
1136 
1137  if (!NIL_P(vfile))
1138  file = RSTRING_PTR(vfile);
1139  return eval_string(self, src, scope, file, line);
1140 }
1141 
1142 VALUE
1143 rb_eval_string(const char *str)
1144 {
1145  return eval_string(rb_vm_top_self(), rb_str_new2(str), Qnil, "(eval)", 1);
1146 }
1147 
1148 VALUE
1149 rb_eval_string_protect(const char *str, int *state)
1150 {
1151  return rb_protect((VALUE (*)(VALUE))rb_eval_string, (VALUE)str, state);
1152 }
1153 
1154 VALUE
1155 rb_eval_string_wrap(const char *str, int *state)
1156 {
1157  int status;
1158  rb_thread_t *th = GET_THREAD();
1159  VALUE self = th->top_self;
1160  VALUE wrapper = th->top_wrapper;
1161  VALUE val;
1162 
1163  th->top_wrapper = rb_module_new();
1166 
1167  val = rb_eval_string_protect(str, &status);
1168 
1169  th->top_self = self;
1170  th->top_wrapper = wrapper;
1171 
1172  if (state) {
1173  *state = status;
1174  }
1175  else if (status) {
1176  JUMP_TAG(status);
1177  }
1178  return val;
1179 }
1180 
1181 VALUE
1182 rb_eval_cmd(VALUE cmd, VALUE arg, int level)
1183 {
1184  int state;
1185  VALUE val = Qnil; /* OK */
1186  volatile int safe = rb_safe_level();
1187 
1188  if (OBJ_TAINTED(cmd)) {
1189  level = 4;
1190  }
1191 
1192  if (TYPE(cmd) != T_STRING) {
1193  PUSH_TAG();
1194  rb_set_safe_level_force(level);
1195  if ((state = EXEC_TAG()) == 0) {
1196  val = rb_funcall2(cmd, rb_intern("call"), RARRAY_LENINT(arg),
1197  RARRAY_PTR(arg));
1198  }
1199  POP_TAG();
1200 
1202 
1203  if (state)
1204  JUMP_TAG(state);
1205  return val;
1206  }
1207 
1208  PUSH_TAG();
1209  if ((state = EXEC_TAG()) == 0) {
1210  val = eval_string(rb_vm_top_self(), cmd, Qnil, 0, 0);
1211  }
1212  POP_TAG();
1213 
1215  if (state) JUMP_TAG(state);
1216  return val;
1217 }
1218 
1219 /* block eval under the class/module context */
1220 
1221 static VALUE
1222 yield_under(VALUE under, VALUE self, VALUE values)
1223 {
1224  rb_thread_t *th = GET_THREAD();
1225  rb_block_t block, *blockptr;
1226  NODE *cref;
1227 
1228  if ((blockptr = GC_GUARDED_PTR_REF(th->cfp->lfp[0])) != 0) {
1229  block = *blockptr;
1230  block.self = self;
1231  th->cfp->lfp[0] = GC_GUARDED_PTR(&block);
1232  }
1233  cref = vm_cref_push(th, under, NOEX_PUBLIC, blockptr);
1235 
1236  if (values == Qundef) {
1237  return vm_yield_with_cref(th, 1, &self, cref);
1238  }
1239  else {
1240  return vm_yield_with_cref(th, RARRAY_LENINT(values), RARRAY_PTR(values), cref);
1241  }
1242 }
1243 
1244 /* string eval under the class/module context */
1245 static VALUE
1246 eval_under(VALUE under, VALUE self, VALUE src, const char *file, int line)
1247 {
1248  NODE *cref = vm_cref_push(GET_THREAD(), under, NOEX_PUBLIC, NULL);
1249 
1250  if (rb_safe_level() >= 4) {
1251  StringValue(src);
1252  }
1253  else {
1254  SafeStringValue(src);
1255  }
1256 
1257  return eval_string_with_cref(self, src, Qnil, cref, file, line);
1258 }
1259 
1260 static VALUE
1261 specific_eval(int argc, VALUE *argv, VALUE klass, VALUE self)
1262 {
1263  if (rb_block_given_p()) {
1264  if (argc > 0) {
1265  rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", argc);
1266  }
1267  return yield_under(klass, self, Qundef);
1268  }
1269  else {
1270  const char *file = "(eval)";
1271  int line = 1;
1272 
1273  if (argc == 0) {
1274  rb_raise(rb_eArgError, "block not supplied");
1275  }
1276  else {
1277  if (rb_safe_level() >= 4) {
1278  StringValue(argv[0]);
1279  }
1280  else {
1281  SafeStringValue(argv[0]);
1282  }
1283  if (argc > 3) {
1284  const char *name = rb_id2name(rb_frame_callee());
1286  "wrong number of arguments: %s(src) or %s{..}",
1287  name, name);
1288  }
1289  if (argc > 2)
1290  line = NUM2INT(argv[2]);
1291  if (argc > 1) {
1292  file = StringValuePtr(argv[1]);
1293  }
1294  }
1295  return eval_under(klass, self, argv[0], file, line);
1296  }
1297 }
1298 
1299 /*
1300  * call-seq:
1301  * obj.instance_eval(string [, filename [, lineno]] ) -> obj
1302  * obj.instance_eval {| | block } -> obj
1303  *
1304  * Evaluates a string containing Ruby source code, or the given block,
1305  * within the context of the receiver (_obj_). In order to set the
1306  * context, the variable +self+ is set to _obj_ while
1307  * the code is executing, giving the code access to _obj_'s
1308  * instance variables. In the version of <code>instance_eval</code>
1309  * that takes a +String+, the optional second and third
1310  * parameters supply a filename and starting line number that are used
1311  * when reporting compilation errors.
1312  *
1313  * class KlassWithSecret
1314  * def initialize
1315  * @secret = 99
1316  * end
1317  * end
1318  * k = KlassWithSecret.new
1319  * k.instance_eval { @secret } #=> 99
1320  */
1321 
1322 VALUE
1323 rb_obj_instance_eval(int argc, VALUE *argv, VALUE self)
1324 {
1325  VALUE klass;
1326 
1327  if (SPECIAL_CONST_P(self)) {
1328  klass = Qnil;
1329  }
1330  else {
1331  klass = rb_singleton_class(self);
1332  }
1333  return specific_eval(argc, argv, klass, self);
1334 }
1335 
1336 /*
1337  * call-seq:
1338  * obj.instance_exec(arg...) {|var...| block } -> obj
1339  *
1340  * Executes the given block within the context of the receiver
1341  * (_obj_). In order to set the context, the variable +self+ is set
1342  * to _obj_ while the code is executing, giving the code access to
1343  * _obj_'s instance variables. Arguments are passed as block parameters.
1344  *
1345  * class KlassWithSecret
1346  * def initialize
1347  * @secret = 99
1348  * end
1349  * end
1350  * k = KlassWithSecret.new
1351  * k.instance_exec(5) {|x| @secret+x } #=> 104
1352  */
1353 
1354 VALUE
1355 rb_obj_instance_exec(int argc, VALUE *argv, VALUE self)
1356 {
1357  VALUE klass;
1358 
1359  if (SPECIAL_CONST_P(self)) {
1360  klass = Qnil;
1361  }
1362  else {
1363  klass = rb_singleton_class(self);
1364  }
1365  return yield_under(klass, self, rb_ary_new4(argc, argv));
1366 }
1367 
1368 /*
1369  * call-seq:
1370  * mod.class_eval(string [, filename [, lineno]]) -> obj
1371  * mod.module_eval {|| block } -> obj
1372  *
1373  * Evaluates the string or block in the context of _mod_. This can
1374  * be used to add methods to a class. <code>module_eval</code> returns
1375  * the result of evaluating its argument. The optional _filename_
1376  * and _lineno_ parameters set the text for error messages.
1377  *
1378  * class Thing
1379  * end
1380  * a = %q{def hello() "Hello there!" end}
1381  * Thing.module_eval(a)
1382  * puts Thing.new.hello()
1383  * Thing.module_eval("invalid code", "dummy", 123)
1384  *
1385  * <em>produces:</em>
1386  *
1387  * Hello there!
1388  * dummy:123:in `module_eval': undefined local variable
1389  * or method `code' for Thing:Class
1390  */
1391 
1392 VALUE
1394 {
1395  return specific_eval(argc, argv, mod, mod);
1396 }
1397 
1398 /*
1399  * call-seq:
1400  * mod.module_exec(arg...) {|var...| block } -> obj
1401  * mod.class_exec(arg...) {|var...| block } -> obj
1402  *
1403  * Evaluates the given block in the context of the class/module.
1404  * The method defined in the block will belong to the receiver.
1405  *
1406  * class Thing
1407  * end
1408  * Thing.class_exec{
1409  * def hello() "Hello there!" end
1410  * }
1411  * puts Thing.new.hello()
1412  *
1413  * <em>produces:</em>
1414  *
1415  * Hello there!
1416  */
1417 
1418 VALUE
1420 {
1421  return yield_under(mod, mod, rb_ary_new4(argc, argv));
1422 }
1423 
1424 /*
1425  * call-seq:
1426  * throw(tag [, obj])
1427  *
1428  * Transfers control to the end of the active +catch+ block
1429  * waiting for _tag_. Raises +ArgumentError+ if there
1430  * is no +catch+ block for the _tag_. The optional second
1431  * parameter supplies a return value for the +catch+ block,
1432  * which otherwise defaults to +nil+. For examples, see
1433  * <code>Kernel::catch</code>.
1434  */
1435 
1436 static VALUE
1437 rb_f_throw(int argc, VALUE *argv)
1438 {
1439  VALUE tag, value;
1440 
1441  rb_scan_args(argc, argv, "11", &tag, &value);
1442  rb_throw_obj(tag, value);
1443  return Qnil; /* not reached */
1444 }
1445 
1446 void
1448 {
1449  rb_thread_t *th = GET_THREAD();
1450  struct rb_vm_tag *tt = th->tag;
1451 
1452  while (tt) {
1453  if (tt->tag == tag) {
1454  tt->retval = value;
1455  break;
1456  }
1457  tt = tt->prev;
1458  }
1459  if (!tt) {
1460  VALUE desc = rb_inspect(tag);
1461  RB_GC_GUARD(desc);
1462  rb_raise(rb_eArgError, "uncaught throw %s", RSTRING_PTR(desc));
1463  }
1465  th->errinfo = NEW_THROW_OBJECT(tag, 0, TAG_THROW);
1466 
1468 }
1469 
1470 void
1471 rb_throw(const char *tag, VALUE val)
1472 {
1473  rb_throw_obj(ID2SYM(rb_intern(tag)), val);
1474 }
1475 
1476 static VALUE
1478 {
1479  return rb_yield_0(1, &tag);
1480 }
1481 
1482 /*
1483  * call-seq:
1484  * catch([arg]) {|tag| block } -> obj
1485  *
1486  * +catch+ executes its block. If a +throw+ is
1487  * executed, Ruby searches up its stack for a +catch+ block
1488  * with a tag corresponding to the +throw+'s
1489  * _tag_. If found, that block is terminated, and
1490  * +catch+ returns the value given to +throw+. If
1491  * +throw+ is not called, the block terminates normally, and
1492  * the value of +catch+ is the value of the last expression
1493  * evaluated. +catch+ expressions may be nested, and the
1494  * +throw+ call need not be in lexical scope.
1495  *
1496  * def routine(n)
1497  * puts n
1498  * throw :done if n <= 0
1499  * routine(n-1)
1500  * end
1501  *
1502  *
1503  * catch(:done) { routine(3) }
1504  *
1505  * <em>produces:</em>
1506  *
1507  * 3
1508  * 2
1509  * 1
1510  * 0
1511  *
1512  * when _arg_ is given, +catch+ yields it as is, or when no
1513  * _arg_ is given, +catch+ assigns a new unique object to
1514  * +throw+. this is useful for nested +catch+. _arg_ can
1515  * be an arbitrary object, not only Symbol.
1516  *
1517  */
1518 
1519 static VALUE
1520 rb_f_catch(int argc, VALUE *argv)
1521 {
1522  VALUE tag;
1523 
1524  if (argc == 0) {
1525  tag = rb_obj_alloc(rb_cObject);
1526  }
1527  else {
1528  rb_scan_args(argc, argv, "01", &tag);
1529  }
1530  return rb_catch_obj(tag, catch_i, 0);
1531 }
1532 
1533 VALUE
1534 rb_catch(const char *tag, VALUE (*func)(), VALUE data)
1535 {
1536  VALUE vtag = tag ? ID2SYM(rb_intern(tag)) : rb_obj_alloc(rb_cObject);
1537  return rb_catch_obj(vtag, func, data);
1538 }
1539 
1540 VALUE
1542 {
1543  int state;
1544  volatile VALUE val = Qnil; /* OK */
1545  rb_thread_t *th = GET_THREAD();
1546  rb_control_frame_t *saved_cfp = th->cfp;
1547 
1548  PUSH_TAG();
1549 
1550  th->tag->tag = tag;
1551 
1552  if ((state = EXEC_TAG()) == 0) {
1553  /* call with argc=1, argv = [tag], block = Qnil to insure compatibility */
1554  val = (*func)(tag, data, 1, &tag, Qnil);
1555  }
1556  else if (state == TAG_THROW && RNODE(th->errinfo)->u1.value == tag) {
1557  th->cfp = saved_cfp;
1558  val = th->tag->retval;
1559  th->errinfo = Qnil;
1560  state = 0;
1561  }
1562  POP_TAG();
1563  if (state)
1564  JUMP_TAG(state);
1565 
1566  return val;
1567 }
1568 
1569 /*
1570  * call-seq:
1571  * caller(start=1) -> array or nil
1572  *
1573  * Returns the current execution stack---an array containing strings in
1574  * the form ``<em>file:line</em>'' or ``<em>file:line: in
1575  * `method'</em>''. The optional _start_ parameter
1576  * determines the number of initial stack entries to omit from the
1577  * result.
1578  *
1579  * Returns +nil+ if _start_ is greater than the size of
1580  * current execution stack.
1581  *
1582  * def a(skip)
1583  * caller(skip)
1584  * end
1585  * def b(skip)
1586  * a(skip)
1587  * end
1588  * def c(skip)
1589  * b(skip)
1590  * end
1591  * c(0) #=> ["prog:2:in `a'", "prog:5:in `b'", "prog:8:in `c'", "prog:10:in `<main>'"]
1592  * c(1) #=> ["prog:5:in `b'", "prog:8:in `c'", "prog:11:in `<main>'"]
1593  * c(2) #=> ["prog:8:in `c'", "prog:12:in `<main>'"]
1594  * c(3) #=> ["prog:13:in `<main>'"]
1595  * c(4) #=> []
1596  * c(5) #=> nil
1597  */
1598 
1599 static VALUE
1600 rb_f_caller(int argc, VALUE *argv)
1601 {
1602  VALUE level;
1603  int lev;
1604 
1605  rb_scan_args(argc, argv, "01", &level);
1606 
1607  if (NIL_P(level))
1608  lev = 1;
1609  else
1610  lev = NUM2INT(level);
1611  if (lev < 0)
1612  rb_raise(rb_eArgError, "negative level (%d)", lev);
1613 
1614  return vm_backtrace(GET_THREAD(), lev);
1615 }
1616 
1617 static int
1618 print_backtrace(void *arg, VALUE file, int line, VALUE method)
1619 {
1620  FILE *fp = arg;
1621  const char *filename = NIL_P(file) ? "ruby" : RSTRING_PTR(file);
1622  if (NIL_P(method)) {
1623  fprintf(fp, "\tfrom %s:%d:in unknown method\n",
1624  filename, line);
1625  }
1626  else {
1627  fprintf(fp, "\tfrom %s:%d:in `%s'\n",
1628  filename, line, RSTRING_PTR(method));
1629  }
1630  return FALSE;
1631 }
1632 
1633 void
1635 {
1637 }
1638 
1639 VALUE
1641 {
1642  return vm_backtrace(GET_THREAD(), -1);
1643 }
1644 
1645 VALUE
1647 {
1648  rb_thread_t *th;
1649  GetThreadPtr(thval, th);
1650 
1651  switch (th->status) {
1652  case THREAD_RUNNABLE:
1653  case THREAD_STOPPED:
1655  break;
1656  case THREAD_TO_KILL:
1657  case THREAD_KILLED:
1658  return Qnil;
1659  }
1660 
1661  return vm_backtrace(th, 0);
1662 }
1663 
1664 int
1666 {
1667  return vm_backtrace_each(GET_THREAD(), -1, NULL, iter, arg);
1668 }
1669 
1670 /*
1671  * call-seq:
1672  * local_variables -> array
1673  *
1674  * Returns the names of the current local variables.
1675  *
1676  * fred = 1
1677  * for i in 1..10
1678  * # ...
1679  * end
1680  * local_variables #=> [:fred, :i]
1681  */
1682 
1683 static VALUE
1685 {
1686  VALUE ary = rb_ary_new();
1687  rb_thread_t *th = GET_THREAD();
1688  rb_control_frame_t *cfp =
1690  int i;
1691 
1692  while (cfp) {
1693  if (cfp->iseq) {
1694  for (i = 0; i < cfp->iseq->local_table_size; i++) {
1695  ID lid = cfp->iseq->local_table[i];
1696  if (lid) {
1697  const char *vname = rb_id2name(lid);
1698  /* should skip temporary variable */
1699  if (vname) {
1700  rb_ary_push(ary, ID2SYM(lid));
1701  }
1702  }
1703  }
1704  }
1705  if (cfp->lfp != cfp->dfp) {
1706  /* block */
1707  VALUE *dfp = GC_GUARDED_PTR_REF(cfp->dfp[0]);
1708 
1709  if (vm_collect_local_variables_in_heap(th, dfp, ary)) {
1710  break;
1711  }
1712  else {
1713  while (cfp->dfp != dfp) {
1714  cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
1715  }
1716  }
1717  }
1718  else {
1719  break;
1720  }
1721  }
1722  return ary;
1723 }
1724 
1725 /*
1726  * call-seq:
1727  * block_given? -> true or false
1728  * iterator? -> true or false
1729  *
1730  * Returns <code>true</code> if <code>yield</code> would execute a
1731  * block in the current context. The <code>iterator?</code> form
1732  * is mildly deprecated.
1733  *
1734  * def try
1735  * if block_given?
1736  * yield
1737  * else
1738  * "no block"
1739  * end
1740  * end
1741  * try #=> "no block"
1742  * try { "hello" } #=> "hello"
1743  * try do "hello" end #=> "hello"
1744  */
1745 
1746 
1747 VALUE
1749 {
1750  rb_thread_t *th = GET_THREAD();
1751  rb_control_frame_t *cfp = th->cfp;
1753 
1754  if (cfp != 0 &&
1755  (cfp->lfp[0] & 0x02) == 0 &&
1756  GC_GUARDED_PTR_REF(cfp->lfp[0])) {
1757  return Qtrue;
1758  }
1759  else {
1760  return Qfalse;
1761  }
1762 }
1763 
1764 VALUE
1766 {
1767  rb_thread_t *th = GET_THREAD();
1768  rb_control_frame_t *cfp = th->cfp;
1770  if (cfp != 0) return cfp->iseq->filepath;
1771  return Qnil;
1772 }
1773 
1774 void
1776 {
1777  rb_define_global_function("eval", rb_f_eval, -1);
1778  rb_define_global_function("local_variables", rb_f_local_variables, 0);
1780  rb_define_global_function("block_given?", rb_f_block_given_p, 0);
1781 
1782  rb_define_global_function("catch", rb_f_catch, -1);
1783  rb_define_global_function("throw", rb_f_throw, -1);
1784 
1786 
1787  rb_define_method(rb_cBasicObject, "instance_eval", rb_obj_instance_eval, -1);
1788  rb_define_method(rb_cBasicObject, "instance_exec", rb_obj_instance_exec, -1);
1790 
1791 #if 1
1793  VM_METHOD_TYPE_OPTIMIZED, (void *)OPTIMIZED_METHOD_TYPE_SEND, 0);
1795  VM_METHOD_TYPE_OPTIMIZED, (void *)OPTIMIZED_METHOD_TYPE_SEND, 0);
1796 #else
1797  rb_define_method(rb_cBasicObject, "__send__", rb_f_send, -1);
1798  rb_define_method(rb_mKernel, "send", rb_f_send, -1);
1799 #endif
1800  rb_define_method(rb_mKernel, "public_send", rb_f_public_send, -1);
1801 
1802  rb_define_method(rb_cModule, "module_exec", rb_mod_module_exec, -1);
1803  rb_define_method(rb_cModule, "class_exec", rb_mod_module_exec, -1);
1804  rb_define_method(rb_cModule, "module_eval", rb_mod_module_eval, -1);
1805  rb_define_method(rb_cModule, "class_eval", rb_mod_module_eval, -1);
1806 
1807  rb_define_global_function("caller", rb_f_caller, -1);
1808 }
1809 
1810