1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15: #include "eval_intern.h"
16:
17: VALUE proc_invoke(VALUE, VALUE, VALUE, VALUE);
18: VALUE rb_binding_new();
19:
20: VALUE rb_f_block_given_p(void);
21:
22: ID rb_frame_callee(void);
23: static VALUE rb_frame_self(void);
24:
25: static ID removed, singleton_removed, undefined, singleton_undefined;
26: static ID init, eqq, each, aref, aset, match, missing;
27: static ID added, singleton_added;
28: static ID object_id, __send__, respond_to;
29:
30: VALUE rb_eLocalJumpError;
31: VALUE rb_eSysStackError;
32: VALUE sysstack_error;
33:
34: static VALUE exception_error;
35:
36: static VALUE eval(VALUE, VALUE, VALUE, const char *, int);
37:
38: static inline VALUE rb_yield_0(int argc, VALUE *argv);
39: static VALUE rb_call(VALUE, VALUE, ID, int, const VALUE *, int);
40:
41: #include "eval_error.c"
42: #include "eval_method.c"
43: #include "eval_safe.c"
44: #include "eval_jump.c"
45:
46:
47:
48: #if defined(__APPLE__)
49: #define environ (*_NSGetEnviron())
50: #elif !defined(_WIN32) && !defined(__MACOS__) || defined(_WIN32_WCE)
51: extern char **environ;
52: #endif
53: char **rb_origenviron;
54:
55: void rb_clear_trace_func(void);
56: void rb_thread_stop_timer_thread(void);
57:
58: void rb_call_inits(void);
59: void Init_stack(VALUE *);
60: void Init_heap(void);
61: void Init_ext(void);
62: void Init_BareVM(void);
63:
64: void
65: ruby_init(void)
66: {
67: static int initialized = 0;
68: int state;
69:
70: if (initialized)
71: return;
72: initialized = 1;
73:
74: #ifdef __MACOS__
75: rb_origenviron = 0;
76: #else
77: rb_origenviron = environ;
78: #endif
79:
80: Init_stack((void *)&state);
81: Init_BareVM();
82: Init_heap();
83:
84: PUSH_TAG();
85: if ((state = EXEC_TAG()) == 0) {
86: rb_call_inits();
87:
88: #ifdef __MACOS__
89: _macruby_init();
90: #elif defined(__VMS)
91: _vmsruby_init();
92: #endif
93:
94: ruby_prog_init();
95: ALLOW_INTS;
96: }
97: POP_TAG();
98:
99: if (state) {
100: error_print();
101: exit(EXIT_FAILURE);
102: }
103: ruby_running = 1;
104: }
105:
106: extern void rb_clear_trace_func(void);
107:
108: void *
109: ruby_options(int argc, char **argv)
110: {
111: int state;
112: void *tree = 0;
113:
114: Init_stack((void *)&state);
115: PUSH_TAG();
116: if ((state = EXEC_TAG()) == 0) {
117: SAVE_ROOT_JMPBUF(GET_THREAD(), tree = ruby_process_options(argc, argv));
118: }
119: else {
120: rb_clear_trace_func();
121: state = error_handle(state);
122: tree = (void *)INT2FIX(state);
123: }
124: POP_TAG();
125: return tree;
126: }
127:
128: static void
129: ruby_finalize_0(void)
130: {
131: rb_clear_trace_func();
132: PUSH_TAG();
133: if (EXEC_TAG() == 0) {
134: rb_trap_exit();
135: }
136: POP_TAG();
137: rb_exec_end_proc();
138: }
139:
140: static void
141: ruby_finalize_1(void)
142: {
143: ruby_sig_finalize();
144: GET_THREAD()->errinfo = Qnil;
145: rb_gc_call_finalizer_at_exit();
146: }
147:
148: void
149: ruby_finalize(void)
150: {
151: ruby_finalize_0();
152: ruby_finalize_1();
153: }
154:
155: void rb_thread_stop_timer_thread(void);
156:
157: int
158: ruby_cleanup(int ex)
159: {
160: int state;
161: volatile VALUE errs[2];
162: rb_thread_t *th = GET_THREAD();
163: int nerr;
164:
165: errs[1] = th->errinfo;
166: th->safe_level = 0;
167: Init_stack((void *)&state);
168: ruby_finalize_0();
169: errs[0] = th->errinfo;
170: PUSH_TAG();
171: if ((state = EXEC_TAG()) == 0) {
172: SAVE_ROOT_JMPBUF(th, rb_thread_terminate_all());
173: }
174: else if (ex == 0) {
175: ex = state;
176: }
177: th->errinfo = errs[1];
178: ex = error_handle(ex);
179: ruby_finalize_1();
180: POP_TAG();
181: rb_thread_stop_timer_thread();
182:
183: for (nerr = 0; nerr < sizeof(errs) / sizeof(errs[0]); ++nerr) {
184: VALUE err = errs[nerr];
185:
186: if (!RTEST(err)) continue;
187:
188:
189: if (TYPE(err) == T_NODE) continue;
190:
191: if (rb_obj_is_kind_of(err, rb_eSystemExit)) {
192: return sysexit_status(err);
193: }
194: else if (rb_obj_is_kind_of(err, rb_eSignal)) {
195: VALUE sig = rb_iv_get(err, "signo");
196: ruby_default_signal(NUM2INT(sig));
197: }
198: else if (ex == 0) {
199: ex = 1;
200: }
201: }
202:
203: #if EXIT_SUCCESS != 0 || EXIT_FAILURE != 1
204: switch (ex) {
205: #if EXIT_SUCCESS != 0
206: case 0: return EXIT_SUCCESS;
207: #endif
208: #if EXIT_FAILURE != 1
209: case 1: return EXIT_FAILURE;
210: #endif
211: }
212: #endif
213:
214: return ex;
215: }
216:
217: int
218: ruby_exec_node(void *n, char *file)
219: {
220: int state;
221: VALUE val;
222: NODE *node = n;
223: rb_thread_t *th = GET_THREAD();
224:
225: if (!node) return 0;
226:
227: PUSH_TAG();
228: if ((state = EXEC_TAG()) == 0) {
229: SAVE_ROOT_JMPBUF(th, {
230: VALUE iseq = rb_iseq_new(n, rb_str_new2("<main>"),
231: rb_str_new2(file), Qfalse, ISEQ_TYPE_TOP);
232: th->base_block = 0;
233: val = rb_iseq_eval(iseq);
234: });
235: }
236: POP_TAG();
237: return state;
238: }
239:
240: void
241: ruby_stop(int ex)
242: {
243: exit(ruby_cleanup(ex));
244: }
245:
246: int
247: ruby_run_node(void *n)
248: {
249: NODE *node = (NODE *)n;
250:
251: switch ((VALUE)n) {
252: case Qtrue: return EXIT_SUCCESS;
253: case Qfalse: return EXIT_FAILURE;
254: }
255: if (FIXNUM_P((VALUE)n)) {
256: return FIX2INT((VALUE)n);
257: }
258: Init_stack((void *)&n);
259: return ruby_cleanup(ruby_exec_node(node, node->nd_file));
260: }
261:
262: VALUE
263: rb_eval_string(const char *str)
264: {
265: return eval(rb_vm_top_self(), rb_str_new2(str), Qnil, "(eval)", 1);
266: }
267:
268: VALUE
269: rb_eval_string_protect(const char *str, int *state)
270: {
271: return rb_protect((VALUE (*)(VALUE))rb_eval_string, (VALUE)str, state);
272: }
273:
274: VALUE
275: rb_eval_string_wrap(const char *str, int *state)
276: {
277: int status;
278: rb_thread_t *th = GET_THREAD();
279: VALUE self = th->top_self;
280: VALUE wrapper = th->top_wrapper;
281: VALUE val;
282:
283: th->top_wrapper = rb_module_new();
284: th->top_self = rb_obj_clone(rb_vm_top_self());
285: rb_extend_object(th->top_self, th->top_wrapper);
286:
287: val = rb_eval_string_protect(str, &status);
288:
289: th->top_self = self;
290: th->top_wrapper = wrapper;
291:
292: if (state) {
293: *state = status;
294: }
295: else if (status) {
296: JUMP_TAG(status);
297: }
298: return val;
299: }
300:
301: VALUE
302: rb_eval_cmd(VALUE cmd, VALUE arg, int level)
303: {
304: int state;
305: VALUE val = Qnil;
306: volatile int safe = rb_safe_level();
307:
308: if (OBJ_TAINTED(cmd)) {
309: level = 4;
310: }
311:
312: if (TYPE(cmd) != T_STRING) {
313: PUSH_TAG();
314: rb_set_safe_level_force(level);
315: if ((state = EXEC_TAG()) == 0) {
316: val = rb_funcall2(cmd, rb_intern("call"), RARRAY_LEN(arg),
317: RARRAY_PTR(arg));
318: }
319: POP_TAG();
320:
321: rb_set_safe_level_force(safe);
322:
323: if (state)
324: JUMP_TAG(state);
325: return val;
326: }
327:
328: PUSH_TAG();
329: if ((state = EXEC_TAG()) == 0) {
330: val = eval(rb_vm_top_self(), cmd, Qnil, 0, 0);
331: }
332: POP_TAG();
333:
334: rb_set_safe_level_force(safe);
335: if (state) vm_jump_tag_but_local_jump(state, val);
336: return val;
337: }
338:
339:
340:
341:
342:
343:
344:
345:
346:
347:
348:
349:
350:
351:
352:
353:
354: static VALUE
355: rb_mod_nesting(void)
356: {
357: VALUE ary = rb_ary_new();
358: NODE *cref = ruby_cref();
359:
360: while (cref && cref->nd_next) {
361: VALUE klass = cref->nd_clss;
362: if (!NIL_P(klass)) {
363: rb_ary_push(ary, klass);
364: }
365: cref = cref->nd_next;
366: }
367: return ary;
368: }
369:
370:
371:
372:
373:
374:
375:
376:
377:
378:
379:
380:
381:
382:
383:
384: static VALUE
385: rb_mod_s_constants(int argc, VALUE *argv, VALUE mod)
386: {
387: NODE *cref = ruby_cref();
388: VALUE klass;
389: VALUE cbase = 0;
390: void *data = 0;
391:
392: if (argc > 0) {
393: return rb_mod_constants(argc, argv, rb_cModule);
394: }
395:
396: while (cref) {
397: klass = cref->nd_clss;
398: if (!NIL_P(klass)) {
399: data = rb_mod_const_at(cref->nd_clss, data);
400: if (!cbase) {
401: cbase = klass;
402: }
403: }
404: cref = cref->nd_next;
405: }
406:
407: if (cbase) {
408: data = rb_mod_const_of(cbase, data);
409: }
410: return rb_const_list(data);
411: }
412:
413: void
414: rb_frozen_class_p(VALUE klass)
415: {
416: char *desc = "something(?!)";
417:
418: if (OBJ_FROZEN(klass)) {
419: if (FL_TEST(klass, FL_SINGLETON))
420: desc = "object";
421: else {
422: switch (TYPE(klass)) {
423: case T_MODULE:
424: case T_ICLASS:
425: desc = "module";
426: break;
427: case T_CLASS:
428: desc = "class";
429: break;
430: }
431: }
432: rb_error_frozen(desc);
433: }
434: }
435:
436:
437:
438:
439:
440:
441:
442:
443:
444:
445: static NODE *basic_respond_to = 0;
446:
447: int
448: rb_obj_respond_to(VALUE obj, ID id, int priv)
449: {
450: VALUE klass = CLASS_OF(obj);
451:
452: if (rb_method_node(klass, respond_to) == basic_respond_to) {
453: return rb_method_boundp(klass, id, !priv);
454: }
455: else {
456: VALUE args[2];
457: int n = 0;
458: args[n++] = ID2SYM(id);
459: if (priv)
460: args[n++] = Qtrue;
461: return rb_funcall2(obj, respond_to, n, args);
462: }
463: }
464:
465: int
466: rb_respond_to(VALUE obj, ID id)
467: {
468: return rb_obj_respond_to(obj, id, Qfalse);
469: }
470:
471:
472:
473:
474:
475:
476:
477:
478:
479:
480: static VALUE
481: obj_respond_to(int argc, VALUE *argv, VALUE obj)
482: {
483: VALUE mid, priv;
484: ID id;
485:
486: rb_scan_args(argc, argv, "11", &mid, &priv);
487: id = rb_to_id(mid);
488: if (rb_method_boundp(CLASS_OF(obj), id, !RTEST(priv))) {
489: return Qtrue;
490: }
491: return Qfalse;
492: }
493:
494:
495:
496:
497:
498:
499:
500:
501:
502:
503:
504:
505:
506:
507:
508:
509:
510:
511:
512:
513:
514:
515:
516:
517:
518:
519:
520: static VALUE
521: rb_mod_method_defined(VALUE mod, VALUE mid)
522: {
523: return rb_method_boundp(mod, rb_to_id(mid), 1);
524: }
525:
526: #define VISI_CHECK(x,f) (((x)&NOEX_MASK) == (f))
527:
528:
529:
530:
531:
532:
533:
534:
535:
536:
537:
538:
539:
540:
541:
542:
543:
544:
545:
546:
547:
548:
549:
550:
551:
552:
553:
554: static VALUE
555: rb_mod_public_method_defined(VALUE mod, VALUE mid)
556: {
557: ID id = rb_to_id(mid);
558: NODE *method;
559:
560: method = rb_method_node(mod, id);
561: if (method) {
562: if (VISI_CHECK(method->nd_noex, NOEX_PUBLIC))
563: return Qtrue;
564: }
565: return Qfalse;
566: }
567:
568:
569:
570:
571:
572:
573:
574:
575:
576:
577:
578:
579:
580:
581:
582:
583:
584:
585:
586:
587:
588:
589:
590:
591:
592:
593:
594: static VALUE
595: rb_mod_private_method_defined(VALUE mod, VALUE mid)
596: {
597: ID id = rb_to_id(mid);
598: NODE *method;
599:
600: method = rb_method_node(mod, id);
601: if (method) {
602: if (VISI_CHECK(method->nd_noex, NOEX_PRIVATE))
603: return Qtrue;
604: }
605: return Qfalse;
606: }
607:
608:
609:
610:
611:
612:
613:
614:
615:
616:
617:
618:
619:
620:
621:
622:
623:
624:
625:
626:
627:
628:
629:
630:
631:
632:
633:
634: static VALUE
635: rb_mod_protected_method_defined(VALUE mod, VALUE mid)
636: {
637: ID id = rb_to_id(mid);
638: NODE *method;
639:
640: method = rb_method_node(mod, id);
641: if (method) {
642: if (VISI_CHECK(method->nd_noex, NOEX_PROTECTED))
643: return Qtrue;
644: }
645: return Qfalse;
646: }
647:
648: NORETURN(static void rb_longjmp(int, VALUE));
649: static VALUE make_backtrace(void);
650:
651: static void
652: rb_longjmp(int tag, VALUE mesg)
653: {
654: VALUE at;
655: VALUE e;
656: rb_thread_t *th = GET_THREAD();
657: const char *file;
658: int line = 0;
659:
660: if (thread_set_raised(th)) {
661: th->errinfo = exception_error;
662: JUMP_TAG(TAG_FATAL);
663: }
664:
665: if (NIL_P(mesg))
666: mesg = th->errinfo;
667: if (NIL_P(mesg)) {
668: mesg = rb_exc_new(rb_eRuntimeError, 0, 0