00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
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
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
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
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
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
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
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
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;
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;
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
00747
00748 (*e_proc) (data2);
00749 if (state)
00750 JUMP_TAG(state);
00751 return result;
00752 }
00753
00754 static const rb_method_entry_t *
00755 method_entry_of_iseq(rb_control_frame_t *cfp, rb_iseq_t *iseq)
00756 {
00757 rb_thread_t *th = GET_THREAD();
00758 rb_control_frame_t *cfp_limit;
00759
00760 cfp_limit = (rb_control_frame_t *)(th->stack + th->stack_size);
00761 while (cfp_limit > cfp) {
00762 if (cfp->iseq == iseq)
00763 return cfp->me;
00764 cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
00765 }
00766 return 0;
00767 }
00768
00769 static ID
00770 frame_func_id(rb_control_frame_t *cfp)
00771 {
00772 const rb_method_entry_t *me_local;
00773 rb_iseq_t *iseq = cfp->iseq;
00774 if (cfp->me) {
00775 return cfp->me->def->original_id;
00776 }
00777 while (iseq) {
00778 if (RUBY_VM_IFUNC_P(iseq)) {
00779 return rb_intern("<ifunc>");
00780 }
00781 me_local = method_entry_of_iseq(cfp, iseq);
00782 if (me_local) {
00783 cfp->me = me_local;
00784 return me_local->def->original_id;
00785 }
00786 if (iseq->defined_method_id) {
00787 return iseq->defined_method_id;
00788 }
00789 if (iseq->local_iseq == iseq) {
00790 break;
00791 }
00792 iseq = iseq->parent_iseq;
00793 }
00794 return 0;
00795 }
00796
00797 ID
00798 rb_frame_this_func(void)
00799 {
00800 return frame_func_id(GET_THREAD()->cfp);
00801 }
00802
00803 ID
00804 rb_frame_callee(void)
00805 {
00806 return frame_func_id(GET_THREAD()->cfp);
00807 }
00808
00809 static ID
00810 rb_frame_caller(void)
00811 {
00812 rb_thread_t *th = GET_THREAD();
00813 rb_control_frame_t *prev_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp);
00814
00815 if ((void *)(th->stack + th->stack_size) == (void *)(prev_cfp)) {
00816 return 0;
00817 }
00818 return frame_func_id(prev_cfp);
00819 }
00820
00821 void
00822 rb_frame_pop(void)
00823 {
00824 rb_thread_t *th = GET_THREAD();
00825 th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp);
00826 }
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840 static VALUE
00841 rb_mod_append_features(VALUE module, VALUE include)
00842 {
00843 switch (TYPE(include)) {
00844 case T_CLASS:
00845 case T_MODULE:
00846 break;
00847 default:
00848 Check_Type(include, T_CLASS);
00849 break;
00850 }
00851 rb_include_module(include, module);
00852
00853 return module;
00854 }
00855
00856
00857
00858
00859
00860
00861
00862
00863 static VALUE
00864 rb_mod_include(int argc, VALUE *argv, VALUE module)
00865 {
00866 int i;
00867
00868 for (i = 0; i < argc; i++)
00869 Check_Type(argv[i], T_MODULE);
00870 while (argc--) {
00871 rb_funcall(argv[argc], rb_intern("append_features"), 1, module);
00872 rb_funcall(argv[argc], rb_intern("included"), 1, module);
00873 }
00874 return module;
00875 }
00876
00877 void
00878 rb_obj_call_init(VALUE obj, int argc, VALUE *argv)
00879 {
00880 PASS_PASSED_BLOCK();
00881 rb_funcall2(obj, idInitialize, argc, argv);
00882 }
00883
00884 void
00885 rb_extend_object(VALUE obj, VALUE module)
00886 {
00887 rb_include_module(rb_singleton_class(obj), module);
00888 }
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917 static VALUE
00918 rb_mod_extend_object(VALUE mod, VALUE obj)
00919 {
00920 rb_extend_object(obj, mod);
00921 return obj;
00922 }
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949 static VALUE
00950 rb_obj_extend(int argc, VALUE *argv, VALUE obj)
00951 {
00952 int i;
00953
00954 if (argc == 0) {
00955 rb_raise(rb_eArgError, "wrong number of arguments (at least 1)");
00956 }
00957 for (i = 0; i < argc; i++)
00958 Check_Type(argv[i], T_MODULE);
00959 while (argc--) {
00960 rb_funcall(argv[argc], rb_intern("extend_object"), 1, obj);
00961 rb_funcall(argv[argc], rb_intern("extended"), 1, obj);
00962 }
00963 return obj;
00964 }
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975 static VALUE
00976 top_include(int argc, VALUE *argv, VALUE self)
00977 {
00978 rb_thread_t *th = GET_THREAD();
00979
00980 rb_secure(4);
00981 if (th->top_wrapper) {
00982 rb_warning
00983 ("main#include in the wrapped load is effective only in wrapper module");
00984 return rb_mod_include(argc, argv, th->top_wrapper);
00985 }
00986 return rb_mod_include(argc, argv, rb_cObject);
00987 }
00988
00989 VALUE rb_f_trace_var();
00990 VALUE rb_f_untrace_var();
00991
00992 static VALUE *
00993 errinfo_place(rb_thread_t *th)
00994 {
00995 rb_control_frame_t *cfp = th->cfp;
00996 rb_control_frame_t *end_cfp = RUBY_VM_END_CONTROL_FRAME(th);
00997
00998 while (RUBY_VM_VALID_CONTROL_FRAME_P(cfp, end_cfp)) {
00999 if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
01000 if (cfp->iseq->type == ISEQ_TYPE_RESCUE) {
01001 return &cfp->dfp[-2];
01002 }
01003 else if (cfp->iseq->type == ISEQ_TYPE_ENSURE &&
01004 TYPE(cfp->dfp[-2]) != T_NODE &&
01005 !FIXNUM_P(cfp->dfp[-2])) {
01006 return &cfp->dfp[-2];
01007 }
01008 }
01009 cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
01010 }
01011 return 0;
01012 }
01013
01014 static VALUE
01015 get_thread_errinfo(rb_thread_t *th)
01016 {
01017 VALUE *ptr = errinfo_place(th);
01018 if (ptr) {
01019 return *ptr;
01020 }
01021 else {
01022 return th->errinfo;
01023 }
01024 }
01025
01026 static VALUE
01027 get_errinfo(void)
01028 {
01029 return get_thread_errinfo(GET_THREAD());
01030 }
01031
01032 static VALUE
01033 errinfo_getter(ID id)
01034 {
01035 return get_errinfo();
01036 }
01037
01038 #if 0
01039 static void
01040 errinfo_setter(VALUE val, ID id, VALUE *var)
01041 {
01042 if (!NIL_P(val) && !rb_obj_is_kind_of(val, rb_eException)) {
01043 rb_raise(rb_eTypeError, "assigning non-exception to $!");
01044 }
01045 else {
01046 VALUE *ptr = errinfo_place(GET_THREAD());
01047 if (ptr) {
01048 *ptr = val;
01049 }
01050 else {
01051 rb_raise(rb_eRuntimeError, "errinfo_setter: not in rescue clause.");
01052 }
01053 }
01054 }
01055 #endif
01056
01057 VALUE
01058 rb_errinfo(void)
01059 {
01060 rb_thread_t *th = GET_THREAD();
01061 return th->errinfo;
01062 }
01063
01064 void
01065 rb_set_errinfo(VALUE err)
01066 {
01067 if (!NIL_P(err) && !rb_obj_is_kind_of(err, rb_eException)) {
01068 rb_raise(rb_eTypeError, "assigning non-exception to $!");
01069 }
01070 GET_THREAD()->errinfo = err;
01071 }
01072
01073 VALUE
01074 rb_rubylevel_errinfo(void)
01075 {
01076 return get_errinfo();
01077 }
01078
01079 static VALUE
01080 errat_getter(ID id)
01081 {
01082 VALUE err = get_errinfo();
01083 if (!NIL_P(err)) {
01084 return get_backtrace(err);
01085 }
01086 else {
01087 return Qnil;
01088 }
01089 }
01090
01091 static void
01092 errat_setter(VALUE val, ID id, VALUE *var)
01093 {
01094 VALUE err = get_errinfo();
01095 if (NIL_P(err)) {
01096 rb_raise(rb_eArgError, "$! not set");
01097 }
01098 set_backtrace(err, val);
01099 }
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111 static VALUE
01112 rb_f_method_name(void)
01113 {
01114 ID fname = rb_frame_caller();
01115
01116 if (fname) {
01117 return ID2SYM(fname);
01118 }
01119 else {
01120 return Qnil;
01121 }
01122 }
01123
01124 void
01125 Init_eval(void)
01126 {
01127 rb_define_virtual_variable("$@", errat_getter, errat_setter);
01128 rb_define_virtual_variable("$!", errinfo_getter, 0);
01129
01130 rb_define_global_function("raise", rb_f_raise, -1);
01131 rb_define_global_function("fail", rb_f_raise, -1);
01132
01133 rb_define_global_function("global_variables", rb_f_global_variables, 0);
01134
01135 rb_define_global_function("__method__", rb_f_method_name, 0);
01136 rb_define_global_function("__callee__", rb_f_method_name, 0);
01137
01138 rb_define_private_method(rb_cModule, "append_features", rb_mod_append_features, 1);
01139 rb_define_private_method(rb_cModule, "extend_object", rb_mod_extend_object, 1);
01140 rb_define_private_method(rb_cModule, "include", rb_mod_include, -1);
01141
01142 rb_undef_method(rb_cClass, "module_function");
01143
01144 {
01145 extern void Init_vm_eval(void);
01146 extern void Init_eval_method(void);
01147 Init_vm_eval();
01148 Init_eval_method();
01149 }
01150
01151 rb_define_singleton_method(rb_cModule, "nesting", rb_mod_nesting, 0);
01152 rb_define_singleton_method(rb_cModule, "constants", rb_mod_s_constants, -1);
01153
01154 rb_define_singleton_method(rb_vm_top_self(), "include", top_include, -1);
01155
01156 rb_define_method(rb_mKernel, "extend", rb_obj_extend, -1);
01157
01158 rb_define_global_function("trace_var", rb_f_trace_var, -1);
01159 rb_define_global_function("untrace_var", rb_f_untrace_var, -1);
01160
01161 exception_error = rb_exc_new3(rb_eFatal,
01162 rb_obj_freeze(rb_str_new2("exception reentered")));
01163 OBJ_TAINT(exception_error);
01164 OBJ_FREEZE(exception_error);
01165 }
01166