add a test.
[ruby-svn.git] / eval.c
blob142433ac933d1c63a71bfafa196a5dfab1da6e76
1 /**********************************************************************
3 eval.c -
5 $Author$
6 created at: Thu Jun 10 14:22:17 JST 1993
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
12 **********************************************************************/
14 #include "eval_intern.h"
16 VALUE proc_invoke(VALUE, VALUE, VALUE, VALUE);
17 VALUE rb_binding_new(void);
18 NORETURN(void rb_raise_jump(VALUE));
20 ID rb_frame_callee(void);
21 VALUE rb_eLocalJumpError;
22 VALUE rb_eSysStackError;
24 #define exception_error GET_VM()->special_exceptions[ruby_error_reenter]
26 #include "eval_error.c"
27 #include "eval_safe.c"
28 #include "eval_jump.c"
30 /* initialize ruby */
32 #if defined(__APPLE__)
33 #define environ (*_NSGetEnviron())
34 #elif !defined(_WIN32) && !defined(__MACOS__) || defined(_WIN32_WCE)
35 extern char **environ;
36 #endif
37 char **rb_origenviron;
39 void rb_clear_trace_func(void);
40 void rb_thread_stop_timer_thread(void);
42 void rb_call_inits(void);
43 void Init_heap(void);
44 void Init_ext(void);
45 void Init_BareVM(void);
47 void
48 ruby_init(void)
50 static int initialized = 0;
51 int state;
53 if (initialized)
54 return;
55 initialized = 1;
57 #ifdef __MACOS__
58 rb_origenviron = 0;
59 #else
60 rb_origenviron = environ;
61 #endif
63 Init_stack((void *)&state);
64 Init_BareVM();
65 Init_heap();
67 PUSH_TAG();
68 if ((state = EXEC_TAG()) == 0) {
69 rb_call_inits();
71 #ifdef __MACOS__
72 _macruby_init();
73 #elif defined(__VMS)
74 _vmsruby_init();
75 #endif
77 ruby_prog_init();
78 ALLOW_INTS;
80 POP_TAG();
82 if (state) {
83 error_print();
84 exit(EXIT_FAILURE);
86 GET_VM()->running = 1;
89 extern void rb_clear_trace_func(void);
91 void *
92 ruby_options(int argc, char **argv)
94 int state;
95 void *tree = 0;
97 Init_stack((void *)&state);
98 PUSH_TAG();
99 if ((state = EXEC_TAG()) == 0) {
100 SAVE_ROOT_JMPBUF(GET_THREAD(), tree = ruby_process_options(argc, argv));
102 else {
103 rb_clear_trace_func();
104 state = error_handle(state);
105 tree = (void *)INT2FIX(state);
107 POP_TAG();
108 return tree;
111 static void
112 ruby_finalize_0(void)
114 PUSH_TAG();
115 if (EXEC_TAG() == 0) {
116 rb_trap_exit();
118 POP_TAG();
119 rb_exec_end_proc();
120 rb_clear_trace_func();
123 static void
124 ruby_finalize_1(void)
126 ruby_sig_finalize();
127 GET_THREAD()->errinfo = Qnil;
128 rb_gc_call_finalizer_at_exit();
131 void
132 ruby_finalize(void)
134 ruby_finalize_0();
135 ruby_finalize_1();
138 void rb_thread_stop_timer_thread(void);
141 ruby_cleanup(int ex)
143 int state;
144 volatile VALUE errs[2];
145 rb_thread_t *th = GET_THREAD();
146 int nerr;
148 errs[1] = th->errinfo;
149 th->safe_level = 0;
150 Init_stack((void *)&state);
152 PUSH_TAG();
153 if ((state = EXEC_TAG()) == 0) {
154 SAVE_ROOT_JMPBUF(th, ruby_finalize_0());
156 POP_TAG();
158 errs[0] = th->errinfo;
159 PUSH_TAG();
160 if ((state = EXEC_TAG()) == 0) {
161 SAVE_ROOT_JMPBUF(th, rb_thread_terminate_all());
163 else if (ex == 0) {
164 ex = state;
166 th->errinfo = errs[1];
167 ex = error_handle(ex);
168 ruby_finalize_1();
169 POP_TAG();
170 rb_thread_stop_timer_thread();
172 for (nerr = 0; nerr < sizeof(errs) / sizeof(errs[0]); ++nerr) {
173 VALUE err = errs[nerr];
175 if (!RTEST(err)) continue;
177 /* th->errinfo contains a NODE while break'ing */
178 if (TYPE(err) == T_NODE) continue;
180 if (rb_obj_is_kind_of(err, rb_eSystemExit)) {
181 return sysexit_status(err);
183 else if (rb_obj_is_kind_of(err, rb_eSignal)) {
184 VALUE sig = rb_iv_get(err, "signo");
185 ruby_default_signal(NUM2INT(sig));
187 else if (ex == 0) {
188 ex = 1;
192 #if EXIT_SUCCESS != 0 || EXIT_FAILURE != 1
193 switch (ex) {
194 #if EXIT_SUCCESS != 0
195 case 0: return EXIT_SUCCESS;
196 #endif
197 #if EXIT_FAILURE != 1
198 case 1: return EXIT_FAILURE;
199 #endif
201 #endif
203 return ex;
207 ruby_exec_node(void *n, const char *file)
209 int state;
210 VALUE iseq = (VALUE)n;
211 rb_thread_t *th = GET_THREAD();
213 if (!n) return 0;
215 PUSH_TAG();
216 if ((state = EXEC_TAG()) == 0) {
217 SAVE_ROOT_JMPBUF(th, {
218 th->base_block = 0;
219 rb_iseq_eval(iseq);
222 POP_TAG();
223 return state;
226 void
227 ruby_stop(int ex)
229 exit(ruby_cleanup(ex));
233 ruby_run_node(void *n)
235 VALUE v = (VALUE)n;
237 switch (v) {
238 case Qtrue: return EXIT_SUCCESS;
239 case Qfalse: return EXIT_FAILURE;
241 if (FIXNUM_P(v)) {
242 return FIX2INT(v);
244 Init_stack((void *)&n);
245 return ruby_cleanup(ruby_exec_node(n, 0));
249 * call-seq:
250 * Module.nesting => array
252 * Returns the list of +Modules+ nested at the point of call.
254 * module M1
255 * module M2
256 * $a = Module.nesting
257 * end
258 * end
259 * $a #=> [M1::M2, M1]
260 * $a[0].name #=> "M1::M2"
263 static VALUE
264 rb_mod_nesting(void)
266 VALUE ary = rb_ary_new();
267 const NODE *cref = vm_cref();
269 while (cref && cref->nd_next) {
270 VALUE klass = cref->nd_clss;
271 if (!NIL_P(klass)) {
272 rb_ary_push(ary, klass);
274 cref = cref->nd_next;
276 return ary;
280 * call-seq:
281 * Module.constants => array
283 * Returns an array of the names of all constants defined in the
284 * system. This list includes the names of all modules and classes.
286 * p Module.constants.sort[1..5]
288 * <em>produces:</em>
290 * ["ARGV", "ArgumentError", "Array", "Bignum", "Binding"]
293 static VALUE
294 rb_mod_s_constants(int argc, VALUE *argv, VALUE mod)
296 const NODE *cref = vm_cref();
297 VALUE klass;
298 VALUE cbase = 0;
299 void *data = 0;
301 if (argc > 0) {
302 return rb_mod_constants(argc, argv, rb_cModule);
305 while (cref) {
306 klass = cref->nd_clss;
307 if (!NIL_P(klass)) {
308 data = rb_mod_const_at(cref->nd_clss, data);
309 if (!cbase) {
310 cbase = klass;
313 cref = cref->nd_next;
316 if (cbase) {
317 data = rb_mod_const_of(cbase, data);
319 return rb_const_list(data);
322 void
323 rb_frozen_class_p(VALUE klass)
325 const char *desc = "something(?!)";
327 if (OBJ_FROZEN(klass)) {
328 if (FL_TEST(klass, FL_SINGLETON))
329 desc = "object";
330 else {
331 switch (TYPE(klass)) {
332 case T_MODULE:
333 case T_ICLASS:
334 desc = "module";
335 break;
336 case T_CLASS:
337 desc = "class";
338 break;
341 rb_error_frozen(desc);
345 NORETURN(static void rb_longjmp(int, VALUE));
346 VALUE rb_make_backtrace(void);
348 static void
349 rb_longjmp(int tag, VALUE mesg)
351 VALUE at;
352 VALUE e;
353 rb_thread_t *th = GET_THREAD();
354 const char *file;
355 int line = 0;
357 if (rb_thread_set_raised(th)) {
358 th->errinfo = exception_error;
359 JUMP_TAG(TAG_FATAL);
362 if (NIL_P(mesg))
363 mesg = th->errinfo;
364 if (NIL_P(mesg)) {
365 mesg = rb_exc_new(rb_eRuntimeError, 0, 0);
368 file = rb_sourcefile();
369 if (file) line = rb_sourceline();
370 if (file && !NIL_P(mesg)) {
371 at = get_backtrace(mesg);
372 if (NIL_P(at)) {
373 at = rb_make_backtrace();
374 if (OBJ_FROZEN(mesg)) {
375 mesg = rb_obj_dup(mesg);
377 set_backtrace(mesg, at);
380 if (!NIL_P(mesg)) {
381 th->errinfo = mesg;
384 if (RTEST(ruby_debug) && !NIL_P(e = th->errinfo) &&
385 !rb_obj_is_kind_of(e, rb_eSystemExit)) {
386 int status;
388 PUSH_TAG();
389 if ((status = EXEC_TAG()) == 0) {
390 RB_GC_GUARD(e) = rb_obj_as_string(e);
391 if (file) {
392 warn_printf("Exception `%s' at %s:%d - %s\n",
393 rb_obj_classname(th->errinfo),
394 file, line, RSTRING_PTR(e));
396 else {
397 warn_printf("Exception `%s' - %s\n",
398 rb_obj_classname(th->errinfo),
399 RSTRING_PTR(e));
402 POP_TAG();
403 if (status == TAG_FATAL && th->errinfo == exception_error) {
404 th->errinfo = mesg;
406 else if (status) {
407 rb_thread_reset_raised(th);
408 JUMP_TAG(status);
412 rb_trap_restore_mask();
414 if (tag != TAG_FATAL) {
415 EXEC_EVENT_HOOK(th, RUBY_EVENT_RAISE, th->cfp->self,
416 0 /* TODO: id */, 0 /* TODO: klass */);
419 rb_thread_raised_clear(th);
420 JUMP_TAG(tag);
423 void
424 rb_exc_raise(VALUE mesg)
426 rb_longjmp(TAG_RAISE, mesg);
429 void
430 rb_exc_fatal(VALUE mesg)
432 rb_longjmp(TAG_FATAL, mesg);
435 void
436 rb_interrupt(void)
438 rb_raise(rb_eInterrupt, "%s", "");
441 static VALUE get_errinfo(void);
444 * call-seq:
445 * raise
446 * raise(string)
447 * raise(exception [, string [, array]])
448 * fail
449 * fail(string)
450 * fail(exception [, string [, array]])
452 * With no arguments, raises the exception in <code>$!</code> or raises
453 * a <code>RuntimeError</code> if <code>$!</code> is +nil+.
454 * With a single +String+ argument, raises a
455 * +RuntimeError+ with the string as a message. Otherwise,
456 * the first parameter should be the name of an +Exception+
457 * class (or an object that returns an +Exception+ object when sent
458 * an +exception+ message). The optional second parameter sets the
459 * message associated with the exception, and the third parameter is an
460 * array of callback information. Exceptions are caught by the
461 * +rescue+ clause of <code>begin...end</code> blocks.
463 * raise "Failed to create socket"
464 * raise ArgumentError, "No parameters", caller
467 static VALUE
468 rb_f_raise(int argc, VALUE *argv)
470 VALUE err;
471 if (argc == 0) {
472 err = get_errinfo();
473 if (!NIL_P(err)) {
474 argc = 1;
475 argv = &err;
478 rb_raise_jump(rb_make_exception(argc, argv));
479 return Qnil; /* not reached */
482 VALUE
483 rb_make_exception(int argc, VALUE *argv)
485 VALUE mesg;
486 ID exception;
487 int n;
489 mesg = Qnil;
490 switch (argc) {
491 case 0:
492 mesg = Qnil;
493 break;
494 case 1:
495 if (NIL_P(argv[0]))
496 break;
497 if (TYPE(argv[0]) == T_STRING) {
498 mesg = rb_exc_new3(rb_eRuntimeError, argv[0]);
499 break;
501 n = 0;
502 goto exception_call;
504 case 2:
505 case 3:
506 n = 1;
507 exception_call:
508 CONST_ID(exception, "exception");
509 if (!rb_respond_to(argv[0], exception)) {
510 rb_raise(rb_eTypeError, "exception class/object expected");
512 mesg = rb_funcall(argv[0], exception, n, argv[1]);
513 break;
514 default:
515 rb_raise(rb_eArgError, "wrong number of arguments");
516 break;
518 if (argc > 0) {
519 if (!rb_obj_is_kind_of(mesg, rb_eException))
520 rb_raise(rb_eTypeError, "exception object expected");
521 if (argc > 2)
522 set_backtrace(mesg, argv[2]);
525 return mesg;
528 void
529 rb_raise_jump(VALUE mesg)
531 rb_thread_t *th = GET_THREAD();
532 th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp);
533 /* TODO: fix me */
534 rb_longjmp(TAG_RAISE, mesg);
537 void
538 rb_jump_tag(int tag)
540 JUMP_TAG(tag);
544 rb_block_given_p(void)
546 rb_thread_t *th = GET_THREAD();
548 if ((th->cfp->lfp[0] & 0x02) == 0 &&
549 GC_GUARDED_PTR_REF(th->cfp->lfp[0])) {
550 return Qtrue;
552 else {
553 return Qfalse;
558 rb_iterator_p()
560 return rb_block_given_p();
564 * call-seq:
565 * block_given? => true or false
566 * iterator? => true or false
568 * Returns <code>true</code> if <code>yield</code> would execute a
569 * block in the current context. The <code>iterator?</code> form
570 * is mildly deprecated.
572 * def try
573 * if block_given?
574 * yield
575 * else
576 * "no block"
577 * end
578 * end
579 * try #=> "no block"
580 * try { "hello" } #=> "hello"
581 * try do "hello" end #=> "hello"
585 VALUE
586 rb_f_block_given_p(void)
588 rb_thread_t *th = GET_THREAD();
589 rb_control_frame_t *cfp = th->cfp;
590 cfp = vm_get_ruby_level_caller_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
592 if (cfp != 0 &&
593 (cfp->lfp[0] & 0x02) == 0 &&
594 GC_GUARDED_PTR_REF(cfp->lfp[0])) {
595 return Qtrue;
597 else {
598 return Qfalse;
602 VALUE rb_eThreadError;
604 void
605 rb_need_block()
607 if (!rb_block_given_p()) {
608 vm_localjump_error("no block given", Qnil, 0);
612 VALUE
613 rb_rescue2(VALUE (* b_proc) (ANYARGS), VALUE data1,
614 VALUE (* r_proc) (ANYARGS), VALUE data2, ...)
616 int state;
617 rb_thread_t *th = GET_THREAD();
618 rb_control_frame_t *cfp = th->cfp;
619 volatile VALUE result;
620 volatile VALUE e_info = th->errinfo;
621 va_list args;
623 PUSH_TAG();
624 if ((state = EXEC_TAG()) == 0) {
625 retry_entry:
626 result = (*b_proc) (data1);
628 else {
629 th->cfp = cfp; /* restore */
631 if (state == TAG_RAISE) {
632 int handle = Qfalse;
633 VALUE eclass;
635 va_init_list(args, data2);
636 while ((eclass = va_arg(args, VALUE)) != 0) {
637 if (rb_obj_is_kind_of(th->errinfo, eclass)) {
638 handle = Qtrue;
639 break;
642 va_end(args);
644 if (handle) {
645 if (r_proc) {
646 PUSH_TAG();
647 if ((state = EXEC_TAG()) == 0) {
648 result = (*r_proc) (data2, th->errinfo);
650 POP_TAG();
651 if (state == TAG_RETRY) {
652 state = 0;
653 th->errinfo = Qnil;
654 goto retry_entry;
657 else {
658 result = Qnil;
659 state = 0;
661 if (state == 0) {
662 th->errinfo = e_info;
667 POP_TAG();
668 if (state)
669 JUMP_TAG(state);
671 return result;
674 VALUE
675 rb_rescue(VALUE (* b_proc)(ANYARGS), VALUE data1,
676 VALUE (* r_proc)(ANYARGS), VALUE data2)
678 return rb_rescue2(b_proc, data1, r_proc, data2, rb_eStandardError,
679 (VALUE)0);
682 VALUE
683 rb_protect(VALUE (* proc) (VALUE), VALUE data, int * state)
685 VALUE result = Qnil; /* OK */
686 int status;
687 rb_thread_t *th = GET_THREAD();
688 rb_control_frame_t *cfp = th->cfp;
689 struct rb_vm_trap_tag trap_tag;
690 rb_jmpbuf_t org_jmpbuf;
692 trap_tag.prev = th->trap_tag;
694 PUSH_TAG();
695 th->trap_tag = &trap_tag;
696 MEMCPY(&org_jmpbuf, &(th)->root_jmpbuf, rb_jmpbuf_t, 1);
697 if ((status = EXEC_TAG()) == 0) {
698 SAVE_ROOT_JMPBUF(th, result = (*proc) (data));
700 MEMCPY(&(th)->root_jmpbuf, &org_jmpbuf, rb_jmpbuf_t, 1);
701 th->trap_tag = trap_tag.prev;
702 POP_TAG();
704 if (state) {
705 *state = status;
707 if (status != 0) {
708 th->cfp = cfp;
709 return Qnil;
712 return result;
715 VALUE
716 rb_ensure(VALUE (*b_proc)(ANYARGS), VALUE data1, VALUE (*e_proc)(ANYARGS), VALUE data2)
718 int state;
719 volatile VALUE result = Qnil;
721 PUSH_TAG();
722 if ((state = EXEC_TAG()) == 0) {
723 result = (*b_proc) (data1);
725 POP_TAG();
726 /* TODO: fix me */
727 /* retval = prot_tag ? prot_tag->retval : Qnil; */ /* save retval */
728 (*e_proc) (data2);
729 if (state)
730 JUMP_TAG(state);
731 return result;
734 VALUE
735 rb_with_disable_interrupt(VALUE (*proc)(ANYARGS), VALUE data)
737 VALUE result = Qnil; /* OK */
738 int status;
740 DEFER_INTS;
742 int thr_critical = rb_thread_critical;
744 rb_thread_critical = Qtrue;
745 PUSH_TAG();
746 if ((status = EXEC_TAG()) == 0) {
747 result = (*proc) (data);
749 POP_TAG();
750 rb_thread_critical = thr_critical;
752 ENABLE_INTS;
753 if (status)
754 JUMP_TAG(status);
756 return result;
759 static ID
760 frame_func_id(rb_control_frame_t *cfp)
762 rb_iseq_t *iseq = cfp->iseq;
763 if (!iseq) {
764 return cfp->method_id;
766 while (iseq) {
767 if (RUBY_VM_IFUNC_P(iseq)) {
768 return rb_intern("<ifunc>");
770 if (iseq->defined_method_id) {
771 return iseq->defined_method_id;
773 if (iseq->local_iseq == iseq) {
774 break;
776 iseq = iseq->parent_iseq;
778 return 0;
782 rb_frame_this_func(void)
784 return frame_func_id(GET_THREAD()->cfp);
788 rb_frame_callee(void)
790 rb_thread_t *th = GET_THREAD();
791 rb_control_frame_t *prev_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp);
792 /* check if prev_cfp can be accessible */
793 if ((void *)(th->stack + th->stack_size) == (void *)(prev_cfp)) {
794 return 0;
796 return frame_func_id(prev_cfp);
799 void
800 rb_frame_pop(void)
802 rb_thread_t *th = GET_THREAD();
803 th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp);
807 * call-seq:
808 * append_features(mod) => mod
810 * When this module is included in another, Ruby calls
811 * <code>append_features</code> in this module, passing it the
812 * receiving module in _mod_. Ruby's default implementation is
813 * to add the constants, methods, and module variables of this module
814 * to _mod_ if this module has not already been added to
815 * _mod_ or one of its ancestors. See also <code>Module#include</code>.
818 static VALUE
819 rb_mod_append_features(VALUE module, VALUE include)
821 switch (TYPE(include)) {
822 case T_CLASS:
823 case T_MODULE:
824 break;
825 default:
826 Check_Type(include, T_CLASS);
827 break;
829 rb_include_module(include, module);
831 return module;
835 * call-seq:
836 * include(module, ...) => self
838 * Invokes <code>Module.append_features</code> on each parameter in turn.
841 static VALUE
842 rb_mod_include(int argc, VALUE *argv, VALUE module)
844 int i;
846 for (i = 0; i < argc; i++)
847 Check_Type(argv[i], T_MODULE);
848 while (argc--) {
849 rb_funcall(argv[argc], rb_intern("append_features"), 1, module);
850 rb_funcall(argv[argc], rb_intern("included"), 1, module);
852 return module;
855 void
856 rb_obj_call_init(VALUE obj, int argc, VALUE *argv)
858 PASS_PASSED_BLOCK();
859 rb_funcall2(obj, idInitialize, argc, argv);
862 void
863 rb_extend_object(VALUE obj, VALUE module)
865 rb_include_module(rb_singleton_class(obj), module);
869 * call-seq:
870 * extend_object(obj) => obj
872 * Extends the specified object by adding this module's constants and
873 * methods (which are added as singleton methods). This is the callback
874 * method used by <code>Object#extend</code>.
876 * module Picky
877 * def Picky.extend_object(o)
878 * if String === o
879 * puts "Can't add Picky to a String"
880 * else
881 * puts "Picky added to #{o.class}"
882 * super
883 * end
884 * end
885 * end
886 * (s = Array.new).extend Picky # Call Object.extend
887 * (s = "quick brown fox").extend Picky
889 * <em>produces:</em>
891 * Picky added to Array
892 * Can't add Picky to a String
895 static VALUE
896 rb_mod_extend_object(VALUE mod, VALUE obj)
898 rb_extend_object(obj, mod);
899 return obj;
903 * call-seq:
904 * obj.extend(module, ...) => obj
906 * Adds to _obj_ the instance methods from each module given as a
907 * parameter.
909 * module Mod
910 * def hello
911 * "Hello from Mod.\n"
912 * end
913 * end
915 * class Klass
916 * def hello
917 * "Hello from Klass.\n"
918 * end
919 * end
921 * k = Klass.new
922 * k.hello #=> "Hello from Klass.\n"
923 * k.extend(Mod) #=> #<Klass:0x401b3bc8>
924 * k.hello #=> "Hello from Mod.\n"
927 static VALUE
928 rb_obj_extend(int argc, VALUE *argv, VALUE obj)
930 int i;
932 if (argc == 0) {
933 rb_raise(rb_eArgError, "wrong number of arguments (0 for 1)");
935 for (i = 0; i < argc; i++)
936 Check_Type(argv[i], T_MODULE);
937 while (argc--) {
938 rb_funcall(argv[argc], rb_intern("extend_object"), 1, obj);
939 rb_funcall(argv[argc], rb_intern("extended"), 1, obj);
941 return obj;
945 * call-seq:
946 * include(module, ...) => self
948 * Invokes <code>Module.append_features</code>
949 * on each parameter in turn. Effectively adds the methods and constants
950 * in each module to the receiver.
953 static VALUE
954 top_include(int argc, VALUE *argv, VALUE self)
956 rb_thread_t *th = GET_THREAD();
958 rb_secure(4);
959 if (th->top_wrapper) {
960 rb_warning
961 ("main#include in the wrapped load is effective only in wrapper module");
962 return rb_mod_include(argc, argv, th->top_wrapper);
964 return rb_mod_include(argc, argv, rb_cObject);
967 VALUE rb_f_trace_var();
968 VALUE rb_f_untrace_var();
970 static VALUE *
971 errinfo_place(void)
973 rb_thread_t *th = GET_THREAD();
974 rb_control_frame_t *cfp = th->cfp;
975 rb_control_frame_t *end_cfp = RUBY_VM_END_CONTROL_FRAME(th);
977 while (RUBY_VM_VALID_CONTROL_FRAME_P(cfp, end_cfp)) {
978 if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
979 if (cfp->iseq->type == ISEQ_TYPE_RESCUE) {
980 return &cfp->dfp[-2];
982 else if (cfp->iseq->type == ISEQ_TYPE_ENSURE &&
983 TYPE(cfp->dfp[-2]) != T_NODE &&
984 !FIXNUM_P(cfp->dfp[-2])) {
985 return &cfp->dfp[-2];
988 cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
990 return 0;
993 static VALUE
994 get_errinfo(void)
996 VALUE *ptr = errinfo_place();
997 if (ptr) {
998 return *ptr;
1000 else {
1001 return Qnil;
1005 static VALUE
1006 errinfo_getter(ID id)
1008 return get_errinfo();
1011 #if 0
1012 static void
1013 errinfo_setter(VALUE val, ID id, VALUE *var)
1015 if (!NIL_P(val) && !rb_obj_is_kind_of(val, rb_eException)) {
1016 rb_raise(rb_eTypeError, "assigning non-exception to $!");
1018 else {
1019 VALUE *ptr = errinfo_place();
1020 if (ptr) {
1021 *ptr = val;
1023 else {
1024 rb_raise(rb_eRuntimeError, "errinfo_setter: not in rescue clause.");
1028 #endif
1030 VALUE
1031 rb_errinfo(void)
1033 rb_thread_t *th = GET_THREAD();
1034 return th->errinfo;
1037 void
1038 rb_set_errinfo(VALUE err)
1040 if (!NIL_P(err) && !rb_obj_is_kind_of(err, rb_eException)) {
1041 rb_raise(rb_eTypeError, "assigning non-exception to $!");
1043 GET_THREAD()->errinfo = err;
1046 VALUE
1047 rb_rubylevel_errinfo(void)
1049 return get_errinfo();
1052 static VALUE
1053 errat_getter(ID id)
1055 VALUE err = get_errinfo();
1056 if (!NIL_P(err)) {
1057 return get_backtrace(err);
1059 else {
1060 return Qnil;
1064 static void
1065 errat_setter(VALUE val, ID id, VALUE *var)
1067 VALUE err = get_errinfo();
1068 if (NIL_P(err)) {
1069 rb_raise(rb_eArgError, "$! not set");
1071 set_backtrace(err, val);
1074 int vm_collect_local_variables_in_heap(rb_thread_t *th, VALUE *dfp, VALUE ary);
1077 * call-seq:
1078 * local_variables => array
1080 * Returns the names of the current local variables.
1082 * fred = 1
1083 * for i in 1..10
1084 * # ...
1085 * end
1086 * local_variables #=> ["fred", "i"]
1089 static VALUE
1090 rb_f_local_variables(void)
1092 VALUE ary = rb_ary_new();
1093 rb_thread_t *th = GET_THREAD();
1094 rb_control_frame_t *cfp =
1095 vm_get_ruby_level_caller_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp));
1096 int i;
1098 while (cfp) {
1099 if (cfp->iseq) {
1100 for (i = 0; i < cfp->iseq->local_table_size; i++) {
1101 ID lid = cfp->iseq->local_table[i];
1102 if (lid) {
1103 const char *vname = rb_id2name(lid);
1104 /* should skip temporary variable */
1105 if (vname) {
1106 rb_ary_push(ary, ID2SYM(lid));
1111 if (cfp->lfp != cfp->dfp) {
1112 /* block */
1113 VALUE *dfp = GC_GUARDED_PTR_REF(cfp->dfp[0]);
1115 if (vm_collect_local_variables_in_heap(th, dfp, ary)) {
1116 break;
1118 else {
1119 while (cfp->dfp != dfp) {
1120 cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
1124 else {
1125 break;
1128 return ary;
1133 * call-seq:
1134 * __method__ => symbol
1135 * __callee__ => symbol
1137 * Returns the name of the current method as a Symbol.
1138 * If called outside of a method, it returns <code>nil</code>.
1142 static VALUE
1143 rb_f_method_name(void)
1145 ID fname = rb_frame_callee();
1147 if (fname) {
1148 return ID2SYM(fname);
1150 else {
1151 return Qnil;
1155 void
1156 Init_eval(void)
1158 /* TODO: fix position */
1159 GET_THREAD()->vm->mark_object_ary = rb_ary_new();
1161 rb_define_virtual_variable("$@", errat_getter, errat_setter);
1162 rb_define_virtual_variable("$!", errinfo_getter, 0);
1164 rb_define_global_function("eval", rb_f_eval, -1);
1165 rb_define_global_function("iterator?", rb_f_block_given_p, 0);
1166 rb_define_global_function("block_given?", rb_f_block_given_p, 0);
1168 rb_define_global_function("raise", rb_f_raise, -1);
1169 rb_define_global_function("fail", rb_f_raise, -1);
1171 rb_define_global_function("global_variables", rb_f_global_variables, 0); /* in variable.c */
1172 rb_define_global_function("local_variables", rb_f_local_variables, 0);
1174 rb_define_global_function("__method__", rb_f_method_name, 0);
1175 rb_define_global_function("__callee__", rb_f_method_name, 0);
1177 rb_define_private_method(rb_cModule, "append_features", rb_mod_append_features, 1);
1178 rb_define_private_method(rb_cModule, "extend_object", rb_mod_extend_object, 1);
1179 rb_define_private_method(rb_cModule, "include", rb_mod_include, -1);
1180 rb_define_method(rb_cModule, "module_eval", rb_mod_module_eval, -1);
1181 rb_define_method(rb_cModule, "class_eval", rb_mod_module_eval, -1);
1183 rb_undef_method(rb_cClass, "module_function");
1186 extern void Init_vm_eval(void);
1187 extern void Init_eval_method(void);
1188 Init_vm_eval();
1189 Init_eval_method();
1192 rb_define_singleton_method(rb_cModule, "nesting", rb_mod_nesting, 0);
1193 rb_define_singleton_method(rb_cModule, "constants", rb_mod_s_constants, -1);
1195 rb_define_singleton_method(rb_vm_top_self(), "include", top_include, -1);
1197 rb_define_method(rb_mKernel, "extend", rb_obj_extend, -1);
1199 rb_define_global_function("trace_var", rb_f_trace_var, -1); /* in variable.c */
1200 rb_define_global_function("untrace_var", rb_f_untrace_var, -1); /* in variable.c */
1202 rb_define_virtual_variable("$SAFE", safe_getter, safe_setter);
1204 exception_error = rb_exc_new3(rb_eFatal,
1205 rb_obj_freeze(rb_str_new2("exception reentered")));
1206 rb_ivar_set(exception_error, idThrowState, INT2FIX(TAG_FATAL));
1207 OBJ_TAINT(exception_error);
1208 OBJ_FREEZE(exception_error);
1212 /* for parser */
1215 rb_dvar_defined(ID id)
1217 rb_thread_t *th = GET_THREAD();
1218 rb_iseq_t *iseq;
1219 if (th->base_block && (iseq = th->base_block->iseq)) {
1220 while (iseq->type == ISEQ_TYPE_BLOCK ||
1221 iseq->type == ISEQ_TYPE_RESCUE ||
1222 iseq->type == ISEQ_TYPE_ENSURE ||
1223 iseq->type == ISEQ_TYPE_EVAL) {
1224 int i;
1226 for (i = 0; i < iseq->local_table_size; i++) {
1227 if (iseq->local_table[i] == id) {
1228 return 1;
1231 iseq = iseq->parent_iseq;
1234 return 0;
1238 rb_local_defined(ID id)
1240 rb_thread_t *th = GET_THREAD();
1241 rb_iseq_t *iseq;
1243 if (th->base_block && th->base_block->iseq) {
1244 int i;
1245 iseq = th->base_block->iseq->local_iseq;
1247 for (i=0; i<iseq->local_table_size; i++) {
1248 if (iseq->local_table[i] == id) {
1249 return 1;
1253 return 0;
1257 rb_parse_in_eval(void)
1259 return GET_THREAD()->parse_in_eval != 0;