6
$Date: 2007-06-06 10:57:36 +0900 (水, 06 6月 2007) $
6
$Date: 2007-08-25 12:29:39 +0900 (土, 25 8月 2007) $
7
7
created at: Thu Jun 10 14:22:17 JST 1993
9
Copyright (C) 1993-2003 Yukihiro Matsumoto
9
Copyright (C) 1993-2007 Yukihiro Matsumoto
10
10
Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
11
11
Copyright (C) 2000 Information-technology Promotion Agency, Japan
22
22
ID rb_frame_callee(void);
23
23
static VALUE rb_frame_self(void);
25
NODE *ruby_current_node;
27
25
static ID removed, singleton_removed, undefined, singleton_undefined;
28
26
static ID init, eqq, each, aref, aset, match, missing;
29
27
static ID added, singleton_added;
32
30
VALUE rb_eLocalJumpError;
33
31
VALUE rb_eSysStackError;
35
extern int ruby_nerrs;
36
extern VALUE ruby_top_self;
38
static VALUE eval(VALUE, VALUE, VALUE, char *, int);
34
static VALUE exception_error;
36
static VALUE eval(VALUE, VALUE, VALUE, const char *, int);
40
38
static inline VALUE rb_yield_0(int argc, VALUE *argv);
41
39
static VALUE rb_call(VALUE, VALUE, ID, int, const VALUE *, int);
43
#include "eval_error.h"
44
#include "eval_method.h"
45
#include "eval_safe.h"
46
#include "eval_jump.h"
41
#include "eval_error.ci"
42
#include "eval_method.ci"
43
#include "eval_safe.ci"
44
#include "eval_jump.ci"
48
46
/* initialize ruby */
57
55
jmp_buf function_call_may_return_twice_jmp_buf;
58
56
int function_call_may_return_twice_false = 0;
58
void rb_clear_trace_func(void);
59
void rb_thread_stop_timer_thread(void);
60
61
void rb_call_inits _((void));
61
62
void Init_stack _((VALUE *));
62
63
void Init_heap _((void));
63
64
void Init_ext _((void));
65
void Init_BareVM(void);
105
106
ruby_running = 1;
109
extern void rb_clear_trace_func(void);
109
112
ruby_options(int argc, char **argv)
113
117
Init_stack((void *)&state);
115
119
if ((state = EXEC_TAG()) == 0) {
116
SAVE_ROOT_JMPBUF(GET_THREAD(), ruby_process_options(argc, argv));
120
SAVE_ROOT_JMPBUF(GET_THREAD(), tree = ruby_process_options(argc, argv));
119
123
rb_clear_trace_func();
120
124
exit(error_handle(state));
191
197
VALUE sig = rb_iv_get(err, "signo");
192
198
ruby_default_signal(NUM2INT(sig));
205
#if EXIT_SUCCESS != 0 || EXIT_FAILURE != 1
207
#if EXIT_SUCCESS != 0
208
case 0: return EXIT_SUCCESS;
210
#if EXIT_FAILURE != 1
211
case 1: return EXIT_FAILURE;
199
extern NODE *ruby_eval_tree;
202
ruby_exec_internal(void)
220
ruby_exec_node(void *n, char *file)
206
225
rb_thread_t *th = GET_THREAD();
208
if (!ruby_eval_tree) return 0;
211
230
if ((state = EXEC_TAG()) == 0) {
212
231
SAVE_ROOT_JMPBUF(th, {
232
VALUE iseq = rb_iseq_new(n, rb_str_new2("<main>"),
233
rb_str_new2(file), Qfalse, ISEQ_TYPE_TOP);
213
234
th->base_block = 0;
214
val = yarvcore_eval_parsed(ruby_eval_tree, rb_str_new2(ruby_sourcefile));
235
val = rb_iseq_eval(iseq);
226
Init_stack((void *)&tmp);
227
return ruby_exec_internal();
231
243
ruby_stop(int ex)
233
245
exit(ruby_cleanup(ex));
249
ruby_run_node(void *n)
242
if (ruby_nerrs > 0) {
251
NODE *node = (NODE *)n;
255
Init_stack((void *)&n);
256
return ruby_cleanup(ruby_exec_node(node, node->nd_file));
255
260
rb_eval_string(const char *str)
258
NODE *oldsrc = ruby_current_node;
260
ruby_current_node = 0;
261
ruby_sourcefile = rb_source_filename("(eval)");
262
v = eval(ruby_top_self, rb_str_new2(str), Qnil, 0, 0);
263
ruby_current_node = oldsrc;
262
return eval(rb_vm_top_self(), rb_str_new2(str), Qnil, "(eval)", 1);
283
280
th->top_wrapper = rb_module_new();
284
th->top_self = rb_obj_clone(ruby_top_self);
281
th->top_self = rb_obj_clone(rb_vm_top_self());
285
282
rb_extend_object(th->top_self, th->top_wrapper);
287
284
val = rb_eval_string_protect(str, &status);
308
305
if (OBJ_TAINTED(cmd)) {
311
309
if (TYPE(cmd) != T_STRING) {
314
311
rb_set_safe_level_force(level);
315
312
if ((state = EXEC_TAG()) == 0) {
317
rb_funcall2(cmd, rb_intern("call"), RARRAY_LEN(arg),
313
val = rb_funcall2(cmd, rb_intern("call"), RARRAY_LEN(arg),
330
326
if ((state = EXEC_TAG()) == 0) {
331
val = eval(ruby_top_self, cmd, Qnil, 0, 0);
327
val = eval(rb_vm_top_self(), cmd, Qnil, 0, 0);
335
331
rb_set_safe_level_force(safe);
336
if (state) th_jump_tag_but_local_jump(state, val);
332
if (state) vm_jump_tag_but_local_jump(state, val);
650
NORETURN(void th_iter_break _((rb_thread_t *)));
655
th_iter_break(GET_THREAD());
658
NORETURN(static void rb_longjmp _((int, VALUE)));
659
static VALUE make_backtrace _((void));
646
NORETURN(static void rb_longjmp(int, VALUE));
647
static VALUE make_backtrace(void);
662
650
rb_longjmp(int tag, VALUE mesg)
665
654
rb_thread_t *th = GET_THREAD();
667
658
if (thread_set_raised(th)) {
668
659
th->errinfo = exception_error;
669
660
JUMP_TAG(TAG_FATAL);
672
mesg = GET_THREAD()->errinfo;
673
665
if (NIL_P(mesg)) {
674
666
mesg = rb_exc_new(rb_eRuntimeError, 0, 0);
677
ruby_set_current_source();
678
if (ruby_sourcefile && !NIL_P(mesg)) {
669
file = rb_sourcefile();
670
if (file) line = rb_sourceline();
671
if (file && !NIL_P(mesg)) {
679
672
at = get_backtrace(mesg);
681
674
at = make_backtrace();
685
678
if (!NIL_P(mesg)) {
686
GET_THREAD()->errinfo = mesg;
689
if (RTEST(ruby_debug) && !NIL_P(GET_THREAD()->errinfo)
690
&& !rb_obj_is_kind_of(GET_THREAD()->errinfo, rb_eSystemExit)) {
691
VALUE e = GET_THREAD()->errinfo;
682
if (RTEST(ruby_debug) && !NIL_P(e = th->errinfo) &&
683
!rb_obj_is_kind_of(e, rb_eSystemExit)) {
695
687
if ((status = EXEC_TAG()) == 0) {
696
e = rb_obj_as_string(e);
688
RB_GC_GUARD(e) = rb_obj_as_string(e);
697
689
warn_printf("Exception `%s' at %s:%d - %s\n",
698
rb_obj_classname(GET_THREAD()->errinfo),
699
ruby_sourcefile, ruby_sourceline, RSTRING_PTR(e));
690
rb_obj_classname(th->errinfo),
691
file, line, RSTRING_PTR(e));
702
if (status == TAG_FATAL && GET_THREAD()->errinfo == exception_error) {
703
GET_THREAD()->errinfo = mesg;
694
if (status == TAG_FATAL && th->errinfo == exception_error) {
705
697
else if (status) {
706
698
thread_reset_raised(th);
885
880
rb_thread_t *th = GET_THREAD();
886
881
rb_control_frame_t *cfp = th->cfp;
887
cfp = th_get_ruby_level_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
882
cfp = vm_get_ruby_level_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
888
883
if (GC_GUARDED_PTR_REF(cfp->lfp[0])) {
901
896
if (!rb_block_given_p()) {
902
th_localjump_error("no block given", Qnil, 0);
897
vm_localjump_error("no block given", Qnil, 0);
906
901
static inline VALUE
907
902
rb_yield_0(int argc, VALUE *argv)
909
return th_yield(GET_THREAD(), argc, argv);
904
return vm_yield(GET_THREAD(), argc, argv);
914
908
rb_yield(VALUE val)
1107
1107
va_init_list(args, data2);
1108
while (eclass = va_arg(args, VALUE)) {
1108
while ((eclass = va_arg(args, VALUE)) != 0) {
1109
1109
if (rb_obj_is_kind_of(th->errinfo, eclass)) {
1110
1110
handle = Qtrue;
1158
1158
rb_thread_t *th = GET_THREAD();
1159
1159
rb_control_frame_t *cfp = th->cfp;
1160
struct rb_vm_trap_tag trap_tag = {
1160
struct rb_vm_trap_tag trap_tag;
1162
trap_tag.prev = th->trap_tag;
1165
1165
th->trap_tag = &trap_tag;
1279
1279
VALUE exc = rb_eNoMethodError;
1280
1280
char *format = 0;
1281
NODE *cnode = ruby_current_node;
1282
1281
rb_thread_t *th = GET_THREAD();
1283
1282
int last_call_status = th->method_missing_reason;
1284
1283
if (argc == 0 || !SYMBOL_P(argv[0])) {
1300
1299
exc = rb_eNameError;
1302
1301
else if (last_call_status & NOEX_SUPER) {
1303
format = "super: no superclass method `%s'";
1302
format = "super: no superclass method `%s' for %s";
1306
1305
format = "undefined method `%s' for %s";
1309
ruby_current_node = cnode;
1360
1359
/* is it in the method cache? */
1361
1360
ent = cache + EXPR1(klass, mid);
1362
1362
if (ent->mid == mid && ent->klass == klass) {
1363
1363
if (!ent->method)
1364
1364
return method_missing(recv, mid, argc, argv,
1380
1380
return method_missing(recv, mid, argc, argv,
1381
1381
scope == 2 ? NOEX_VCALL : 0);
1383
1385
if (mid != missing) {
1384
1386
/* receiver specified form for private method */
1385
if (((noex & NOEX_MASK) & NOEX_PRIVATE) && scope == 0) {
1386
return method_missing(recv, mid, argc, argv, NOEX_PRIVATE);
1389
/* self must be kind of a specified form for protected method */
1390
if (((noex & NOEX_MASK) & NOEX_PROTECTED) && scope == 0) {
1391
VALUE defined_class = klass;
1393
if (TYPE(defined_class) == T_ICLASS) {
1394
defined_class = RBASIC(defined_class)->klass;
1397
if (!rb_obj_is_kind_of(rb_frame_self(),
1398
rb_class_real(defined_class))) {
1399
return method_missing(recv, mid, argc, argv, NOEX_PROTECTED);
1387
if (UNLIKELY(noex)) {
1388
if (((noex & NOEX_MASK) & NOEX_PRIVATE) && scope == 0) {
1389
return method_missing(recv, mid, argc, argv, NOEX_PRIVATE);
1392
/* self must be kind of a specified form for protected method */
1393
if (((noex & NOEX_MASK) & NOEX_PROTECTED) && scope == 0) {
1394
VALUE defined_class = klass;
1396
if (TYPE(defined_class) == T_ICLASS) {
1397
defined_class = RBASIC(defined_class)->klass;
1400
if (!rb_obj_is_kind_of(rb_frame_self(),
1401
rb_class_real(defined_class))) {
1402
return method_missing(recv, mid, argc, argv, NOEX_PROTECTED);
1406
if (NOEX_SAFE(noex) > th->safe_level) {
1407
rb_raise(rb_eSecurityError, "calling insecure method: %s", rb_id2name(mid));
1412
1420
//printf("%s with %d args\n", rb_id2name(mid), argc);
1415
th_call0(GET_THREAD(), klass, recv, mid, id, argc, argv, body,
1416
noex & NOEX_NOSUPER);
1422
val = vm_call0(th, klass, recv, mid, id, argc, argv, body,
1423
noex & NOEX_NOSUPER);
1419
1426
//for(i=0; i<level; i++){printf(" ");}
1439
send_funcall(int argc, VALUE *argv, VALUE recv, int scope)
1446
send_internal(int argc, VALUE *argv, VALUE recv, int scope)
1478
1485
scope = NOEX_NOSUPER | NOEX_PRIVATE;
1481
return send_funcall(argc, argv, recv, scope);
1488
return send_internal(argc, argv, recv, scope);
1486
* obj.funcall(symbol [, args...]) => obj
1487
* obj.__send!(symbol [, args...]) => obj
1493
* obj.send!(symbol [, args...]) => obj
1494
* obj.__send!(symbol [, args...]) => obj
1489
1496
* Invokes the method identified by _symbol_, passing it any
1490
* arguments specified. Unlike send, which calls private methods only
1491
* when it is invoked in function call style, funcall always aware of
1497
* arguments specified. Unlike send, which calls public methods only
1498
* when it is invoked in function call style, send! always aware of
1492
1499
* private methods.
1494
* 1.funcall(:puts, "hello") # prints "foo"
1501
* 1.send!(:puts, "hello") # prints "foo"
1498
rb_f_funcall(int argc, VALUE *argv, VALUE recv)
1505
rb_f_send_bang(int argc, VALUE *argv, VALUE recv)
1500
return send_funcall(argc, argv, recv, NOEX_NOSUPER | NOEX_PRIVATE);
1507
return send_internal(argc, argv, recv, NOEX_NOSUPER | NOEX_PRIVATE);
1612
1619
return cfp->method_id;
1614
else if (RUBY_VM_IFUNC_P(iseq)) {
1615
return rb_intern("<ifunc>");
1618
return rb_intern(RSTRING_PTR(iseq->name));
1622
if (RUBY_VM_IFUNC_P(iseq)) {
1623
return rb_intern("<ifunc>");
1625
if (iseq->defined_method_id) {
1626
return iseq->defined_method_id;
1628
if (iseq->local_iseq == iseq) {
1631
iseq = iseq->parent_iseq;
1650
1664
return GET_THREAD()->cfp->self;
1656
rb_thread_t *th = GET_THREAD();
1657
rb_control_frame_t *cfp = th_get_ruby_level_cfp(th, th->cfp);
1660
return RSTRING_PTR(cfp->iseq->filename);
1670
rb_thread_t *th = GET_THREAD();
1671
rb_control_frame_t *cfp = th_get_ruby_level_cfp(th, th->cfp);
1674
return th_get_sourceline(cfp);
1682
eval(VALUE self, VALUE src, VALUE scope, char *file, int line)
1668
eval(VALUE self, VALUE src, VALUE scope, const char *file, int line)
1685
1671
VALUE result = Qundef;
1716
1700
th->base_block = &env->block;
1719
rb_control_frame_t *cfp = th_get_ruby_level_cfp(th, th->cfp);
1703
rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp);
1720
1704
th->base_block = RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp);
1721
1705
th->base_block->iseq = cfp->iseq; /* TODO */
1724
1708
/* make eval iseq */
1725
1709
th->parse_in_eval++;
1726
iseqval = th_compile(th, src, rb_str_new2(file), INT2FIX(line));
1710
iseqval = rb_iseq_compile(src, rb_str_new2(file), INT2FIX(line));
1727
1711
th->parse_in_eval--;
1728
th_set_eval_stack(th, iseqval);
1712
rb_vm_set_eval_stack(th, iseqval);
1729
1713
th->base_block = 0;
1731
1715
if (0) { /* for debug */
1736
1720
/* save new env */
1737
1721
GetISeqPtr(iseqval, iseq);
1738
1722
if (bind && iseq->local_size > 0) {
1739
bind->env = th_make_env_object(th, th->cfp);
1723
bind->env = vm_make_env_object(th, th->cfp);
1743
1727
if (stored_cref_stack) {
1744
1728
stored_cref_stack =
1745
th_set_special_cref(th, env->block.lfp, stored_cref_stack);
1729
vm_set_special_cref(th, env->block.lfp, stored_cref_stack);
1749
result = th_eval_body(th);
1733
result = vm_eval_body(th);
1753
1737
if (stored_cref_stack) {
1754
th_set_special_cref(th, env->block.lfp, stored_cref_stack);
1738
vm_set_special_cref(th, env->block.lfp, stored_cref_stack);
1758
1742
if (state == TAG_RAISE) {
1743
VALUE errinfo = th->errinfo;
1759
1744
if (strcmp(file, "(eval)") == 0) {
1760
1745
VALUE mesg, errat;
1762
errat = get_backtrace(GET_THREAD()->errinfo);
1763
mesg = rb_attr_get(GET_THREAD()->errinfo, rb_intern("mesg"));
1747
errat = get_backtrace(errinfo);
1748
mesg = rb_attr_get(errinfo, rb_intern("mesg"));
1764
1749
if (!NIL_P(errat) && TYPE(errat) == T_ARRAY) {
1765
1750
if (!NIL_P(mesg) && TYPE(mesg) == T_STRING) {
1766
1751
rb_str_update(mesg, 0, 0, rb_str_new2(": "));
1825
1810
return eval(self, src, scope, file, line);
1828
VALUE *th_cfp_svar(rb_control_frame_t *cfp, int idx);
1813
VALUE vm_cfp_svar_get(rb_thread_t *th, rb_control_frame_t *cfp, VALUE key);
1814
void vm_cfp_svar_set(rb_thread_t *th, rb_control_frame_t *cfp, VALUE key, VALUE val);
1830
1816
/* function to call func under the specified class/module context */
1857
1842
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
1860
pcref = (NODE **) th_cfp_svar(cfp, -1);
1861
stored_cref = *pcref;
1862
*pcref = th_cref_push(th, under, NOEX_PUBLIC);
1845
stored_cref = (NODE *)vm_cfp_svar_get(th, cfp, 2);
1846
vm_cfp_svar_set(th, cfp, 2, (VALUE)vm_cref_push(th, under, NOEX_PUBLIC));
1865
1849
if ((state = EXEC_TAG()) == 0) {
2497
2481
while (RUBY_VM_VALID_CONTROL_FRAME_P(cfp, end_cfp)) {
2498
2482
if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
2499
2483
if (cfp->iseq->type == ISEQ_TYPE_RESCUE) {
2500
return cfp->dfp[-1];
2484
return &cfp->dfp[-1];
2502
2486
else if (cfp->iseq->type == ISEQ_TYPE_ENSURE &&
2503
2487
TYPE(cfp->dfp[-1]) != T_NODE) {
2504
return cfp->dfp[-1];
2488
return &cfp->dfp[-1];
2507
2491
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
2499
VALUE *ptr = errinfo_place();
2528
2519
rb_raise(rb_eTypeError, "assigning non-exception to $!");
2531
GET_THREAD()->errinfo = val;
2522
VALUE *ptr = errinfo_place();
2527
rb_raise(rb_eRuntimeError, "errinfo_setter: not in rescue clause.");
2536
rb_thread_t *th = GET_THREAD();
2536
2541
rb_set_errinfo(VALUE err)
2538
errinfo_setter(err, 0, 0);
2543
if (!NIL_P(err) && !rb_obj_is_kind_of(err, rb_eException)) {
2544
rb_raise(rb_eTypeError, "assigning non-exception to $!");
2546
GET_THREAD()->errinfo = err;
2550
rb_rubylevel_errinfo(void)
2552
return get_errinfo();
2573
2587
* local_variables #=> ["fred", "i"]
2576
int th_collect_local_variables_in_heap(rb_thread_t *th, VALUE *dfp, VALUE ary);
2590
int vm_collect_local_variables_in_heap(rb_thread_t *th, VALUE *dfp, VALUE ary);
2579
2593
rb_f_local_variables(void)
2581
2595
VALUE ary = rb_ary_new();
2582
2596
rb_thread_t *th = GET_THREAD();
2583
2597
rb_control_frame_t *cfp =
2584
th_get_ruby_level_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp));
2598
vm_get_ruby_level_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp));
2602
2616
VALUE *dfp = GC_GUARDED_PTR_REF(cfp->dfp[0]);
2604
if (th_collect_local_variables_in_heap(th, dfp, ary)) {
2618
if (vm_collect_local_variables_in_heap(th, dfp, ary)) {
2694
2708
__send = rb_intern("__send");
2695
2709
__send_bang = rb_intern("__send!");
2697
rb_global_variable((VALUE *)&ruby_eval_tree);
2699
2711
rb_define_virtual_variable("$@", errat_getter, errat_setter);
2700
rb_define_virtual_variable("$!", errinfo_getter, errinfo_setter);
2712
rb_define_virtual_variable("$!", errinfo_getter, 0);
2702
2714
rb_define_global_function("eval", rb_f_eval, -1);
2703
2715
rb_define_global_function("iterator?", rb_f_block_given_p, 0);
2724
2736
rb_define_method(rb_cBasicObject, "send", rb_f_send, -1);
2725
2737
rb_define_method(rb_cBasicObject, "__send__", rb_f_send, -1);
2726
2738
rb_define_method(rb_cBasicObject, "__send", rb_f_send, -1);
2727
rb_define_method(rb_cBasicObject, "funcall", rb_f_funcall, -1);
2728
rb_define_method(rb_cBasicObject, "__send!", rb_f_funcall, -1);
2739
rb_define_method(rb_cBasicObject, "send!", rb_f_send_bang, -1);
2740
rb_define_method(rb_cBasicObject, "__send!", rb_f_send_bang, -1);
2730
2742
rb_define_method(rb_mKernel, "instance_eval", rb_obj_instance_eval, -1);
2731
2743
rb_define_method(rb_mKernel, "instance_exec", rb_obj_instance_exec, -1);
2757
2769
rb_define_singleton_method(rb_cModule, "nesting", rb_mod_nesting, 0);
2758
2770
rb_define_singleton_method(rb_cModule, "constants", rb_mod_s_constants, -1);
2760
rb_define_singleton_method(ruby_top_self, "include", top_include, -1);
2761
rb_define_singleton_method(ruby_top_self, "public", top_public, -1);
2762
rb_define_singleton_method(ruby_top_self, "private", top_private, -1);
2772
rb_define_singleton_method(rb_vm_top_self(), "include", top_include, -1);
2773
rb_define_singleton_method(rb_vm_top_self(), "public", top_public, -1);
2774
rb_define_singleton_method(rb_vm_top_self(), "private", top_private, -1);
2764
2776
rb_define_method(rb_mKernel, "extend", rb_obj_extend, -1);
2767
2779
rb_define_global_function("untrace_var", rb_f_untrace_var, -1); /* in variable.c */
2769
2781
rb_define_virtual_variable("$SAFE", safe_getter, safe_setter);
2783
exception_error = rb_exc_new2(rb_eFatal, "exception reentered");
2784
rb_ivar_set(exception_error, idThrowState, INT2FIX(TAG_FATAL));
2785
rb_register_mark_object(exception_error);