Ruby 1.9.2p136(2010-12-25revision30365)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

# eval.c

Go to the documentation of this file.

    00001 /**********************************************************************
    00002
    00003   eval.c -
    00004
    00005   $Author: yugui $
    00006   created at: Thu Jun 10 14:22:17 JST 1993
    00007
    00008   Copyright (C) 1993-2007 Yukihiro Matsumoto
    00009   Copyright (C) 2000  Network Applied Communication Laboratory, Inc.
    00010   Copyright (C) 2000  Information-technology Promotion Agency, Japan
    00011
    00012 **********************************************************************/
    00013
    00014 #include "eval_intern.h"
    00015 #include "iseq.h"
    00016 #include "gc.h"
    00017 #include "ruby/vm.h"
    00018 #include "ruby/encoding.h"
    00019
    00020 #define numberof(array) (int)(sizeof(array) / sizeof((array)[0]))
    00021
    00022 VALUE proc_invoke(VALUE, VALUE, VALUE, VALUE);
    00023 VALUE rb_binding_new(void);
    00024 NORETURN(void rb_raise_jump(VALUE));
    00025
    00026 ID rb_frame_callee(void);
    00027 VALUE rb_eLocalJumpError;
    00028 VALUE rb_eSysStackError;
    00029
    00030 #define exception_error GET_VM()->special_exceptions[ruby_error_reenter]
    00031
    00032 #include "eval_error.c"
    00033 #include "eval_jump.c"
    00034
    00035 /* initialize ruby */
    00036
    00037 void rb_clear_trace_func(void);
    00038 void rb_thread_stop_timer_thread(void);
    00039
    00040 void rb_call_inits(void);
    00041 void Init_heap(void);
    00042 void Init_BareVM(void);
    00043
    00044 void
    00045 ruby_init(void)
    00046 {
    00047     static int initialized = 0;
    00048     int state;
    00049
    00050     if (initialized)
    00051         return;
    00052     initialized = 1;
    00053
    00054     ruby_init_stack((void *)&state);
    00055     Init_BareVM();
    00056     Init_heap();
    00057
    00058     PUSH_TAG();
    00059     if ((state = EXEC_TAG()) == 0) {
    00060         rb_call_inits();
    00061         ruby_prog_init();
    00062     }
    00063     POP_TAG();
    00064
    00065     if (state) {
    00066         error_print();
    00067         exit(EXIT_FAILURE);
    00068     }
    00069     GET_VM()->running = 1;
    00070 }
    00071
    00072 extern void rb_clear_trace_func(void);
    00073
    00074 void *
    00075 ruby_options(int argc, char **argv)
    00076 {
    00077     int state;
    00078     void *volatile iseq = 0;
    00079
    00080     ruby_init_stack((void *)&iseq);
    00081     PUSH_TAG();
    00082     if ((state = EXEC_TAG()) == 0) {
    00083         SAVE_ROOT_JMPBUF(GET_THREAD(), iseq = ruby_process_options(argc, argv));
    00084     }
    00085     else {
    00086         rb_clear_trace_func();
    00087         state = error_handle(state);
    00088         iseq = (void *)INT2FIX(state);
    00089     }
    00090     POP_TAG();
    00091     return iseq;
    00092 }
    00093
    00094 static void
    00095 ruby_finalize_0(void)
    00096 {
    00097     PUSH_TAG();
    00098     if (EXEC_TAG() == 0) {
    00099         rb_trap_exit();
    00100     }
    00101     POP_TAG();
    00102     rb_exec_end_proc();
    00103     rb_clear_trace_func();
    00104 }
    00105
    00106 static void
    00107 ruby_finalize_1(void)
    00108 {
    00109     ruby_sig_finalize();
    00110     GET_THREAD()->errinfo = Qnil;
    00111     rb_gc_call_finalizer_at_exit();
    00112 }
    00113
    00114 void
    00115 ruby_finalize(void)
    00116 {
    00117     ruby_finalize_0();
    00118     ruby_finalize_1();
    00119 }
    00120
    00121 void rb_thread_stop_timer_thread(void);
    00122
    00123 int
    00124 ruby_cleanup(volatile int ex)
    00125 {
    00126     int state;
    00127     volatile VALUE errs[2];
    00128     rb_thread_t *th = GET_THREAD();
    00129     int nerr;
    00130     void rb_threadptr_interrupt(rb_thread_t *th);
    00131     void rb_threadptr_check_signal(rb_thread_t *mth);
    00132
    00133     rb_threadptr_interrupt(th);
    00134     rb_threadptr_check_signal(th);
    00135     PUSH_TAG();
    00136     if ((state = EXEC_TAG()) == 0) {
    00137         SAVE_ROOT_JMPBUF(th, { RUBY_VM_CHECK_INTS(); });
    00138     }
    00139     POP_TAG();
    00140
    00141     errs[1] = th->errinfo;
    00142     th->safe_level = 0;
    00143     ruby_init_stack(&errs[STACK_UPPER(errs, 0, 1)]);
    00144
    00145     PUSH_TAG();
    00146     if ((state = EXEC_TAG()) == 0) {
    00147         SAVE_ROOT_JMPBUF(th, ruby_finalize_0());
    00148     }
    00149     POP_TAG();
    00150
    00151     errs[0] = th->errinfo;
    00152     PUSH_TAG();
    00153     if ((state = EXEC_TAG()) == 0) {
    00154         SAVE_ROOT_JMPBUF(th, rb_thread_terminate_all());
    00155     }
    00156     else if (ex == 0) {
    00157         ex = state;
    00158     }
    00159     th->errinfo = errs[1];
    00160     ex = error_handle(ex);
    00161     ruby_finalize_1();
    00162     POP_TAG();
    00163     rb_thread_stop_timer_thread();
    00164
    00165     state = 0;
    00166     for (nerr = 0; nerr < numberof(errs); ++nerr) {
    00167         VALUE err = errs[nerr];
    00168
    00169         if (!RTEST(err)) continue;
    00170
    00171         /* th->errinfo contains a NODE while break'ing */
    00172         if (TYPE(err) == T_NODE) continue;
    00173
    00174         if (rb_obj_is_kind_of(err, rb_eSystemExit)) {
    00175             return sysexit_status(err);
    00176         }
    00177         else if (rb_obj_is_kind_of(err, rb_eSignal)) {
    00178             VALUE sig = rb_iv_get(err, "signo");
    00179             state = NUM2INT(sig);
    00180             break;
    00181         }
    00182         else if (ex == 0) {
    00183             ex = 1;
    00184         }
    00185     }
    00186     ruby_vm_destruct(GET_VM());
    00187     if (state) ruby_default_signal(state);
    00188
    00189 #if EXIT_SUCCESS != 0 || EXIT_FAILURE != 1
    00190     switch (ex) {
    00191 #if EXIT_SUCCESS != 0
    00192       case 0: return EXIT_SUCCESS;
    00193 #endif
    00194 #if EXIT_FAILURE != 1
    00195       case 1: return EXIT_FAILURE;
    00196 #endif
    00197     }
    00198 #endif
    00199
    00200     return ex;
    00201 }
    00202
    00203 static int
    00204 ruby_exec_internal(void *n)
    00205 {
    00206     volatile int state;
    00207     VALUE iseq = (VALUE)n;
    00208     rb_thread_t *th = GET_THREAD();
    00209
    00210     if (!n) return 0;
    00211
    00212     PUSH_TAG();
    00213     if ((state = EXEC_TAG()) == 0) {
    00214         SAVE_ROOT_JMPBUF(th, {
    00215             th->base_block = 0;
    00216             rb_iseq_eval_main(iseq);
    00217         });
    00218     }
    00219     POP_TAG();
    00220     return state;
    00221 }
    00222
    00223 void
    00224 ruby_stop(int ex)
    00225 {
    00226     exit(ruby_cleanup(ex));
    00227 }
    00228
    00229 int
    00230 ruby_executable_node(void *n, int *status)
    00231 {
    00232     VALUE v = (VALUE)n;
    00233     int s;
    00234
    00235     switch (v) {
    00236       case Qtrue:  s = EXIT_SUCCESS; break;
    00237       case Qfalse: s = EXIT_FAILURE; break;
    00238       default:
    00239         if (!FIXNUM_P(v)) return TRUE;
    00240         s = FIX2INT(v);
    00241     }
    00242     if (status) *status = s;
    00243     return FALSE;
    00244 }
    00245
    00246 int
    00247 ruby_run_node(void *n)
    00248 {
    00249     int status;
    00250     if (!ruby_executable_node(n, &status)) {
    00251         ruby_cleanup(0);
    00252         return status;
    00253     }
    00254     return ruby_cleanup(ruby_exec_node(n));
    00255 }
    00256
    00257 int
    00258 ruby_exec_node(void *n)
    00259 {
    00260     ruby_init_stack((void *)&n);
    00261     return ruby_exec_internal(n);
    00262 }
    00263
    00264 /*
    00265  *  call-seq:
    00266  *     Module.nesting    -> array
    00267  *
    00268  *  Returns the list of +Modules+ nested at the point of call.
    00269  *
    00270  *     module M1
    00271  *       module M2
    00272  *         $a = Module.nesting
    00273  *       end
    00274  *     end
    00275  *     $a           #=> [M1::M2, M1]
    00276  *     $a[0].name   #=> "M1::M2"
    00277  */
    00278
    00279 static VALUE
    00280 rb_mod_nesting(void)
    00281 {
    00282     VALUE ary = rb_ary_new();
    00283     const NODE *cref = rb_vm_cref();
    00284
    00285     while (cref && cref->nd_next) {
    00286         VALUE klass = cref->nd_clss;
    00287         if (!(cref->flags & NODE_FL_CREF_PUSHED_BY_EVAL) &&
    00288             !NIL_P(klass)) {
    00289             rb_ary_push(ary, klass);
    00290         }
    00291         cref = cref->nd_next;
    00292     }
    00293     return ary;
    00294 }
    00295
    00296 /*
    00297  *  call-seq:
    00298  *     Module.constants   -> array
    00299  *
    00300  *  Returns an array of the names of all constants defined in the
    00301  *  system. This list includes the names of all modules and classes.
    00302  *
    00303  *     p Module.constants.sort[1..5]
    00304  *
    00305  *  <em>produces:</em>
    00306  *
    00307  *     ["ARGV", "ArgumentError", "Array", "Bignum", "Binding"]
    00308  */
    00309
    00310 static VALUE
    00311 rb_mod_s_constants(int argc, VALUE *argv, VALUE mod)
    00312 {
    00313     const NODE *cref = rb_vm_cref();
    00314     VALUE klass;
    00315     VALUE cbase = 0;
    00316     void *data = 0;
    00317
    00318     if (argc > 0) {
    00319         return rb_mod_constants(argc, argv, rb_cModule);
    00320     }
    00321
    00322     while (cref) {
    00323         klass = cref->nd_clss;
    00324         if (!NIL_P(klass)) {
    00325             data = rb_mod_const_at(cref->nd_clss, data);
    00326             if (!cbase) {
    00327                 cbase = klass;
    00328             }
    00329         }
    00330         cref = cref->nd_next;
    00331     }
    00332
    00333     if (cbase) {
    00334         data = rb_mod_const_of(cbase, data);
    00335     }
    00336     return rb_const_list(data);
    00337 }
    00338
    00339 void
    00340 rb_frozen_class_p(VALUE klass)
    00341 {
    00342     const char *desc = "something(?!)";
    00343
    00344     if (OBJ_FROZEN(klass)) {
    00345         if (FL_TEST(klass, FL_SINGLETON))
    00346             desc = "object";
    00347         else {
    00348             switch (TYPE(klass)) {
    00349               case T_MODULE:
    00350               case T_ICLASS:
    00351                 desc = "module";
    00352                 break;
    00353               case T_CLASS:
    00354                 desc = "class";
    00355                 break;
    00356             }
    00357         }
    00358         rb_error_frozen(desc);
    00359     }
    00360 }
    00361
    00362 NORETURN(static void rb_longjmp(int, volatile VALUE));
    00363
    00364 static void
    00365 setup_exception(rb_thread_t *th, int tag, volatile VALUE mesg)
    00366 {
    00367     VALUE at;
    00368     VALUE e;
    00369     const char *file;
    00370     volatile int line = 0;
    00371
    00372     if (NIL_P(mesg))
    00373         mesg = th->errinfo;
    00374     if (NIL_P(mesg)) {
    00375         mesg = rb_exc_new(rb_eRuntimeError, 0, 0);
    00376     }
    00377
    00378     file = rb_sourcefile();
    00379     if (file) line = rb_sourceline();
    00380     if (file && !NIL_P(mesg)) {
    00381         if (mesg == sysstack_error) {
    00382             at = rb_enc_sprintf(rb_usascii_encoding(), "%s:%d", file, line);
    00383             at = rb_ary_new3(1, at);
    00384             rb_iv_set(mesg, "bt", at);
    00385         }
    00386         else {
    00387             at = get_backtrace(mesg);
    00388             if (NIL_P(at)) {
    00389                 at = rb_make_backtrace();
    00390                 if (OBJ_FROZEN(mesg)) {
    00391                     mesg = rb_obj_dup(mesg);
    00392                 }
    00393                 set_backtrace(mesg, at);
    00394             }
    00395         }
    00396     }
    00397     if (!NIL_P(mesg)) {
    00398         th->errinfo = mesg;
    00399     }
    00400
    00401     if (RTEST(ruby_debug) && !NIL_P(e = th->errinfo) &&
    00402         !rb_obj_is_kind_of(e, rb_eSystemExit)) {
    00403         int status;
    00404
    00405         PUSH_TAG();
    00406         if ((status = EXEC_TAG()) == 0) {
    00407             RB_GC_GUARD(e) = rb_obj_as_string(e);
    00408             if (file && line) {
    00409                 warn_printf("Exception `%s' at %s:%d - %s\n",
    00410                             rb_obj_classname(th->errinfo),
    00411                             file, line, RSTRING_PTR(e));
    00412             }
    00413             else if (file) {
    00414                 warn_printf("Exception `%s' at %s - %s\n",
    00415                             rb_obj_classname(th->errinfo),
    00416                             file, RSTRING_PTR(e));
    00417             }
    00418             else {
    00419                 warn_printf("Exception `%s' - %s\n",
    00420                             rb_obj_classname(th->errinfo),
    00421                             RSTRING_PTR(e));
    00422             }
    00423         }
    00424         POP_TAG();
    00425         if (status == TAG_FATAL && th->errinfo == exception_error) {
    00426             th->errinfo = mesg;
    00427         }
    00428         else if (status) {
    00429             rb_threadptr_reset_raised(th);
    00430             JUMP_TAG(status);
    00431         }
    00432     }
    00433
    00434     if (rb_threadptr_set_raised(th)) {
    00435         th->errinfo = exception_error;
    00436         rb_threadptr_reset_raised(th);
    00437         JUMP_TAG(TAG_FATAL);
    00438     }
    00439
    00440     rb_trap_restore_mask();
    00441
    00442     if (tag != TAG_FATAL) {
    00443         EXEC_EVENT_HOOK(th, RUBY_EVENT_RAISE, th->cfp->self, 0, 0);
    00444     }
    00445 }
    00446
    00447 static void
    00448 rb_longjmp(int tag, volatile VALUE mesg)
    00449 {
    00450     rb_thread_t *th = GET_THREAD();
    00451     setup_exception(th, tag, mesg);
    00452     rb_thread_raised_clear(th);
    00453     JUMP_TAG(tag);
    00454 }
    00455
    00456 static VALUE make_exception(int argc, VALUE *argv, int isstr);
    00457
    00458 void
    00459 rb_exc_raise(VALUE mesg)
    00460 {
    00461     if (!NIL_P(mesg)) {
    00462         mesg = make_exception(1, &mesg, FALSE);
    00463     }
    00464     rb_longjmp(TAG_RAISE, mesg);
    00465 }
    00466
    00467 void
    00468 rb_exc_fatal(VALUE mesg)
    00469 {
    00470     if (!NIL_P(mesg)) {
    00471         mesg = make_exception(1, &mesg, FALSE);
    00472     }
    00473     rb_longjmp(TAG_FATAL, mesg);
    00474 }
    00475
    00476 void
    00477 rb_interrupt(void)
    00478 {
    00479     rb_raise(rb_eInterrupt, "%s", "");
    00480 }
    00481
    00482 static VALUE get_errinfo(void);
    00483
    00484 /*
    00485  *  call-seq:
    00486  *     raise
    00487  *     raise(string)
    00488  *     raise(exception [, string [, array]])
    00489  *     fail
    00490  *     fail(string)
    00491  *     fail(exception [, string [, array]])
    00492  *
    00493  *  With no arguments, raises the exception in <code>$!</code> or raises
    00494  *  a <code>RuntimeError</code> if <code>$!</code> is +nil+.
    00495  *  With a single +String+ argument, raises a
    00496  *  +RuntimeError+ with the string as a message. Otherwise,
    00497  *  the first parameter should be the name of an +Exception+
    00498  *  class (or an object that returns an +Exception+ object when sent
    00499  *  an +exception+ message). The optional second parameter sets the
    00500  *  message associated with the exception, and the third parameter is an
    00501  *  array of callback information. Exceptions are caught by the
    00502  *  +rescue+ clause of <code>begin...end</code> blocks.
    00503  *
    00504  *     raise "Failed to create socket"
    00505  *     raise ArgumentError, "No parameters", caller
    00506  */
    00507
    00508 static VALUE
    00509 rb_f_raise(int argc, VALUE *argv)
    00510 {
    00511     VALUE err;
    00512     if (argc == 0) {
    00513         err = get_errinfo();
    00514         if (!NIL_P(err)) {
    00515             argc = 1;
    00516             argv = &err;
    00517         }
    00518     }
    00519     rb_raise_jump(rb_make_exception(argc, argv));
    00520     return Qnil;                /* not reached */
    00521 }
    00522
    00523 static VALUE
    00524 make_exception(int argc, VALUE *argv, int isstr)
    00525 {
    00526     VALUE mesg;
    00527     ID exception;
    00528     int n;
    00529
    00530     mesg = Qnil;
    00531     switch (argc) {
    00532       case 0:
    00533         break;
    00534       case 1:
    00535         if (NIL_P(argv[0]))
    00536             break;
    00537         if (isstr) {
    00538             mesg = rb_check_string_type(argv[0]);
    00539             if (!NIL_P(mesg)) {
    00540                 mesg = rb_exc_new3(rb_eRuntimeError, mesg);
    00541                 break;
    00542             }
    00543         }
    00544         n = 0;
    00545         goto exception_call;
    00546
    00547       case 2:
    00548       case 3:
    00549         n = 1;
    00550       exception_call:
    00551         if (argv[0] == sysstack_error) return argv[0];
    00552         CONST_ID(exception, "exception");
    00553         mesg = rb_check_funcall(argv[0], exception, n, argv+1);
    00554         if (mesg == Qundef) {
    00555             rb_raise(rb_eTypeError, "exception class/object expected");
    00556         }
    00557         break;
    00558       default:
    00559         rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..3)", argc);
    00560         break;
    00561     }
    00562     if (argc > 0) {
    00563         if (!rb_obj_is_kind_of(mesg, rb_eException))
    00564             rb_raise(rb_eTypeError, "exception object expected");
    00565         if (argc > 2)
    00566             set_backtrace(mesg, argv[2]);
    00567     }
    00568
    00569     return mesg;
    00570 }
    00571
    00572 VALUE
    00573 rb_make_exception(int argc, VALUE *argv)
    00574 {
    00575     return make_exception(argc, argv, TRUE);
    00576 }
    00577
    00578 void
    00579 rb_raise_jump(VALUE mesg)
    00580 {
    00581     rb_thread_t *th = GET_THREAD();
    00582     rb_control_frame_t *cfp = th->cfp;
    00583     VALUE klass = cfp->me->klass;
    00584     VALUE self = cfp->self;
    00585     ID mid = cfp->me->called_id;
    00586
    00587     th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp);
    00588
    00589     setup_exception(th, TAG_RAISE, mesg);
    00590
    00591     EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, self, mid, klass);
    00592     rb_thread_raised_clear(th);
    00593     JUMP_TAG(TAG_RAISE);
    00594 }
    00595
    00596 void
    00597 rb_jump_tag(int tag)
    00598 {
    00599     JUMP_TAG(tag);
    00600 }
    00601
    00602 int
    00603 rb_block_given_p(void)
    00604 {
    00605     rb_thread_t *th = GET_THREAD();
    00606
    00607     if ((th->cfp->lfp[0] & 0x02) == 0 &&
    00608         GC_GUARDED_PTR_REF(th->cfp->lfp[0])) {
    00609         return TRUE;
    00610     }
    00611     else {
    00612         return FALSE;
    00613     }
    00614 }
    00615
    00616 int
    00617 rb_iterator_p(void)
    00618 {
    00619     return rb_block_given_p();
    00620 }
    00621
    00622 VALUE rb_eThreadError;
    00623
    00624 void
    00625 rb_need_block(void)
    00626 {
    00627     if (!rb_block_given_p()) {
    00628         rb_vm_localjump_error("no block given", Qnil, 0);
    00629     }
    00630 }
    00631
    00632 VALUE
    00633 rb_rescue2(VALUE (* b_proc) (ANYARGS), VALUE data1,
    00634            VALUE (* r_proc) (ANYARGS), VALUE data2, ...)
    00635 {
    00636     int state;
    00637     rb_thread_t *th = GET_THREAD();
    00638     rb_control_frame_t *cfp = th->cfp;
    00639     volatile VALUE result;
    00640     volatile VALUE e_info = th->errinfo;
    00641     va_list args;
    00642
    00643     PUSH_TAG();
    00644     if ((state = EXEC_TAG()) == 0) {
    00645       retry_entry:
    00646         result = (*b_proc) (data1);
    00647     }
    00648     else {
    00649         th->cfp = cfp; /* restore */
    00650
    00651         if (state == TAG_RAISE) {
    00652             int handle = FALSE;
    00653             VALUE eclass;
    00654
    00655             va_init_list(args, data2);
    00656             while ((eclass = va_arg(args, VALUE)) != 0) {
    00657                 if (rb_obj_is_kind_of(th->errinfo, eclass)) {
    00658                     handle = TRUE;
    00659                     break;
    00660                 }
    00661             }
    00662             va_end(args);
    00663
    00664             if (handle) {
    00665                 if (r_proc) {
    00666                     PUSH_TAG();
    00667                     if ((state = EXEC_TAG()) == 0) {
    00668                         result = (*r_proc) (data2, th->errinfo);
    00669                     }
    00670                     POP_TAG();
    00671                     if (state == TAG_RETRY) {
    00672                         state = 0;
    00673                         th->errinfo = Qnil;
    00674                         goto retry_entry;
    00675                     }
    00676                 }
    00677                 else {
    00678                     result = Qnil;
    00679                     state = 0;
    00680                 }
    00681                 if (state == 0) {
    00682                     th->errinfo = e_info;
    00683                 }
    00684             }
    00685         }
    00686     }
    00687     POP_TAG();
    00688     if (state)
    00689         JUMP_TAG(state);
    00690
    00691     return result;
    00692 }
    00693
    00694 VALUE
    00695 rb_rescue(VALUE (* b_proc)(ANYARGS), VALUE data1,
    00696           VALUE (* r_proc)(ANYARGS), VALUE data2)
    00697 {
    00698     return rb_rescue2(b_proc, data1, r_proc, data2, rb_eStandardError,
    00699                       (VALUE)0);
    00700 }
    00701
    00702 VALUE
    00703 rb_protect(VALUE (* proc) (VALUE), VALUE data, int * state)
    00704 {
    00705     volatile VALUE result = Qnil;
    00706     int status;
    00707     rb_thread_t *th = GET_THREAD();
    00708     rb_control_frame_t *cfp = th->cfp;
    00709     struct rb_vm_protect_tag protect_tag;
    00710     rb_jmpbuf_t org_jmpbuf;
    00711
    00712     protect_tag.prev = th->protect_tag;
    00713
    00714     PUSH_TAG();
    00715     th->protect_tag = &protect_tag;
    00716     MEMCPY(&org_jmpbuf, &(th)->root_jmpbuf, rb_jmpbuf_t, 1);
    00717     if ((status = EXEC_TAG()) == 0) {
    00718         SAVE_ROOT_JMPBUF(th, result = (*proc) (data));
    00719     }
    00720     MEMCPY(&(th)->root_jmpbuf, &org_jmpbuf, rb_jmpbuf_t, 1);
    00721     th->protect_tag = protect_tag.prev;
    00722     POP_TAG();
    00723
    00724     if (state) {
    00725         *state = status;
    00726     }
    00727     if (status != 0) {
    00728         th->cfp = cfp;
    00729         return Qnil;
    00730     }
    00731
    00732     return result;
    00733 }
    00734
    00735 VALUE
    00736 rb_ensure(VALUE (*b_proc)(ANYARGS), VALUE data1, VALUE (*e_proc)(ANYARGS), VALUE data2)
    00737 {
    00738     int state;
    00739     volatile VALUE result = Qnil;
    00740
    00741     PUSH_TAG();
    00742     if ((state = EXEC_TAG()) == 0) {
    00743         result = (*b_proc) (data1);
    00744     }
    00745     POP_TAG();
    00746     /* TODO: fix me */
    00747     /* retval = prot_tag ? prot_tag->retval : Qnil; */     /* save retval */
    00748     (*e_proc) (data2);
    00749     if (state)
    00750         JUMP_TAG(state);
    00751     return result;
    00752 }
    00753
    00754 static ID
    00755 frame_func_id(rb_control_frame_t *cfp)
    00756 {
    00757     rb_iseq_t *iseq = cfp->iseq;
    00758     if (!iseq) {
    00759         return cfp->me->def->original_id;
    00760     }
    00761     while (iseq) {
    00762         if (RUBY_VM_IFUNC_P(iseq)) {
    00763             return rb_intern("<ifunc>");
    00764         }
    00765         if (iseq->defined_method_id) {
    00766             return iseq->defined_method_id;
    00767         }
    00768         if (iseq->local_iseq == iseq) {
    00769             break;
    00770         }
    00771         iseq = iseq->parent_iseq;
    00772     }
    00773     return 0;
    00774 }
    00775
    00776 ID
    00777 rb_frame_this_func(void)
    00778 {
    00779     return frame_func_id(GET_THREAD()->cfp);
    00780 }
    00781
    00782 ID
    00783 rb_frame_callee(void)
    00784 {
    00785     return frame_func_id(GET_THREAD()->cfp);
    00786 }
    00787
    00788 static ID
    00789 rb_frame_caller(void)
    00790 {
    00791     rb_thread_t *th = GET_THREAD();
    00792     rb_control_frame_t *prev_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp);
    00793     /* check if prev_cfp can be accessible */
    00794     if ((void *)(th->stack + th->stack_size) == (void *)(prev_cfp)) {
    00795         return 0;
    00796     }
    00797     return frame_func_id(prev_cfp);
    00798 }
    00799
    00800 void
    00801 rb_frame_pop(void)
    00802 {
    00803     rb_thread_t *th = GET_THREAD();
    00804     th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp);
    00805 }
    00806
    00807 /*
    00808  *  call-seq:
    00809  *     append_features(mod)   -> mod
    00810  *
    00811  *  When this module is included in another, Ruby calls
    00812  *  <code>append_features</code> in this module, passing it the
    00813  *  receiving module in _mod_. Ruby's default implementation is
    00814  *  to add the constants, methods, and module variables of this module
    00815  *  to _mod_ if this module has not already been added to
    00816  *  _mod_ or one of its ancestors. See also <code>Module#include</code>.
    00817  */
    00818
    00819 static VALUE
    00820 rb_mod_append_features(VALUE module, VALUE include)
    00821 {
    00822     switch (TYPE(include)) {
    00823       case T_CLASS:
    00824       case T_MODULE:
    00825         break;
    00826       default:
    00827         Check_Type(include, T_CLASS);
    00828         break;
    00829     }
    00830     rb_include_module(include, module);
    00831
    00832     return module;
    00833 }
    00834
    00835 /*
    00836  *  call-seq:
    00837  *     include(module, ...)    -> self
    00838  *
    00839  *  Invokes <code>Module.append_features</code> on each parameter in reverse order.
    00840  */
    00841
    00842 static VALUE
    00843 rb_mod_include(int argc, VALUE *argv, VALUE module)
    00844 {
    00845     int i;
    00846
    00847     for (i = 0; i < argc; i++)
    00848         Check_Type(argv[i], T_MODULE);
    00849     while (argc--) {
    00850         rb_funcall(argv[argc], rb_intern("append_features"), 1, module);
    00851         rb_funcall(argv[argc], rb_intern("included"), 1, module);
    00852     }
    00853     return module;
    00854 }
    00855
    00856 void
    00857 rb_obj_call_init(VALUE obj, int argc, VALUE *argv)
    00858 {
    00859     PASS_PASSED_BLOCK();
    00860     rb_funcall2(obj, idInitialize, argc, argv);
    00861 }
    00862
    00863 void
    00864 rb_extend_object(VALUE obj, VALUE module)
    00865 {
    00866     rb_include_module(rb_singleton_class(obj), module);
    00867 }
    00868
    00869 /*
    00870  *  call-seq:
    00871  *     extend_object(obj)    -> obj
    00872  *
    00873  *  Extends the specified object by adding this module's constants and
    00874  *  methods (which are added as singleton methods). This is the callback
    00875  *  method used by <code>Object#extend</code>.
    00876  *
    00877  *     module Picky
    00878  *       def Picky.extend_object(o)
    00879  *         if String === o
    00880  *           puts "Can't add Picky to a String"
    00881  *         else
    00882  *           puts "Picky added to #{o.class}"
    00883  *           super
    00884  *         end
    00885  *       end
    00886  *     end
    00887  *     (s = Array.new).extend Picky  # Call Object.extend
    00888  *     (s = "quick brown fox").extend Picky
    00889  *
    00890  *  <em>produces:</em>
    00891  *
    00892  *     Picky added to Array
    00893  *     Can't add Picky to a String
    00894  */
    00895
    00896 static VALUE
    00897 rb_mod_extend_object(VALUE mod, VALUE obj)
    00898 {
    00899     rb_extend_object(obj, mod);
    00900     return obj;
    00901 }
    00902
    00903 /*
    00904  *  call-seq:
    00905  *     obj.extend(module, ...)    -> obj
    00906  *
    00907  *  Adds to _obj_ the instance methods from each module given as a
    00908  *  parameter.
    00909  *
    00910  *     module Mod
    00911  *       def hello
    00912  *         "Hello from Mod.\n"
    00913  *       end
    00914  *     end
    00915  *
    00916  *     class Klass
    00917  *       def hello
    00918  *         "Hello from Klass.\n"
    00919  *       end
    00920  *     end
    00921  *
    00922  *     k = Klass.new
    00923  *     k.hello         #=> "Hello from Klass.\n"
    00924  *     k.extend(Mod)   #=> #<Klass:0x401b3bc8>
    00925  *     k.hello         #=> "Hello from Mod.\n"
    00926  */
    00927
    00928 static VALUE
    00929 rb_obj_extend(int argc, VALUE *argv, VALUE obj)
    00930 {
    00931     int i;
    00932
    00933     if (argc == 0) {
    00934         rb_raise(rb_eArgError, "wrong number of arguments (at least 1)");
    00935     }
    00936     for (i = 0; i < argc; i++)
    00937         Check_Type(argv[i], T_MODULE);
    00938     while (argc--) {
    00939         rb_funcall(argv[argc], rb_intern("extend_object"), 1, obj);
    00940         rb_funcall(argv[argc], rb_intern("extended"), 1, obj);
    00941     }
    00942     return obj;
    00943 }
    00944
    00945 /*
    00946  *  call-seq:
    00947  *     include(module, ...)   -> self
    00948  *
    00949  *  Invokes <code>Module.append_features</code>
    00950  *  on each parameter in turn. Effectively adds the methods and constants
    00951  *  in each module to the receiver.
    00952  */
    00953
    00954 static VALUE
    00955 top_include(int argc, VALUE *argv, VALUE self)
    00956 {
    00957     rb_thread_t *th = GET_THREAD();
    00958
    00959     rb_secure(4);
    00960     if (th->top_wrapper) {
    00961         rb_warning
    00962             ("main#include in the wrapped load is effective only in wrapper module");
    00963         return rb_mod_include(argc, argv, th->top_wrapper);
    00964     }
    00965     return rb_mod_include(argc, argv, rb_cObject);
    00966 }
    00967
    00968 VALUE rb_f_trace_var();
    00969 VALUE rb_f_untrace_var();
    00970
    00971 static VALUE *
    00972 errinfo_place(rb_thread_t *th)
    00973 {
    00974     rb_control_frame_t *cfp = th->cfp;
    00975     rb_control_frame_t *end_cfp = RUBY_VM_END_CONTROL_FRAME(th);
    00976
    00977     while (RUBY_VM_VALID_CONTROL_FRAME_P(cfp, end_cfp)) {
    00978         if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
    00979             if (cfp->iseq->type == ISEQ_TYPE_RESCUE) {
    00980                 return &cfp->dfp[-2];
    00981             }
    00982             else if (cfp->iseq->type == ISEQ_TYPE_ENSURE &&
    00983                      TYPE(cfp->dfp[-2]) != T_NODE &&
    00984                      !FIXNUM_P(cfp->dfp[-2])) {
    00985                 return &cfp->dfp[-2];
    00986             }
    00987         }
    00988         cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
    00989     }
    00990     return 0;
    00991 }
    00992
    00993 static VALUE
    00994 get_thread_errinfo(rb_thread_t *th)
    00995 {
    00996     VALUE *ptr = errinfo_place(th);
    00997     if (ptr) {
    00998         return *ptr;
    00999     }
    01000     else {
    01001         return th->errinfo;
    01002     }
    01003 }
    01004
    01005 static VALUE
    01006 get_errinfo(void)
    01007 {
    01008     return get_thread_errinfo(GET_THREAD());
    01009 }
    01010
    01011 static VALUE
    01012 errinfo_getter(ID id)
    01013 {
    01014     return get_errinfo();
    01015 }
    01016
    01017 #if 0
    01018 static void
    01019 errinfo_setter(VALUE val, ID id, VALUE *var)
    01020 {
    01021     if (!NIL_P(val) && !rb_obj_is_kind_of(val, rb_eException)) {
    01022         rb_raise(rb_eTypeError, "assigning non-exception to $!");
    01023     }
    01024     else {
    01025         VALUE *ptr = errinfo_place(GET_THREAD());
    01026         if (ptr) {
    01027             *ptr = val;
    01028         }
    01029         else {
    01030             rb_raise(rb_eRuntimeError, "errinfo_setter: not in rescue clause.");
    01031         }
    01032     }
    01033 }
    01034 #endif
    01035
    01036 VALUE
    01037 rb_errinfo(void)
    01038 {
    01039     rb_thread_t *th = GET_THREAD();
    01040     return th->errinfo;
    01041 }
    01042
    01043 void
    01044 rb_set_errinfo(VALUE err)
    01045 {
    01046     if (!NIL_P(err) && !rb_obj_is_kind_of(err, rb_eException)) {
    01047         rb_raise(rb_eTypeError, "assigning non-exception to $!");
    01048     }
    01049     GET_THREAD()->errinfo = err;
    01050 }
    01051
    01052 VALUE
    01053 rb_rubylevel_errinfo(void)
    01054 {
    01055     return get_errinfo();
    01056 }
    01057
    01058 static VALUE
    01059 errat_getter(ID id)
    01060 {
    01061     VALUE err = get_errinfo();
    01062     if (!NIL_P(err)) {
    01063         return get_backtrace(err);
    01064     }
    01065     else {
    01066         return Qnil;
    01067     }
    01068 }
    01069
    01070 static void
    01071 errat_setter(VALUE val, ID id, VALUE *var)
    01072 {
    01073     VALUE err = get_errinfo();
    01074     if (NIL_P(err)) {
    01075         rb_raise(rb_eArgError, "$! not set");
    01076     }
    01077     set_backtrace(err, val);
    01078 }
    01079
    01080 /*
    01081  *  call-seq:
    01082  *     __method__         -> symbol
    01083  *     __callee__         -> symbol
    01084  *
    01085  *  Returns the name of the current method as a Symbol.
    01086  *  If called outside of a method, it returns <code>nil</code>.
    01087  *
    01088  */
    01089
    01090 static VALUE
    01091 rb_f_method_name(void)
    01092 {
    01093     ID fname = rb_frame_caller(); /* need *caller* ID */
    01094
    01095     if (fname) {
    01096         return ID2SYM(fname);
    01097     }
    01098     else {
    01099         return Qnil;
    01100     }
    01101 }
    01102
    01103 void
    01104 Init_eval(void)
    01105 {
    01106     rb_define_virtual_variable("$@", errat_getter, errat_setter);
    01107     rb_define_virtual_variable("$!", errinfo_getter, 0);
    01108
    01109     rb_define_global_function("raise", rb_f_raise, -1);
    01110     rb_define_global_function("fail", rb_f_raise, -1);
    01111
    01112     rb_define_global_function("global_variables", rb_f_global_variables, 0);    /* in variable.c */
    01113
    01114     rb_define_global_function("__method__", rb_f_method_name, 0);
    01115     rb_define_global_function("__callee__", rb_f_method_name, 0);
    01116
    01117     rb_define_private_method(rb_cModule, "append_features", rb_mod_append_features, 1);
    01118     rb_define_private_method(rb_cModule, "extend_object", rb_mod_extend_object, 1);
    01119     rb_define_private_method(rb_cModule, "include", rb_mod_include, -1);
    01120
    01121     rb_undef_method(rb_cClass, "module_function");
    01122
    01123     {
    01124         extern void Init_vm_eval(void);
    01125         extern void Init_eval_method(void);
    01126         Init_vm_eval();
    01127         Init_eval_method();
    01128     }
    01129
    01130     rb_define_singleton_method(rb_cModule, "nesting", rb_mod_nesting, 0);
    01131     rb_define_singleton_method(rb_cModule, "constants", rb_mod_s_constants, -1);
    01132
    01133     rb_define_singleton_method(rb_vm_top_self(), "include", top_include, -1);
    01134
    01135     rb_define_method(rb_mKernel, "extend", rb_obj_extend, -1);
    01136
    01137     rb_define_global_function("trace_var", rb_f_trace_var, -1); /* in variable.c */
    01138     rb_define_global_function("untrace_var", rb_f_untrace_var, -1);     /* in variable.c */
    01139
    01140     exception_error = rb_exc_new3(rb_eFatal,
    01141                                   rb_obj_freeze(rb_str_new2("exception reentered")));
    01142     OBJ_TAINT(exception_error);
    01143     OBJ_FREEZE(exception_error);
    01144 }
    01145