~ubuntu-branches/ubuntu/intrepid/ruby1.9/intrepid-updates

« back to all changes in this revision

Viewing changes to eval.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2007-09-04 16:01:17 UTC
  • mfrom: (1.1.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20070904160117-i15zckg2nhxe9fyw
Tags: 1.9.0+20070830-2ubuntu1
* Sync from Debian; remaining changes:
  - Add -g to CFLAGS.
* Fixes build failure on ia64.
* Fixes build failure with gcc-4.2 on lpia.
* Robustify check for target_os, fixing build failure on lpia.
* Set Ubuntu maintainer address.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 
3
3
  eval.c -
4
4
 
5
 
  $Author: ko1 $
6
 
  $Date: 2007-06-06 10:57:36 +0900 (水, 06  6月 2007) $
 
5
  $Author: matz $
 
6
  $Date: 2007-08-25 12:29:39 +0900 (土, 25  8月 2007) $
7
7
  created at: Thu Jun 10 14:22:17 JST 1993
8
8
 
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
12
12
 
22
22
ID rb_frame_callee(void);
23
23
static VALUE rb_frame_self(void);
24
24
 
25
 
NODE *ruby_current_node;
26
 
 
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;
31
29
 
32
30
VALUE rb_eLocalJumpError;
33
31
VALUE rb_eSysStackError;
34
 
 
35
 
extern int ruby_nerrs;
36
 
extern VALUE ruby_top_self;
37
 
 
38
 
static VALUE eval(VALUE, VALUE, VALUE, char *, int);
 
32
VALUE sysstack_error;
 
33
 
 
34
static VALUE exception_error;
 
35
 
 
36
static VALUE eval(VALUE, VALUE, VALUE, const char *, int);
39
37
 
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);
42
40
 
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"
47
45
 
48
46
/* initialize ruby */
49
47
 
57
55
jmp_buf function_call_may_return_twice_jmp_buf;
58
56
int function_call_may_return_twice_false = 0;
59
57
 
 
58
void rb_clear_trace_func(void);
 
59
void rb_thread_stop_timer_thread(void);
 
60
 
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));
64
 
void Init_yarv(void);
 
65
void Init_BareVM(void);
65
66
 
66
67
void
67
68
ruby_init(void)
80
81
#endif
81
82
 
82
83
    Init_stack((void *)&state);
83
 
    Init_yarv();
 
84
    Init_BareVM();
84
85
    Init_heap();
85
86
 
86
87
    PUSH_TAG();
96
97
        ruby_prog_init();
97
98
        ALLOW_INTS;
98
99
    }
99
 
    POP_TAG_INIT();
 
100
    POP_TAG();
100
101
 
101
102
    if (state) {
102
103
        error_print();
105
106
    ruby_running = 1;
106
107
}
107
108
 
108
 
void
 
109
extern void rb_clear_trace_func(void);
 
110
 
 
111
void *
109
112
ruby_options(int argc, char **argv)
110
113
{
111
114
    int state;
 
115
    void *tree = 0;
112
116
 
113
117
    Init_stack((void *)&state);
114
118
    PUSH_TAG();
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));
117
121
    }
118
122
    else {
119
123
        rb_clear_trace_func();
120
124
        exit(error_handle(state));
121
125
    }
122
126
    POP_TAG();
 
127
    return tree;
123
128
}
124
129
 
125
130
static void
137
142
ruby_finalize_1(void)
138
143
{
139
144
    signal(SIGINT, SIG_DFL);
140
 
    GET_THREAD()->errinfo = 0;
 
145
    GET_THREAD()->errinfo = Qnil;
141
146
    rb_clear_trace_func();
142
147
    rb_gc_call_finalizer_at_exit();
143
148
}
149
154
    ruby_finalize_1();
150
155
}
151
156
 
 
157
void rb_thread_stop_timer_thread(void);
 
158
 
152
159
int
153
160
ruby_cleanup(int ex)
154
161
{
155
162
    int state;
156
163
    volatile VALUE errs[2];
157
164
    rb_thread_t *th = GET_THREAD();
158
 
    rb_vm_t *vm = th->vm;
159
165
    int nerr;
160
166
 
161
167
    errs[1] = th->errinfo;
191
197
            VALUE sig = rb_iv_get(err, "signo");
192
198
            ruby_default_signal(NUM2INT(sig));
193
199
        }
194
 
    }
 
200
        else if (ex == 0) {
 
201
            ex = 1;
 
202
        }
 
203
    }
 
204
 
 
205
#if EXIT_SUCCESS != 0 || EXIT_FAILURE != 1
 
206
    switch (ex) {
 
207
#if EXIT_SUCCESS != 0
 
208
      case 0: return EXIT_SUCCESS;
 
209
#endif
 
210
#if EXIT_FAILURE != 1
 
211
      case 1: return EXIT_FAILURE;
 
212
#endif
 
213
    }
 
214
#endif
195
215
 
196
216
    return ex;
197
217
}
198
218
 
199
 
extern NODE *ruby_eval_tree;
200
 
 
201
 
static int
202
 
ruby_exec_internal(void)
 
219
int
 
220
ruby_exec_node(void *n, char *file)
203
221
{
204
222
    int state;
205
223
    VALUE val;
 
224
    NODE *node = n;
206
225
    rb_thread_t *th = GET_THREAD();
207
226
 
208
 
    if (!ruby_eval_tree) return 0;
 
227
    if (!node) return 0;
209
228
 
210
229
    PUSH_TAG();
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);
215
236
        });
216
237
    }
217
238
    POP_TAG();
218
239
    return state;
219
240
}
220
241
 
221
 
int
222
 
ruby_exec(void)
223
 
{
224
 
    volatile NODE *tmp;
225
 
 
226
 
    Init_stack((void *)&tmp);
227
 
    return ruby_exec_internal();
228
 
}
229
 
 
230
242
void
231
243
ruby_stop(int ex)
232
244
{
233
245
    exit(ruby_cleanup(ex));
234
246
}
235
247
 
236
 
void
237
 
ruby_run(void)
 
248
int
 
249
ruby_run_node(void *n)
238
250
{
239
 
    int state;
240
 
    static int ex;
241
 
 
242
 
    if (ruby_nerrs > 0) {
243
 
        exit(EXIT_FAILURE);
244
 
    }
245
 
 
246
 
    state = ruby_exec();
247
 
 
248
 
    if (state && !ex) {
249
 
        ex = state;
250
 
    }
251
 
    ruby_stop(ex);
 
251
    NODE *node = (NODE *)n;
 
252
    if (!n) {
 
253
        return EXIT_FAILURE;
 
254
    }
 
255
    Init_stack((void *)&n);
 
256
    return ruby_cleanup(ruby_exec_node(node, node->nd_file));
252
257
}
253
258
 
254
259
VALUE
255
260
rb_eval_string(const char *str)
256
261
{
257
 
    VALUE v;
258
 
    NODE *oldsrc = ruby_current_node;
259
 
 
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;
264
 
 
265
 
    return v;
 
262
    return eval(rb_vm_top_self(), rb_str_new2(str), Qnil, "(eval)", 1);
266
263
}
267
264
 
268
265
VALUE
281
278
    VALUE val;
282
279
 
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);
286
283
 
287
284
    val = rb_eval_string_protect(str, &status);
308
305
    if (OBJ_TAINTED(cmd)) {
309
306
        level = 4;
310
307
    }
 
308
 
311
309
    if (TYPE(cmd) != T_STRING) {
312
 
 
313
310
        PUSH_TAG();
314
311
        rb_set_safe_level_force(level);
315
312
        if ((state = EXEC_TAG()) == 0) {
316
 
            val =
317
 
              rb_funcall2(cmd, rb_intern("call"), RARRAY_LEN(arg),
318
 
                          RARRAY_PTR(arg));
 
313
            val = rb_funcall2(cmd, rb_intern("call"), RARRAY_LEN(arg),
 
314
                              RARRAY_PTR(arg));
319
315
        }
320
316
        POP_TAG();
321
317
 
328
324
 
329
325
    PUSH_TAG();
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);
332
328
    }
333
329
    POP_TAG();
334
330
 
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);
337
333
    return val;
338
334
}
339
335
 
647
643
    return Qfalse;
648
644
}
649
645
 
650
 
NORETURN(void th_iter_break _((rb_thread_t *)));
651
 
 
652
 
void
653
 
rb_iter_break()
654
 
{
655
 
    th_iter_break(GET_THREAD());
656
 
}
657
 
 
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);
660
648
 
661
649
static void
662
650
rb_longjmp(int tag, VALUE mesg)
663
651
{
664
652
    VALUE at;
 
653
    VALUE e;
665
654
    rb_thread_t *th = GET_THREAD();
 
655
    const char *file;
 
656
    int line = 0;
666
657
 
667
658
    if (thread_set_raised(th)) {
668
659
        th->errinfo = exception_error;
669
660
        JUMP_TAG(TAG_FATAL);
670
661
    }
 
662
 
671
663
    if (NIL_P(mesg))
672
 
      mesg = GET_THREAD()->errinfo;
 
664
        mesg = th->errinfo;
673
665
    if (NIL_P(mesg)) {
674
666
        mesg = rb_exc_new(rb_eRuntimeError, 0, 0);
675
667
    }
676
668
 
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);
680
673
        if (NIL_P(at)) {
681
674
            at = make_backtrace();
683
676
        }
684
677
    }
685
678
    if (!NIL_P(mesg)) {
686
 
        GET_THREAD()->errinfo = mesg;
 
679
        th->errinfo = mesg;
687
680
    }
688
681
 
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)) {
692
684
        int status;
693
685
 
694
686
        PUSH_TAG();
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));
700
692
        }
701
693
        POP_TAG();
702
 
        if (status == TAG_FATAL && GET_THREAD()->errinfo == exception_error) {
703
 
            GET_THREAD()->errinfo = mesg;
 
694
        if (status == TAG_FATAL && th->errinfo == exception_error) {
 
695
            th->errinfo = mesg;
704
696
        }
705
697
        else if (status) {
706
698
            thread_reset_raised(th);
709
701
    }
710
702
 
711
703
    rb_trap_restore_mask();
 
704
 
712
705
    if (tag != TAG_FATAL) {
713
706
        EXEC_EVENT_HOOK(th, RUBY_EVENT_RAISE, th->cfp->self,
714
707
                        0 /* TODO: id */, 0 /* TODO: klass */);
715
708
    }
 
709
 
716
710
    thread_reset_raised(th);
717
711
    JUMP_TAG(tag);
718
712
}
732
726
}
733
727
 
734
728
void
735
 
rb_interrupt()
 
729
rb_interrupt(void)
736
730
{
737
 
    rb_raise(rb_eInterrupt, "");
 
731
    static const char fmt[1] = {'\0'};
 
732
    rb_raise(rb_eInterrupt, fmt);
738
733
}
739
734
 
740
735
/*
884
879
{
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])) {
889
884
        return Qtrue;
890
885
    }
899
894
rb_need_block()
900
895
{
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);
903
898
    }
904
899
}
905
900
 
906
901
static inline VALUE
907
902
rb_yield_0(int argc, VALUE *argv)
908
903
{
909
 
    return th_yield(GET_THREAD(), argc, argv);
 
904
    return vm_yield(GET_THREAD(), argc, argv);
910
905
}
911
906
 
912
 
 
913
907
VALUE
914
908
rb_yield(VALUE val)
915
909
{
957
951
    return v;
958
952
}
959
953
 
 
954
static VALUE
 
955
loop_i()
 
956
{
 
957
    for (;;) {
 
958
        rb_yield_0(0, 0);
 
959
    }
 
960
}
 
961
 
960
962
/*
961
963
 *  call-seq:
962
964
 *     loop {|| block }
974
976
static VALUE
975
977
rb_f_loop(void)
976
978
{
977
 
    for (;;) {
978
 
        rb_yield_0(0, 0);
979
 
    }
 
979
    rb_rescue2(loop_i, (VALUE)0, 0, 0, rb_eStopIteration, (VALUE)0);
980
980
    return Qnil;                /* dummy */
981
981
}
982
982
 
1105
1105
            VALUE eclass;
1106
1106
 
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;
1111
1111
                    break;
1157
1157
    int status;
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 = {
1161
 
        th->trap_tag,
1162
 
    };
 
1160
    struct rb_vm_trap_tag trap_tag;
 
1161
 
 
1162
    trap_tag.prev = th->trap_tag;
1163
1163
 
1164
1164
    PUSH_TAG();
1165
1165
    th->trap_tag = &trap_tag;
1278
1278
    ID id;
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;
1301
1300
    }
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";
1304
1303
    }
1305
1304
    if (!format) {
1306
1305
        format = "undefined method `%s' for %s";
1307
1306
    }
1308
1307
 
1309
 
    ruby_current_node = cnode;
1310
1308
    {
1311
1309
        int n = 0;
1312
1310
        VALUE args[3];
1351
1349
    int noex;
1352
1350
    ID id = mid;
1353
1351
    struct cache_entry *ent;
 
1352
    rb_thread_t *th = GET_THREAD();
1354
1353
 
1355
1354
    if (!klass) {
1356
1355
        rb_raise(rb_eNotImpError,
1359
1358
    }
1360
1359
    /* is it in the method cache? */
1361
1360
    ent = cache + EXPR1(klass, mid);
 
1361
 
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);
1382
1382
    }
 
1383
    
 
1384
 
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);
1387
 
        }
1388
 
 
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;
1392
 
 
1393
 
            if (TYPE(defined_class) == T_ICLASS) {
1394
 
                defined_class = RBASIC(defined_class)->klass;
1395
 
            }
1396
 
 
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);
 
1390
            }
 
1391
 
 
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;
 
1395
                
 
1396
                if (TYPE(defined_class) == T_ICLASS) {
 
1397
                    defined_class = RBASIC(defined_class)->klass;
 
1398
                }
 
1399
                
 
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);
 
1403
                }
 
1404
            }
 
1405
 
 
1406
            if (NOEX_SAFE(noex) > th->safe_level) {
 
1407
                rb_raise(rb_eSecurityError, "calling insecure method: %s", rb_id2name(mid));
1400
1408
            }
1401
1409
        }
1402
1410
    }
1411
1419
        //level++;
1412
1420
        //printf("%s with %d args\n", rb_id2name(mid), argc);
1413
1421
        */
1414
 
        val =
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);
1417
1424
        /*
1418
1425
        //level--;
1419
1426
        //for(i=0; i<level; i++){printf("  ");}
1436
1443
}
1437
1444
 
1438
1445
static VALUE
1439
 
send_funcall(int argc, VALUE *argv, VALUE recv, int scope)
 
1446
send_internal(int argc, VALUE *argv, VALUE recv, int scope)
1440
1447
{
1441
1448
    VALUE vid;
1442
1449
 
1478
1485
        scope = NOEX_NOSUPER | NOEX_PRIVATE;
1479
1486
    }
1480
1487
 
1481
 
    return send_funcall(argc, argv, recv, scope);
 
1488
    return send_internal(argc, argv, recv, scope);
1482
1489
}
1483
1490
 
1484
1491
/*
1485
1492
 *  call-seq:
1486
 
 *     obj.funcall(symbol [, args...])        => obj
1487
 
 *     obj.__send!(symbol [, args...])        => obj
 
1493
 *     obj.send!(symbol [, args...])        => obj
 
1494
 *     obj.__send!(symbol [, args...])      => obj
1488
1495
 *
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.
1493
1500
 *
1494
 
 *     1.funcall(:puts, "hello")  # prints "foo"
 
1501
 *     1.send!(:puts, "hello")  # prints "foo"
1495
1502
 */
1496
1503
 
1497
1504
VALUE
1498
 
rb_f_funcall(int argc, VALUE *argv, VALUE recv)
 
1505
rb_f_send_bang(int argc, VALUE *argv, VALUE recv)
1499
1506
{
1500
 
    return send_funcall(argc, argv, recv, NOEX_NOSUPER | NOEX_PRIVATE);
 
1507
    return send_internal(argc, argv, recv, NOEX_NOSUPER | NOEX_PRIVATE);
1501
1508
}
1502
1509
 
1503
1510
VALUE
1540
1547
static VALUE
1541
1548
backtrace(int lev)
1542
1549
{
1543
 
    return th_backtrace(GET_THREAD(), lev);
 
1550
    return vm_backtrace(GET_THREAD(), lev);
1544
1551
}
1545
1552
 
1546
1553
/*
1611
1618
    if (!iseq) {
1612
1619
        return cfp->method_id;
1613
1620
    }
1614
 
    else if (RUBY_VM_IFUNC_P(iseq)) {
1615
 
        return rb_intern("<ifunc>");
1616
 
    }
1617
 
    else {
1618
 
        return rb_intern(RSTRING_PTR(iseq->name));
1619
 
    }
 
1621
    while (iseq) {
 
1622
        if (RUBY_VM_IFUNC_P(iseq)) {
 
1623
            return rb_intern("<ifunc>");
 
1624
        }
 
1625
        if (iseq->defined_method_id) {
 
1626
            return iseq->defined_method_id;
 
1627
        }
 
1628
        if (iseq->local_iseq == iseq) {
 
1629
            break;
 
1630
        }
 
1631
        iseq = iseq->parent_iseq;
 
1632
    }
 
1633
    return 0;
1620
1634
}
1621
1635
 
1622
1636
ID
1650
1664
    return GET_THREAD()->cfp->self;
1651
1665
}
1652
1666
 
1653
 
const char *
1654
 
rb_sourcefile(void)
1655
 
{
1656
 
    rb_thread_t *th = GET_THREAD();
1657
 
    rb_control_frame_t *cfp = th_get_ruby_level_cfp(th, th->cfp);
1658
 
 
1659
 
    if (cfp) {
1660
 
        return RSTRING_PTR(cfp->iseq->filename);
1661
 
    }
1662
 
    else {
1663
 
        return "";
1664
 
    }
1665
 
}
1666
 
 
1667
 
int
1668
 
rb_sourceline(void)
1669
 
{
1670
 
    rb_thread_t *th = GET_THREAD();
1671
 
    rb_control_frame_t *cfp = th_get_ruby_level_cfp(th, th->cfp);
1672
 
 
1673
 
    if (cfp) {
1674
 
        return th_get_sourceline(cfp);
1675
 
    }
1676
 
    else {
1677
 
        return 0;
1678
 
    }
1679
 
}
1680
 
 
1681
1667
static VALUE
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)
1683
1669
{
1684
1670
    int state;
1685
1671
    VALUE result = Qundef;
1690
1676
    NODE *stored_cref_stack = 0;
1691
1677
 
1692
1678
    if (file == 0) {
1693
 
        ruby_set_current_source();
1694
 
        file = ruby_sourcefile;
1695
 
        line = ruby_sourceline;
 
1679
        file = rb_sourcefile();
 
1680
        line = rb_sourceline();
1696
1681
    }
1697
1682
 
1698
1683
    PUSH_TAG();
1701
1686
        VALUE iseqval;
1702
1687
 
1703
1688
        if (scope != Qnil) {
1704
 
 
1705
1689
            if (CLASS_OF(scope) == rb_cBinding) {
1706
1690
                GetBindingPtr(scope, bind);
1707
1691
                envval = bind->env;
1716
1700
            th->base_block = &env->block;
1717
1701
        }
1718
1702
        else {
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 */
1722
1706
        }
1723
1707
 
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;
1730
1714
 
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);
1740
1724
        }
1741
1725
 
1742
1726
        /* push tag */
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);
1746
1730
        }
1747
1731
 
1748
1732
        /* kick */
1749
 
        result = th_eval_body(th);
 
1733
        result = vm_eval_body(th);
1750
1734
    }
1751
1735
    POP_TAG();
1752
1736
 
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);
1755
1739
    }
1756
1740
 
1757
1741
    if (state) {
1758
1742
        if (state == TAG_RAISE) {
 
1743
            VALUE errinfo = th->errinfo;
1759
1744
            if (strcmp(file, "(eval)") == 0) {
1760
1745
                VALUE mesg, errat;
1761
1746
 
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(": "));
1769
1754
                    RARRAY_PTR(errat)[0] = RARRAY_PTR(backtrace(-2))[0];
1770
1755
                }
1771
1756
            }
1772
 
            rb_exc_raise(GET_THREAD()->errinfo);
 
1757
            rb_exc_raise(errinfo);
1773
1758
        }
1774
1759
        JUMP_TAG(state);
1775
1760
    }
1825
1810
    return eval(self, src, scope, file, line);
1826
1811
}
1827
1812
 
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);
1829
1815
 
1830
1816
/* function to call func under the specified class/module context */
1831
1817
static VALUE
1837
1823
    rb_control_frame_t *pcfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
1838
1824
    VALUE stored_self = pcfp->self;
1839
1825
    NODE *stored_cref = 0;
1840
 
    NODE **pcref = 0;
1841
1826
 
1842
1827
    rb_block_t block;
1843
1828
    rb_block_t *blockptr;
1857
1842
        cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
1858
1843
    }
1859
1844
 
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));
1863
1847
 
1864
1848
    PUSH_TAG();
1865
1849
    if ((state = EXEC_TAG()) == 0) {
1868
1852
    POP_TAG();
1869
1853
 
1870
1854
    /* restore environment */
1871
 
    *pcref = stored_cref;
 
1855
    vm_cfp_svar_set(th, cfp, 2, (VALUE)stored_cref);
1872
1856
    pcfp->self = stored_self;
1873
1857
 
1874
1858
    if (state) {
2487
2471
VALUE rb_f_trace_var();
2488
2472
VALUE rb_f_untrace_var();
2489
2473
 
2490
 
static VALUE
2491
 
get_errinfo(void)
 
2474
static VALUE *
 
2475
errinfo_place(void)
2492
2476
{
2493
2477
    rb_thread_t *th = GET_THREAD();
2494
2478
    rb_control_frame_t *cfp = th->cfp;
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];
2501
2485
            }
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];
2505
2489
            }
2506
2490
        }
2507
2491
        cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
2508
2492
    }
2509
 
    return Qnil;
 
2493
    return 0;
 
2494
}
 
2495
 
 
2496
static VALUE
 
2497
get_errinfo(void)
 
2498
{
 
2499
    VALUE *ptr = errinfo_place();
 
2500
    if (ptr) {
 
2501
        return *ptr;
 
2502
    }
 
2503
    else {
 
2504
        return Qnil;
 
2505
    }
2510
2506
}
2511
2507
 
2512
2508
static VALUE
2515
2511
    return get_errinfo();
2516
2512
}
2517
2513
 
2518
 
VALUE
2519
 
rb_errinfo(void)
2520
 
{
2521
 
    return get_errinfo();
2522
 
}
2523
 
 
 
2514
#if 0
2524
2515
static void
2525
2516
errinfo_setter(VALUE val, ID id, VALUE *var)
2526
2517
{
2528
2519
        rb_raise(rb_eTypeError, "assigning non-exception to $!");
2529
2520
    }
2530
2521
    else {
2531
 
        GET_THREAD()->errinfo = val;
 
2522
        VALUE *ptr = errinfo_place();
 
2523
        if (ptr) {
 
2524
            *ptr = val;
 
2525
        }
 
2526
        else {
 
2527
            rb_raise(rb_eRuntimeError, "errinfo_setter: not in rescue clause.");
 
2528
        }
2532
2529
    }
2533
2530
}
 
2531
#endif
 
2532
 
 
2533
VALUE
 
2534
rb_errinfo(void)
 
2535
{
 
2536
    rb_thread_t *th = GET_THREAD();
 
2537
    return th->errinfo;
 
2538
}
2534
2539
 
2535
2540
void
2536
2541
rb_set_errinfo(VALUE err)
2537
2542
{
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 $!");
 
2545
    }
 
2546
    GET_THREAD()->errinfo = err;
 
2547
}
 
2548
 
 
2549
VALUE
 
2550
rb_rubylevel_errinfo(void)
 
2551
{
 
2552
    return get_errinfo();
2539
2553
}
2540
2554
 
2541
2555
static VALUE
2573
2587
 *     local_variables   #=> ["fred", "i"]
2574
2588
 */
2575
2589
 
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);
2577
2591
 
2578
2592
static VALUE
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));
2585
2599
    int i;
2586
2600
 
2587
2601
    while (1) {
2601
2615
            /* block */
2602
2616
            VALUE *dfp = GC_GUARDED_PTR_REF(cfp->dfp[0]);
2603
2617
 
2604
 
            if (th_collect_local_variables_in_heap(th, dfp, ary)) {
 
2618
            if (vm_collect_local_variables_in_heap(th, dfp, ary)) {
2605
2619
                break;
2606
2620
            }
2607
2621
            else {
2694
2708
    __send = rb_intern("__send");
2695
2709
    __send_bang = rb_intern("__send!");
2696
2710
 
2697
 
    rb_global_variable((VALUE *)&ruby_eval_tree);
2698
 
 
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);
2701
2713
 
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);
2729
2741
 
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);
2759
2771
 
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);
2763
2775
 
2764
2776
    rb_define_method(rb_mKernel, "extend", rb_obj_extend, -1);
2765
2777
 
2767
2779
    rb_define_global_function("untrace_var", rb_f_untrace_var, -1);     /* in variable.c */
2768
2780
 
2769
2781
    rb_define_virtual_variable("$SAFE", safe_getter, safe_setter);
 
2782
 
 
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);
2770
2786
}
2771
2787
 
2772
2788