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