Ruby 3.1.3p185 (2022-11-24 revision 1a6b16756e0ba6b95ab71a441357ed5484e33498)
eval.c
1/**********************************************************************
2
3 eval.c -
4
5 $Author$
6 created at: Thu Jun 10 14:22:17 JST 1993
7
8 Copyright (C) 1993-2007 Yukihiro Matsumoto
9 Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
10 Copyright (C) 2000 Information-technology Promotion Agency, Japan
11
12**********************************************************************/
13
14#include "ruby/internal/config.h"
15
16#ifdef HAVE_SYS_PRCTL_H
17#include <sys/prctl.h>
18#endif
19
20#include "eval_intern.h"
21#include "gc.h"
22#include "internal.h"
23#include "internal/class.h"
24#include "internal/error.h"
25#include "internal/eval.h"
26#include "internal/hash.h"
27#include "internal/inits.h"
28#include "internal/io.h"
29#include "internal/object.h"
30#include "internal/thread.h"
31#include "internal/variable.h"
33#include "iseq.h"
34#include "mjit.h"
35#include "probes.h"
36#include "probes_helper.h"
37#include "ruby/vm.h"
38#include "vm_core.h"
39#include "ractor_core.h"
40
41NORETURN(static void rb_raise_jump(VALUE, VALUE));
42void rb_ec_clear_current_thread_trace_func(const rb_execution_context_t *ec);
43void rb_ec_clear_all_trace_func(const rb_execution_context_t *ec);
44
45static int rb_ec_cleanup(rb_execution_context_t *ec, int ex);
46static int rb_ec_exec_node(rb_execution_context_t *ec, void *n);
47
50
51ID ruby_static_id_signo, ruby_static_id_status;
52extern ID ruby_static_id_cause;
53#define id_cause ruby_static_id_cause
54
55#define exception_error GET_VM()->special_exceptions[ruby_error_reenter]
56
57#include "eval_error.c"
58#include "eval_jump.c"
59
60#define CLASS_OR_MODULE_P(obj) \
61 (!SPECIAL_CONST_P(obj) && \
62 (BUILTIN_TYPE(obj) == T_CLASS || BUILTIN_TYPE(obj) == T_MODULE))
63
64int
66{
67 enum ruby_tag_type state;
68
69 if (GET_VM())
70 return 0;
71
72 ruby_init_stack((void *)&state);
73
74 /*
75 * Disable THP early before mallocs happen because we want this to
76 * affect as many future pages as possible for CoW-friendliness
77 */
78#if defined(__linux__) && defined(PR_SET_THP_DISABLE)
79 prctl(PR_SET_THP_DISABLE, 1, 0, 0, 0);
80#endif
81 Init_BareVM();
82 Init_heap();
83 rb_vm_encoded_insn_data_table_init();
84 Init_vm_objects();
85
86 EC_PUSH_TAG(GET_EC());
87 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
88 rb_call_inits();
90 GET_VM()->running = 1;
91 }
92 EC_POP_TAG();
93
94 return state;
95}
96
97void
99{
100 int state = ruby_setup();
101 if (state) {
102 if (RTEST(ruby_debug))
103 error_print(GET_EC());
104 exit(EXIT_FAILURE);
105 }
106}
107
108void *
109ruby_options(int argc, char **argv)
110{
111 rb_execution_context_t *ec = GET_EC();
112 enum ruby_tag_type state;
113 void *volatile iseq = 0;
114
115 ruby_init_stack((void *)&iseq);
116 EC_PUSH_TAG(ec);
117 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
118 SAVE_ROOT_JMPBUF(GET_THREAD(), iseq = ruby_process_options(argc, argv));
119 }
120 else {
121 rb_ec_clear_current_thread_trace_func(ec);
122 state = error_handle(ec, state);
123 iseq = (void *)INT2FIX(state);
124 }
125 EC_POP_TAG();
126 return iseq;
127}
128
129static void
130rb_ec_fiber_scheduler_finalize(rb_execution_context_t *ec)
131{
132 enum ruby_tag_type state;
133
134 EC_PUSH_TAG(ec);
135 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
137 }
138 else {
139 state = error_handle(ec, state);
140 }
141 EC_POP_TAG();
142}
143
144static void
145rb_ec_teardown(rb_execution_context_t *ec)
146{
147 // If the user code defined a scheduler for the top level thread, run it:
148 rb_ec_fiber_scheduler_finalize(ec);
149
150 EC_PUSH_TAG(ec);
151 if (EC_EXEC_TAG() == TAG_NONE) {
152 rb_vm_trap_exit(rb_ec_vm_ptr(ec));
153 }
154 EC_POP_TAG();
155 rb_ec_exec_end_proc(ec);
156 rb_ec_clear_all_trace_func(ec);
157}
158
159static void
160rb_ec_finalize(rb_execution_context_t *ec)
161{
163 ec->errinfo = Qnil;
164 rb_objspace_call_finalizer(rb_ec_vm_ptr(ec)->objspace);
165}
166
167void
169{
170 rb_execution_context_t *ec = GET_EC();
171 rb_ec_teardown(ec);
172 rb_ec_finalize(ec);
173}
174
175int
177{
178 return rb_ec_cleanup(GET_EC(), ex);
179}
180
181static int
182rb_ec_cleanup(rb_execution_context_t *ec, int ex0)
183{
184 int state;
185 volatile VALUE errs[2] = { Qundef, Qundef };
186 int nerr;
187 rb_thread_t *th = rb_ec_thread_ptr(ec);
188 rb_thread_t *const volatile th0 = th;
189 volatile int sysex = EXIT_SUCCESS;
190 volatile int step = 0;
191 volatile int ex = ex0;
192
193 rb_threadptr_interrupt(th);
194 rb_threadptr_check_signal(th);
195
196 EC_PUSH_TAG(ec);
197 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
198 SAVE_ROOT_JMPBUF(th, { RUBY_VM_CHECK_INTS(ec); });
199
200 step_0: step++;
201 errs[1] = ec->errinfo;
202 if (THROW_DATA_P(ec->errinfo)) ec->errinfo = Qnil;
203 ruby_init_stack(&errs[STACK_UPPER(errs, 0, 1)]);
204
205 SAVE_ROOT_JMPBUF(th, rb_ec_teardown(ec));
206
207 step_1: step++;
208 /* protect from Thread#raise */
209 th->status = THREAD_KILLED;
210
211 errs[0] = ec->errinfo;
212 SAVE_ROOT_JMPBUF(th, rb_ractor_terminate_all());
213 }
214 else {
215 th = th0;
216 switch (step) {
217 case 0: goto step_0;
218 case 1: goto step_1;
219 }
220 if (ex == 0) ex = state;
221 }
222 ec->errinfo = errs[1];
223 sysex = error_handle(ec, ex);
224
225 state = 0;
226 for (nerr = 0; nerr < numberof(errs); ++nerr) {
227 VALUE err = ATOMIC_VALUE_EXCHANGE(errs[nerr], Qnil);
228 VALUE sig;
229
230 if (!RTEST(err)) continue;
231
232 /* ec->errinfo contains a NODE while break'ing */
233 if (THROW_DATA_P(err)) continue;
234
235 if (rb_obj_is_kind_of(err, rb_eSystemExit)) {
236 sysex = sysexit_status(err);
237 break;
238 }
239 else if (rb_obj_is_kind_of(err, rb_eSignal)) {
240 VALUE sig = rb_ivar_get(err, id_signo);
241 state = NUM2INT(sig);
242 break;
243 }
244 else if (rb_obj_is_kind_of(err, rb_eSystemCallError) &&
245 FIXNUM_P(sig = rb_attr_get(err, id_signo))) {
246 state = NUM2INT(sig);
247 break;
248 }
249 else if (sysex == EXIT_SUCCESS) {
250 sysex = EXIT_FAILURE;
251 }
252 }
253
254 mjit_finish(true); // We still need ISeqs here.
255
256 rb_ec_finalize(ec);
257
258 /* unlock again if finalizer took mutexes. */
259 rb_threadptr_unlock_all_locking_mutexes(th);
260 th = th0;
261 EC_POP_TAG();
262 th = th0;
263 rb_thread_stop_timer_thread();
264 ruby_vm_destruct(th->vm);
265 if (state) ruby_default_signal(state);
266
267 return sysex;
268}
269
270static int
271rb_ec_exec_node(rb_execution_context_t *ec, void *n)
272{
273 volatile int state;
274 rb_iseq_t *iseq = (rb_iseq_t *)n;
275 if (!n) return 0;
276
277 EC_PUSH_TAG(ec);
278 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
279 rb_thread_t *const th = rb_ec_thread_ptr(ec);
280 SAVE_ROOT_JMPBUF(th, {
281 rb_iseq_eval_main(iseq);
282 });
283 }
284 EC_POP_TAG();
285 return state;
286}
287
288void
290{
291 exit(ruby_cleanup(ex));
292}
293
294int
295ruby_executable_node(void *n, int *status)
296{
297 VALUE v = (VALUE)n;
298 int s;
299
300 switch (v) {
301 case Qtrue: s = EXIT_SUCCESS; break;
302 case Qfalse: s = EXIT_FAILURE; break;
303 default:
304 if (!FIXNUM_P(v)) return TRUE;
305 s = FIX2INT(v);
306 }
307 if (status) *status = s;
308 return FALSE;
309}
310
311int
313{
314 rb_execution_context_t *ec = GET_EC();
315 int status;
316 if (!ruby_executable_node(n, &status)) {
317 rb_ec_cleanup(ec, 0);
318 return status;
319 }
320 ruby_init_stack((void *)&status);
321 return rb_ec_cleanup(ec, rb_ec_exec_node(ec, n));
322}
323
324int
326{
327 ruby_init_stack((void *)&n);
328 return rb_ec_exec_node(GET_EC(), n);
329}
330
331/*
332 * call-seq:
333 * Module.nesting -> array
334 *
335 * Returns the list of +Modules+ nested at the point of call.
336 *
337 * module M1
338 * module M2
339 * $a = Module.nesting
340 * end
341 * end
342 * $a #=> [M1::M2, M1]
343 * $a[0].name #=> "M1::M2"
344 */
345
346static VALUE
347rb_mod_nesting(VALUE _)
348{
349 VALUE ary = rb_ary_new();
350 const rb_cref_t *cref = rb_vm_cref();
351
352 while (cref && CREF_NEXT(cref)) {
353 VALUE klass = CREF_CLASS(cref);
354 if (!CREF_PUSHED_BY_EVAL(cref) &&
355 !NIL_P(klass)) {
356 rb_ary_push(ary, klass);
357 }
358 cref = CREF_NEXT(cref);
359 }
360 return ary;
361}
362
363/*
364 * call-seq:
365 * Module.constants -> array
366 * Module.constants(inherited) -> array
367 *
368 * In the first form, returns an array of the names of all
369 * constants accessible from the point of call.
370 * This list includes the names of all modules and classes
371 * defined in the global scope.
372 *
373 * Module.constants.first(4)
374 * # => [:ARGF, :ARGV, :ArgumentError, :Array]
375 *
376 * Module.constants.include?(:SEEK_SET) # => false
377 *
378 * class IO
379 * Module.constants.include?(:SEEK_SET) # => true
380 * end
381 *
382 * The second form calls the instance method +constants+.
383 */
384
385static VALUE
386rb_mod_s_constants(int argc, VALUE *argv, VALUE mod)
387{
388 const rb_cref_t *cref = rb_vm_cref();
389 VALUE klass;
390 VALUE cbase = 0;
391 void *data = 0;
392
393 if (argc > 0 || mod != rb_cModule) {
394 return rb_mod_constants(argc, argv, mod);
395 }
396
397 while (cref) {
398 klass = CREF_CLASS(cref);
399 if (!CREF_PUSHED_BY_EVAL(cref) &&
400 !NIL_P(klass)) {
401 data = rb_mod_const_at(CREF_CLASS(cref), data);
402 if (!cbase) {
403 cbase = klass;
404 }
405 }
406 cref = CREF_NEXT(cref);
407 }
408
409 if (cbase) {
410 data = rb_mod_const_of(cbase, data);
411 }
412 return rb_const_list(data);
413}
414
421void
423{
424 if (SPECIAL_CONST_P(klass)) {
425 Check_Type(klass, T_CLASS);
426 }
427 if (RB_TYPE_P(klass, T_MODULE)) {
428 rb_module_set_initialized(klass);
429 }
430 if (OBJ_FROZEN(klass)) {
431 const char *desc;
432
433 if (FL_TEST(klass, FL_SINGLETON)) {
434 desc = "object";
435 klass = rb_ivar_get(klass, id__attached__);
436 if (!SPECIAL_CONST_P(klass)) {
437 switch (BUILTIN_TYPE(klass)) {
438 case T_MODULE:
439 case T_ICLASS:
440 desc = "Module";
441 break;
442 case T_CLASS:
443 desc = "Class";
444 break;
445 default:
446 break;
447 }
448 }
449 }
450 else {
451 switch (BUILTIN_TYPE(klass)) {
452 case T_MODULE:
453 case T_ICLASS:
454 desc = "module";
455 break;
456 case T_CLASS:
457 desc = "class";
458 break;
459 default:
460 Check_Type(klass, T_CLASS);
462 }
463 }
464 rb_frozen_error_raise(klass, "can't modify frozen %s: %"PRIsVALUE, desc, klass);
465 }
466}
467
468NORETURN(static void rb_longjmp(rb_execution_context_t *, int, volatile VALUE, VALUE));
469static VALUE get_errinfo(void);
470#define get_ec_errinfo(ec) rb_ec_get_errinfo(ec)
471
472static VALUE
473exc_setup_cause(VALUE exc, VALUE cause)
474{
475#if OPT_SUPPORT_JOKE
476 if (NIL_P(cause)) {
477 ID id_true_cause;
478 CONST_ID(id_true_cause, "true_cause");
479
480 cause = rb_attr_get(rb_eFatal, id_true_cause);
481 if (NIL_P(cause)) {
482 cause = rb_exc_new_cstr(rb_eFatal, "because using such Ruby");
483 rb_ivar_set(cause, id_cause, INT2FIX(42)); /* the answer */
484 OBJ_FREEZE(cause);
485 rb_ivar_set(rb_eFatal, id_true_cause, cause);
486 }
487 }
488#endif
489 if (!NIL_P(cause) && cause != exc) {
490 rb_ivar_set(exc, id_cause, cause);
491 if (!rb_ivar_defined(cause, id_cause)) {
492 rb_ivar_set(cause, id_cause, Qnil);
493 }
494 }
495 return exc;
496}
497
498static inline VALUE
499exc_setup_message(const rb_execution_context_t *ec, VALUE mesg, VALUE *cause)
500{
501 int nocause = 0;
502 int nocircular = 0;
503
504 if (NIL_P(mesg)) {
505 mesg = ec->errinfo;
506 if (INTERNAL_EXCEPTION_P(mesg)) EC_JUMP_TAG(ec, TAG_FATAL);
507 nocause = 1;
508 }
509 if (NIL_P(mesg)) {
510 mesg = rb_exc_new(rb_eRuntimeError, 0, 0);
511 nocause = 0;
512 nocircular = 1;
513 }
514 if (*cause == Qundef) {
515 if (nocause) {
516 *cause = Qnil;
517 nocircular = 1;
518 }
519 else if (!rb_ivar_defined(mesg, id_cause)) {
520 *cause = get_ec_errinfo(ec);
521 }
522 else {
523 nocircular = 1;
524 }
525 }
526 else if (!NIL_P(*cause) && !rb_obj_is_kind_of(*cause, rb_eException)) {
527 rb_raise(rb_eTypeError, "exception object expected");
528 }
529
530 if (!nocircular && !NIL_P(*cause) && *cause != Qundef && *cause != mesg) {
531 VALUE c = *cause;
532 while (!NIL_P(c = rb_attr_get(c, id_cause))) {
533 if (c == mesg) {
534 rb_raise(rb_eArgError, "circular causes");
535 }
536 }
537 }
538 return mesg;
539}
540
541static void
542setup_exception(rb_execution_context_t *ec, int tag, volatile VALUE mesg, VALUE cause)
543{
544 VALUE e;
545 int line;
546 const char *file = rb_source_location_cstr(&line);
547 const char *const volatile file0 = file;
548
549 if ((file && !NIL_P(mesg)) || (cause != Qundef)) {
550 volatile int state = 0;
551
552 EC_PUSH_TAG(ec);
553 if (EC_EXEC_TAG() == TAG_NONE && !(state = rb_ec_set_raised(ec))) {
554 VALUE bt = rb_get_backtrace(mesg);
555 if (!NIL_P(bt) || cause == Qundef) {
556 if (OBJ_FROZEN(mesg)) {
557 mesg = rb_obj_dup(mesg);
558 }
559 }
560 if (cause != Qundef && !THROW_DATA_P(cause)) {
561 exc_setup_cause(mesg, cause);
562 }
563 if (NIL_P(bt)) {
564 VALUE at = rb_ec_backtrace_object(ec);
565 rb_ivar_set(mesg, idBt_locations, at);
566 set_backtrace(mesg, at);
567 }
568 rb_ec_reset_raised(ec);
569 }
570 EC_POP_TAG();
571 file = file0;
572 if (state) goto fatal;
573 }
574
575 if (!NIL_P(mesg)) {
576 ec->errinfo = mesg;
577 }
578
579 if (RTEST(ruby_debug) && !NIL_P(e = ec->errinfo) &&
580 !rb_obj_is_kind_of(e, rb_eSystemExit)) {
581 enum ruby_tag_type state;
582
583 mesg = e;
584 EC_PUSH_TAG(ec);
585 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
586 ec->errinfo = Qnil;
587 e = rb_obj_as_string(mesg);
588 ec->errinfo = mesg;
589 if (file && line) {
590 e = rb_sprintf("Exception `%"PRIsVALUE"' at %s:%d - %"PRIsVALUE"\n",
591 rb_obj_class(mesg), file, line, e);
592 }
593 else if (file) {
594 e = rb_sprintf("Exception `%"PRIsVALUE"' at %s - %"PRIsVALUE"\n",
595 rb_obj_class(mesg), file, e);
596 }
597 else {
598 e = rb_sprintf("Exception `%"PRIsVALUE"' - %"PRIsVALUE"\n",
599 rb_obj_class(mesg), e);
600 }
601 warn_print_str(e);
602 }
603 EC_POP_TAG();
604 if (state == TAG_FATAL && ec->errinfo == exception_error) {
605 ec->errinfo = mesg;
606 }
607 else if (state) {
608 rb_ec_reset_raised(ec);
609 EC_JUMP_TAG(ec, state);
610 }
611 }
612
613 if (rb_ec_set_raised(ec)) {
614 goto fatal;
615 }
616
617 if (tag != TAG_FATAL) {
618 RUBY_DTRACE_HOOK(RAISE, rb_obj_classname(ec->errinfo));
619 EXEC_EVENT_HOOK(ec, RUBY_EVENT_RAISE, ec->cfp->self, 0, 0, 0, mesg);
620 }
621 return;
622
623 fatal:
624 ec->errinfo = exception_error;
625 rb_ec_reset_raised(ec);
626 EC_JUMP_TAG(ec, TAG_FATAL);
627}
628
630void
631rb_ec_setup_exception(const rb_execution_context_t *ec, VALUE mesg, VALUE cause)
632{
633 if (cause == Qundef) {
634 cause = get_ec_errinfo(ec);
635 }
636 if (cause != mesg) {
637 rb_ivar_set(mesg, id_cause, cause);
638 }
639}
640
641static void
642rb_longjmp(rb_execution_context_t *ec, int tag, volatile VALUE mesg, VALUE cause)
643{
644 mesg = exc_setup_message(ec, mesg, &cause);
645 setup_exception(ec, tag, mesg, cause);
646 rb_ec_raised_clear(ec);
647 EC_JUMP_TAG(ec, tag);
648}
649
650static VALUE make_exception(int argc, const VALUE *argv, int isstr);
651
652NORETURN(static void rb_exc_exception(VALUE mesg, int tag, VALUE cause));
653
654static void
655rb_exc_exception(VALUE mesg, int tag, VALUE cause)
656{
657 if (!NIL_P(mesg)) {
658 mesg = make_exception(1, &mesg, FALSE);
659 }
660 rb_longjmp(GET_EC(), tag, mesg, cause);
661}
662
670void
671rb_exc_raise(VALUE mesg)
672{
673 rb_exc_exception(mesg, TAG_RAISE, Qundef);
674}
675
683void
684rb_exc_fatal(VALUE mesg)
685{
686 rb_exc_exception(mesg, TAG_FATAL, Qnil);
687}
688
689void
691{
692 rb_exc_raise(rb_exc_new(rb_eInterrupt, 0, 0));
693}
694
695enum {raise_opt_cause, raise_max_opt}; /*< \private */
696
697static int
698extract_raise_opts(int argc, const VALUE *argv, VALUE *opts)
699{
700 int i;
701 if (argc > 0) {
702 VALUE opt = argv[argc-1];
703 if (RB_TYPE_P(opt, T_HASH)) {
704 if (!RHASH_EMPTY_P(opt)) {
705 ID keywords[1];
706 CONST_ID(keywords[0], "cause");
707 rb_get_kwargs(opt, keywords, 0, -1-raise_max_opt, opts);
708 if (RHASH_EMPTY_P(opt)) --argc;
709 return argc;
710 }
711 }
712 }
713 for (i = 0; i < raise_max_opt; ++i) {
714 opts[i] = Qundef;
715 }
716 return argc;
717}
718
719VALUE
720rb_f_raise(int argc, VALUE *argv)
721{
722 VALUE err;
723 VALUE opts[raise_max_opt], *const cause = &opts[raise_opt_cause];
724
725 argc = extract_raise_opts(argc, argv, opts);
726 if (argc == 0) {
727 if (*cause != Qundef) {
728 rb_raise(rb_eArgError, "only cause is given with no arguments");
729 }
730 err = get_errinfo();
731 if (!NIL_P(err)) {
732 argc = 1;
733 argv = &err;
734 }
735 }
736 rb_raise_jump(rb_make_exception(argc, argv), *cause);
737
739}
740
741/*
742 * call-seq:
743 * raise
744 * raise(string, cause: $!)
745 * raise(exception [, string [, array]], cause: $!)
746 * fail
747 * fail(string, cause: $!)
748 * fail(exception [, string [, array]], cause: $!)
749 *
750 * With no arguments, raises the exception in <code>$!</code> or raises
751 * a RuntimeError if <code>$!</code> is +nil+. With a single +String+
752 * argument, raises a +RuntimeError+ with the string as a message. Otherwise,
753 * the first parameter should be an +Exception+ class (or another
754 * object that returns an +Exception+ object when sent an +exception+
755 * message). The optional second parameter sets the message associated with
756 * the exception (accessible via Exception#message), and the third parameter
757 * is an array of callback information (accessible via Exception#backtrace).
758 * The +cause+ of the generated exception (accessible via Exception#cause)
759 * is automatically set to the "current" exception (<code>$!</code>), if any.
760 * An alternative value, either an +Exception+ object or +nil+, can be
761 * specified via the +:cause+ argument.
762 *
763 * Exceptions are caught by the +rescue+ clause of
764 * <code>begin...end</code> blocks.
765 *
766 * raise "Failed to create socket"
767 * raise ArgumentError, "No parameters", caller
768 */
769
770static VALUE
771f_raise(int c, VALUE *v, VALUE _)
772{
773 return rb_f_raise(c, v);
774}
775
776static VALUE
777make_exception(int argc, const VALUE *argv, int isstr)
778{
779 VALUE mesg, exc;
780
781 mesg = Qnil;
782 switch (argc) {
783 case 0:
784 return Qnil;
785 case 1:
786 exc = argv[0];
787 if (isstr &&! NIL_P(exc)) {
788 mesg = rb_check_string_type(exc);
789 if (!NIL_P(mesg)) {
790 return rb_exc_new3(rb_eRuntimeError, mesg);
791 }
792 }
793
794 case 2:
795 case 3:
796 break;
797 default:
798 rb_error_arity(argc, 0, 3);
799 }
800 if (NIL_P(mesg)) {
801 mesg = rb_check_funcall(argv[0], idException, argc != 1, &argv[1]);
802 }
803 if (mesg == Qundef) {
804 rb_raise(rb_eTypeError, "exception class/object expected");
805 }
806 if (!rb_obj_is_kind_of(mesg, rb_eException)) {
807 rb_raise(rb_eTypeError, "exception object expected");
808 }
809 if (argc == 3) {
810 set_backtrace(mesg, argv[2]);
811 }
812
813 return mesg;
814}
815
816VALUE
817rb_make_exception(int argc, const VALUE *argv)
818{
819 return make_exception(argc, argv, TRUE);
820}
821
824static void
825rb_raise_jump(VALUE mesg, VALUE cause)
826{
827 rb_execution_context_t *ec = GET_EC();
828 const rb_control_frame_t *cfp = ec->cfp;
829 const rb_callable_method_entry_t *me = rb_vm_frame_method_entry(cfp);
830 VALUE klass = me->owner;
831 VALUE self = cfp->self;
832 ID mid = me->called_id;
833
834 rb_vm_pop_frame(ec);
835 EXEC_EVENT_HOOK(ec, RUBY_EVENT_C_RETURN, self, me->def->original_id, mid, klass, Qnil);
836
837 rb_longjmp(ec, TAG_RAISE, mesg, cause);
838}
839
840void
842{
843 if (UNLIKELY(tag < TAG_RETURN || tag > TAG_FATAL)) {
844 unknown_longjmp_status(tag);
845 }
846 EC_JUMP_TAG(GET_EC(), tag);
847}
848
849int
851{
852 if (rb_vm_frame_block_handler(GET_EC()->cfp) == VM_BLOCK_HANDLER_NONE) {
853 return FALSE;
854 }
855 else {
856 return TRUE;
857 }
858}
859
860int rb_vm_cframe_keyword_p(const rb_control_frame_t *cfp);
861
862int
864{
865 return rb_vm_cframe_keyword_p(GET_EC()->cfp);
866}
867
869
870void
872{
873 if (!rb_block_given_p()) {
874 rb_vm_localjump_error("no block given", Qnil, 0);
875 }
876}
877
878VALUE
879rb_rescue2(VALUE (* b_proc) (VALUE), VALUE data1,
880 VALUE (* r_proc) (VALUE, VALUE), VALUE data2, ...)
881{
882 va_list ap;
883 va_start(ap, data2);
884 VALUE ret = rb_vrescue2(b_proc, data1, r_proc, data2, ap);
885 va_end(ap);
886 return ret;
887}
888
889VALUE
890rb_vrescue2(VALUE (* b_proc) (VALUE), VALUE data1,
891 VALUE (* r_proc) (VALUE, VALUE), VALUE data2,
892 va_list args)
893{
894 enum ruby_tag_type state;
895 rb_execution_context_t * volatile ec = GET_EC();
896 rb_control_frame_t *volatile cfp = ec->cfp;
897 volatile VALUE result = Qfalse;
898 volatile VALUE e_info = ec->errinfo;
899
900 EC_PUSH_TAG(ec);
901 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
902 retry_entry:
903 result = (*b_proc) (data1);
904 }
905 else if (result) {
906 /* escape from r_proc */
907 if (state == TAG_RETRY) {
908 state = TAG_NONE;
909 ec->errinfo = Qnil;
910 result = Qfalse;
911 goto retry_entry;
912 }
913 }
914 else {
915 rb_vm_rewind_cfp(ec, cfp);
916
917 if (state == TAG_RAISE) {
918 int handle = FALSE;
919 VALUE eclass;
920 va_list ap;
921
922 result = Qnil;
923 /* reuses args when raised again after retrying in r_proc */
924 va_copy(ap, args);
925 while ((eclass = va_arg(ap, VALUE)) != 0) {
926 if (rb_obj_is_kind_of(ec->errinfo, eclass)) {
927 handle = TRUE;
928 break;
929 }
930 }
931 va_end(ap);
932
933 if (handle) {
934 state = TAG_NONE;
935 if (r_proc) {
936 result = (*r_proc) (data2, ec->errinfo);
937 }
938 ec->errinfo = e_info;
939 }
940 }
941 }
942 EC_POP_TAG();
943 if (state)
944 EC_JUMP_TAG(ec, state);
945
946 return result;
947}
948
949VALUE
950rb_rescue(VALUE (* b_proc)(VALUE), VALUE data1,
951 VALUE (* r_proc)(VALUE, VALUE), VALUE data2)
952{
953 return rb_rescue2(b_proc, data1, r_proc, data2, rb_eStandardError,
954 (VALUE)0);
955}
956
957VALUE
958rb_protect(VALUE (* proc) (VALUE), VALUE data, int *pstate)
959{
960 volatile VALUE result = Qnil;
961 volatile enum ruby_tag_type state;
962 rb_execution_context_t * volatile ec = GET_EC();
963 rb_control_frame_t *volatile cfp = ec->cfp;
964
965 EC_PUSH_TAG(ec);
966 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
967 SAVE_ROOT_JMPBUF(rb_ec_thread_ptr(ec), result = (*proc) (data));
968 }
969 else {
970 rb_vm_rewind_cfp(ec, cfp);
971 }
972 EC_POP_TAG();
973
974 if (pstate != NULL) *pstate = state;
975 return result;
976}
977
978VALUE
979rb_ensure(VALUE (*b_proc)(VALUE), VALUE data1, VALUE (*e_proc)(VALUE), VALUE data2)
980{
981 int state;
982 volatile VALUE result = Qnil;
983 VALUE errinfo;
984 rb_execution_context_t * volatile ec = GET_EC();
985 rb_ensure_list_t ensure_list;
986 ensure_list.entry.marker = 0;
987 ensure_list.entry.e_proc = e_proc;
988 ensure_list.entry.data2 = data2;
989 ensure_list.next = ec->ensure_list;
990 ec->ensure_list = &ensure_list;
991 EC_PUSH_TAG(ec);
992 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
993 result = (*b_proc) (data1);
994 }
995 EC_POP_TAG();
996 errinfo = ec->errinfo;
997 if (!NIL_P(errinfo) && !RB_TYPE_P(errinfo, T_OBJECT)) {
998 ec->errinfo = Qnil;
999 }
1000 ec->ensure_list=ensure_list.next;
1001 (*ensure_list.entry.e_proc)(ensure_list.entry.data2);
1002 ec->errinfo = errinfo;
1003 if (state)
1004 EC_JUMP_TAG(ec, state);
1005 return result;
1006}
1007
1008static ID
1009frame_func_id(const rb_control_frame_t *cfp)
1010{
1011 const rb_callable_method_entry_t *me = rb_vm_frame_method_entry(cfp);
1012
1013 if (me) {
1014 return me->def->original_id;
1015 }
1016 else {
1017 return 0;
1018 }
1019}
1020
1021static ID
1022frame_called_id(rb_control_frame_t *cfp)
1023{
1024 const rb_callable_method_entry_t *me = rb_vm_frame_method_entry(cfp);
1025
1026 if (me) {
1027 return me->called_id;
1028 }
1029 else {
1030 return 0;
1031 }
1032}
1033
1034ID
1036{
1037 return frame_func_id(GET_EC()->cfp);
1038}
1039
1040ID
1042{
1043 return frame_called_id(GET_EC()->cfp);
1044}
1045
1046static rb_control_frame_t *
1047previous_frame(const rb_execution_context_t *ec)
1048{
1049 rb_control_frame_t *prev_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(ec->cfp);
1050 /* check if prev_cfp can be accessible */
1051 if ((void *)(ec->vm_stack + ec->vm_stack_size) == (void *)(prev_cfp)) {
1052 return 0;
1053 }
1054 return prev_cfp;
1055}
1056
1057static ID
1058prev_frame_callee(void)
1059{
1060 rb_control_frame_t *prev_cfp = previous_frame(GET_EC());
1061 if (!prev_cfp) return 0;
1062 return frame_called_id(prev_cfp);
1063}
1064
1065static ID
1066prev_frame_func(void)
1067{
1068 rb_control_frame_t *prev_cfp = previous_frame(GET_EC());
1069 if (!prev_cfp) return 0;
1070 return frame_func_id(prev_cfp);
1071}
1072
1079ID
1081{
1082 const rb_execution_context_t *ec = GET_EC();
1083 const rb_control_frame_t *cfp = ec->cfp;
1084 ID mid;
1085
1086 while (!(mid = frame_func_id(cfp)) &&
1087 (cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp),
1088 !RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(ec, cfp)));
1089 return mid;
1090}
1091
1092/*
1093 * call-seq:
1094 * append_features(mod) -> mod
1095 *
1096 * When this module is included in another, Ruby calls
1097 * #append_features in this module, passing it the receiving module
1098 * in _mod_. Ruby's default implementation is to add the constants,
1099 * methods, and module variables of this module to _mod_ if this
1100 * module has not already been added to _mod_ or one of its
1101 * ancestors. See also Module#include.
1102 */
1103
1104static VALUE
1105rb_mod_append_features(VALUE module, VALUE include)
1106{
1107 if (!CLASS_OR_MODULE_P(include)) {
1108 Check_Type(include, T_CLASS);
1109 }
1110 rb_include_module(include, module);
1111
1112 return module;
1113}
1114
1115/*
1116 * call-seq:
1117 * include(module, ...) -> self
1118 *
1119 * Invokes Module.append_features on each parameter in reverse order.
1120 */
1121
1122static VALUE
1123rb_mod_include(int argc, VALUE *argv, VALUE module)
1124{
1125 int i;
1126 ID id_append_features, id_included;
1127
1128 CONST_ID(id_append_features, "append_features");
1129 CONST_ID(id_included, "included");
1130
1131 if (FL_TEST(module, RMODULE_IS_REFINEMENT)) {
1132 rb_warn_deprecated_to_remove_at(3.2, "Refinement#include", NULL);
1133 }
1134
1136 for (i = 0; i < argc; i++)
1137 Check_Type(argv[i], T_MODULE);
1138 while (argc--) {
1139 rb_funcall(argv[argc], id_append_features, 1, module);
1140 rb_funcall(argv[argc], id_included, 1, module);
1141 }
1142 return module;
1143}
1144
1145/*
1146 * call-seq:
1147 * prepend_features(mod) -> mod
1148 *
1149 * When this module is prepended in another, Ruby calls
1150 * #prepend_features in this module, passing it the receiving module
1151 * in _mod_. Ruby's default implementation is to overlay the
1152 * constants, methods, and module variables of this module to _mod_
1153 * if this module has not already been added to _mod_ or one of its
1154 * ancestors. See also Module#prepend.
1155 */
1156
1157static VALUE
1158rb_mod_prepend_features(VALUE module, VALUE prepend)
1159{
1160 if (!CLASS_OR_MODULE_P(prepend)) {
1161 Check_Type(prepend, T_CLASS);
1162 }
1163 rb_prepend_module(prepend, module);
1164
1165 return module;
1166}
1167
1168/*
1169 * call-seq:
1170 * prepend(module, ...) -> self
1171 *
1172 * Invokes Module.prepend_features on each parameter in reverse order.
1173 */
1174
1175static VALUE
1176rb_mod_prepend(int argc, VALUE *argv, VALUE module)
1177{
1178 int i;
1179 ID id_prepend_features, id_prepended;
1180
1181 if (FL_TEST(module, RMODULE_IS_REFINEMENT)) {
1182 rb_warn_deprecated_to_remove_at(3.2, "Refinement#prepend", NULL);
1183 }
1184
1185 CONST_ID(id_prepend_features, "prepend_features");
1186 CONST_ID(id_prepended, "prepended");
1187
1189 for (i = 0; i < argc; i++)
1190 Check_Type(argv[i], T_MODULE);
1191 while (argc--) {
1192 rb_funcall(argv[argc], id_prepend_features, 1, module);
1193 rb_funcall(argv[argc], id_prepended, 1, module);
1194 }
1195 return module;
1196}
1197
1198static void
1199ensure_class_or_module(VALUE obj)
1200{
1201 if (!RB_TYPE_P(obj, T_CLASS) && !RB_TYPE_P(obj, T_MODULE)) {
1202 rb_raise(rb_eTypeError,
1203 "wrong argument type %"PRIsVALUE" (expected Class or Module)",
1204 rb_obj_class(obj));
1205 }
1206}
1207
1208static VALUE
1209hidden_identity_hash_new(void)
1210{
1211 VALUE hash = rb_ident_hash_new();
1212
1213 RBASIC_CLEAR_CLASS(hash); /* hide from ObjectSpace */
1214 return hash;
1215}
1216
1217static VALUE
1218refinement_superclass(VALUE superclass)
1219{
1220 if (RB_TYPE_P(superclass, T_MODULE)) {
1221 /* FIXME: Should ancestors of superclass be used here? */
1222 return rb_include_class_new(RCLASS_ORIGIN(superclass), rb_cBasicObject);
1223 }
1224 else {
1225 return superclass;
1226 }
1227}
1228
1232static void
1233rb_using_refinement(rb_cref_t *cref, VALUE klass, VALUE module)
1234{
1235 VALUE iclass, c, superclass = klass;
1236
1237 ensure_class_or_module(klass);
1238 Check_Type(module, T_MODULE);
1239 if (NIL_P(CREF_REFINEMENTS(cref))) {
1240 CREF_REFINEMENTS_SET(cref, hidden_identity_hash_new());
1241 }
1242 else {
1243 if (CREF_OMOD_SHARED(cref)) {
1244 CREF_REFINEMENTS_SET(cref, rb_hash_dup(CREF_REFINEMENTS(cref)));
1245 CREF_OMOD_SHARED_UNSET(cref);
1246 }
1247 if (!NIL_P(c = rb_hash_lookup(CREF_REFINEMENTS(cref), klass))) {
1248 superclass = c;
1249 while (c && RB_TYPE_P(c, T_ICLASS)) {
1250 if (RBASIC(c)->klass == module) {
1251 /* already used refinement */
1252 return;
1253 }
1254 c = RCLASS_SUPER(c);
1255 }
1256 }
1257 }
1258 FL_SET(module, RMODULE_IS_OVERLAID);
1259 superclass = refinement_superclass(superclass);
1260 c = iclass = rb_include_class_new(module, superclass);
1261 RB_OBJ_WRITE(c, &RCLASS_REFINED_CLASS(c), klass);
1262
1263 RCLASS_M_TBL(c) = RCLASS_M_TBL(module);
1264
1265 module = RCLASS_SUPER(module);
1266 while (module && module != klass) {
1267 FL_SET(module, RMODULE_IS_OVERLAID);
1268 c = RCLASS_SET_SUPER(c, rb_include_class_new(module, RCLASS_SUPER(c)));
1269 RB_OBJ_WRITE(c, &RCLASS_REFINED_CLASS(c), klass);
1270 module = RCLASS_SUPER(module);
1271 }
1272 rb_hash_aset(CREF_REFINEMENTS(cref), klass, iclass);
1273}
1274
1275static int
1276using_refinement(VALUE klass, VALUE module, VALUE arg)
1277{
1278 rb_cref_t *cref = (rb_cref_t *) arg;
1279
1280 rb_using_refinement(cref, klass, module);
1281 return ST_CONTINUE;
1282}
1283
1284static void
1285using_module_recursive(const rb_cref_t *cref, VALUE klass)
1286{
1287 ID id_refinements;
1288 VALUE super, module, refinements;
1289
1290 super = RCLASS_SUPER(klass);
1291 if (super) {
1292 using_module_recursive(cref, super);
1293 }
1294 switch (BUILTIN_TYPE(klass)) {
1295 case T_MODULE:
1296 module = klass;
1297 break;
1298
1299 case T_ICLASS:
1300 module = RBASIC(klass)->klass;
1301 break;
1302
1303 default:
1304 rb_raise(rb_eTypeError, "wrong argument type %s (expected Module)",
1305 rb_obj_classname(klass));
1306 break;
1307 }
1308 CONST_ID(id_refinements, "__refinements__");
1309 refinements = rb_attr_get(module, id_refinements);
1310 if (NIL_P(refinements)) return;
1311 rb_hash_foreach(refinements, using_refinement, (VALUE) cref);
1312}
1313
1317static void
1318rb_using_module(const rb_cref_t *cref, VALUE module)
1319{
1320 Check_Type(module, T_MODULE);
1321 using_module_recursive(cref, module);
1322 rb_clear_method_cache_all();
1323}
1324
1326VALUE
1327rb_refinement_module_get_refined_class(VALUE module)
1328{
1329 ID id_refined_class;
1330
1331 CONST_ID(id_refined_class, "__refined_class__");
1332 return rb_attr_get(module, id_refined_class);
1333}
1334
1335static void
1336add_activated_refinement(VALUE activated_refinements,
1337 VALUE klass, VALUE refinement)
1338{
1339 VALUE iclass, c, superclass = klass;
1340
1341 if (!NIL_P(c = rb_hash_lookup(activated_refinements, klass))) {
1342 superclass = c;
1343 while (c && RB_TYPE_P(c, T_ICLASS)) {
1344 if (RBASIC(c)->klass == refinement) {
1345 /* already used refinement */
1346 return;
1347 }
1348 c = RCLASS_SUPER(c);
1349 }
1350 }
1351 FL_SET(refinement, RMODULE_IS_OVERLAID);
1352 superclass = refinement_superclass(superclass);
1353 c = iclass = rb_include_class_new(refinement, superclass);
1354 RB_OBJ_WRITE(c, &RCLASS_REFINED_CLASS(c), klass);
1355 refinement = RCLASS_SUPER(refinement);
1356 while (refinement && refinement != klass) {
1357 FL_SET(refinement, RMODULE_IS_OVERLAID);
1358 c = RCLASS_SET_SUPER(c, rb_include_class_new(refinement, RCLASS_SUPER(c)));
1359 RB_OBJ_WRITE(c, &RCLASS_REFINED_CLASS(c), klass);
1360 refinement = RCLASS_SUPER(refinement);
1361 }
1362 rb_hash_aset(activated_refinements, klass, iclass);
1363}
1364
1365/*
1366 * call-seq:
1367 * refine(mod) { block } -> module
1368 *
1369 * Refine <i>mod</i> in the receiver.
1370 *
1371 * Returns a module, where refined methods are defined.
1372 */
1373
1374static VALUE
1375rb_mod_refine(VALUE module, VALUE klass)
1376{
1377 VALUE refinement;
1378 ID id_refinements, id_activated_refinements,
1379 id_refined_class, id_defined_at;
1380 VALUE refinements, activated_refinements;
1381 rb_thread_t *th = GET_THREAD();
1382 VALUE block_handler = rb_vm_frame_block_handler(th->ec->cfp);
1383
1384 if (block_handler == VM_BLOCK_HANDLER_NONE) {
1385 rb_raise(rb_eArgError, "no block given");
1386 }
1387 if (vm_block_handler_type(block_handler) != block_handler_type_iseq) {
1388 rb_raise(rb_eArgError, "can't pass a Proc as a block to Module#refine");
1389 }
1390
1391 ensure_class_or_module(klass);
1392 CONST_ID(id_refinements, "__refinements__");
1393 refinements = rb_attr_get(module, id_refinements);
1394 if (NIL_P(refinements)) {
1395 refinements = hidden_identity_hash_new();
1396 rb_ivar_set(module, id_refinements, refinements);
1397 }
1398 CONST_ID(id_activated_refinements, "__activated_refinements__");
1399 activated_refinements = rb_attr_get(module, id_activated_refinements);
1400 if (NIL_P(activated_refinements)) {
1401 activated_refinements = hidden_identity_hash_new();
1402 rb_ivar_set(module, id_activated_refinements,
1403 activated_refinements);
1404 }
1405 refinement = rb_hash_lookup(refinements, klass);
1406 if (NIL_P(refinement)) {
1407 VALUE superclass = refinement_superclass(klass);
1408 refinement = rb_refinement_new();
1409 RCLASS_SET_SUPER(refinement, superclass);
1410 FL_SET(refinement, RMODULE_IS_REFINEMENT);
1411 CONST_ID(id_refined_class, "__refined_class__");
1412 rb_ivar_set(refinement, id_refined_class, klass);
1413 CONST_ID(id_defined_at, "__defined_at__");
1414 rb_ivar_set(refinement, id_defined_at, module);
1415 rb_hash_aset(refinements, klass, refinement);
1416 add_activated_refinement(activated_refinements, klass, refinement);
1417 }
1418 rb_yield_refine_block(refinement, activated_refinements);
1419 return refinement;
1420}
1421
1422static void
1423ignored_block(VALUE module, const char *klass)
1424{
1425 const char *anon = "";
1426 Check_Type(module, T_MODULE);
1427 if (!RTEST(rb_search_class_path(module))) {
1428 anon = ", maybe for Module.new";
1429 }
1430 rb_warn("%s""using doesn't call the given block""%s.", klass, anon);
1431}
1432
1433/*
1434 * call-seq:
1435 * using(module) -> self
1436 *
1437 * Import class refinements from <i>module</i> into the current class or
1438 * module definition.
1439 */
1440
1441static VALUE
1442mod_using(VALUE self, VALUE module)
1443{
1444 rb_control_frame_t *prev_cfp = previous_frame(GET_EC());
1445
1446 if (prev_frame_func()) {
1447 rb_raise(rb_eRuntimeError,
1448 "Module#using is not permitted in methods");
1449 }
1450 if (prev_cfp && prev_cfp->self != self) {
1451 rb_raise(rb_eRuntimeError, "Module#using is not called on self");
1452 }
1453 if (rb_block_given_p()) {
1454 ignored_block(module, "Module#");
1455 }
1456 rb_using_module(rb_vm_cref_replace_with_duplicated_cref(), module);
1457 return self;
1458}
1459
1460static int
1461used_modules_i(VALUE _, VALUE mod, VALUE ary)
1462{
1463 ID id_defined_at;
1464 CONST_ID(id_defined_at, "__defined_at__");
1465 while (FL_TEST(rb_class_of(mod), RMODULE_IS_REFINEMENT)) {
1466 rb_ary_push(ary, rb_attr_get(rb_class_of(mod), id_defined_at));
1467 mod = RCLASS_SUPER(mod);
1468 }
1469 return ST_CONTINUE;
1470}
1471
1472/*
1473 * call-seq:
1474 * used_modules -> array
1475 *
1476 * Returns an array of all modules used in the current scope. The ordering
1477 * of modules in the resulting array is not defined.
1478 *
1479 * module A
1480 * refine Object do
1481 * end
1482 * end
1483 *
1484 * module B
1485 * refine Object do
1486 * end
1487 * end
1488 *
1489 * using A
1490 * using B
1491 * p Module.used_modules
1492 *
1493 * <em>produces:</em>
1494 *
1495 * [B, A]
1496 */
1497static VALUE
1498rb_mod_s_used_modules(VALUE _)
1499{
1500 const rb_cref_t *cref = rb_vm_cref();
1501 VALUE ary = rb_ary_new();
1502
1503 while (cref) {
1504 if (!NIL_P(CREF_REFINEMENTS(cref))) {
1505 rb_hash_foreach(CREF_REFINEMENTS(cref), used_modules_i, ary);
1506 }
1507 cref = CREF_NEXT(cref);
1508 }
1509
1510 return rb_funcall(ary, rb_intern("uniq"), 0);
1511}
1512
1514 rb_cref_t *cref;
1515 VALUE refinement;
1516 VALUE module;
1517};
1518
1519/* vm.c */
1520rb_cref_t *rb_vm_cref_dup_without_refinements(const rb_cref_t *cref);
1521
1522static enum rb_id_table_iterator_result
1523refinement_import_methods_i(ID key, VALUE value, void *data)
1524{
1525 const rb_method_entry_t *me = (const rb_method_entry_t *)value;
1527
1528 if (me->def->type != VM_METHOD_TYPE_ISEQ) {
1529 rb_raise(rb_eArgError, "Can't import method which is not defined with Ruby code: %"PRIsVALUE"#%"PRIsVALUE, rb_class_path(arg->module), rb_id2str(key));
1530 }
1531 rb_cref_t *new_cref = rb_vm_cref_dup_without_refinements(me->def->body.iseq.cref);
1532 CREF_REFINEMENTS_SET(new_cref, CREF_REFINEMENTS(arg->cref));
1533 rb_add_method_iseq(arg->refinement, key, me->def->body.iseq.iseqptr, new_cref, METHOD_ENTRY_VISI(me));
1534 return ID_TABLE_CONTINUE;
1535}
1536
1537/*
1538 * Note: docs for the method are in class.c
1539 */
1540
1541static VALUE
1542refinement_import_methods(int argc, VALUE *argv, VALUE refinement)
1543{
1544 int i;
1546
1548 for (i = 0; i < argc; i++) {
1549 Check_Type(argv[i], T_MODULE);
1550 if (RCLASS_SUPER(argv[i])) {
1551 rb_warn("%"PRIsVALUE" has ancestors, but Refinement#import_methods doesn't import their methods", rb_class_path(argv[i]));
1552 }
1553 }
1554 arg.cref = rb_vm_cref_replace_with_duplicated_cref();
1555 arg.refinement = refinement;
1556 for (i = 0; i < argc; i++) {
1557 arg.module = argv[i];
1558 struct rb_id_table *m_tbl = RCLASS_M_TBL(argv[i]);
1559 if (!m_tbl) continue;
1560 rb_id_table_foreach(m_tbl, refinement_import_methods_i, &arg);
1561 }
1562 return refinement;
1563}
1564
1565void
1566rb_obj_call_init(VALUE obj, int argc, const VALUE *argv)
1567{
1568 rb_obj_call_init_kw(obj, argc, argv, RB_NO_KEYWORDS);
1569}
1570
1571void
1572rb_obj_call_init_kw(VALUE obj, int argc, const VALUE *argv, int kw_splat)
1573{
1574 PASS_PASSED_BLOCK_HANDLER();
1575 rb_funcallv_kw(obj, idInitialize, argc, argv, kw_splat);
1576}
1577
1578void
1579rb_extend_object(VALUE obj, VALUE module)
1580{
1581 rb_include_module(rb_singleton_class(obj), module);
1582}
1583
1584/*
1585 * call-seq:
1586 * extend_object(obj) -> obj
1587 *
1588 * Extends the specified object by adding this module's constants and
1589 * methods (which are added as singleton methods). This is the callback
1590 * method used by Object#extend.
1591 *
1592 * module Picky
1593 * def Picky.extend_object(o)
1594 * if String === o
1595 * puts "Can't add Picky to a String"
1596 * else
1597 * puts "Picky added to #{o.class}"
1598 * super
1599 * end
1600 * end
1601 * end
1602 * (s = Array.new).extend Picky # Call Object.extend
1603 * (s = "quick brown fox").extend Picky
1604 *
1605 * <em>produces:</em>
1606 *
1607 * Picky added to Array
1608 * Can't add Picky to a String
1609 */
1610
1611static VALUE
1612rb_mod_extend_object(VALUE mod, VALUE obj)
1613{
1614 rb_extend_object(obj, mod);
1615 return obj;
1616}
1617
1618/*
1619 * call-seq:
1620 * obj.extend(module, ...) -> obj
1621 *
1622 * Adds to _obj_ the instance methods from each module given as a
1623 * parameter.
1624 *
1625 * module Mod
1626 * def hello
1627 * "Hello from Mod.\n"
1628 * end
1629 * end
1630 *
1631 * class Klass
1632 * def hello
1633 * "Hello from Klass.\n"
1634 * end
1635 * end
1636 *
1637 * k = Klass.new
1638 * k.hello #=> "Hello from Klass.\n"
1639 * k.extend(Mod) #=> #<Klass:0x401b3bc8>
1640 * k.hello #=> "Hello from Mod.\n"
1641 */
1642
1643static VALUE
1644rb_obj_extend(int argc, VALUE *argv, VALUE obj)
1645{
1646 int i;
1647 ID id_extend_object, id_extended;
1648
1649 CONST_ID(id_extend_object, "extend_object");
1650 CONST_ID(id_extended, "extended");
1651
1653 for (i = 0; i < argc; i++)
1654 Check_Type(argv[i], T_MODULE);
1655 while (argc--) {
1656 rb_funcall(argv[argc], id_extend_object, 1, obj);
1657 rb_funcall(argv[argc], id_extended, 1, obj);
1658 }
1659 return obj;
1660}
1661
1662/*
1663 * call-seq:
1664 * include(module, ...) -> self
1665 *
1666 * Invokes Module.append_features on each parameter in turn.
1667 * Effectively adds the methods and constants in each module to the
1668 * receiver.
1669 */
1670
1671static VALUE
1672top_include(int argc, VALUE *argv, VALUE self)
1673{
1674 rb_thread_t *th = GET_THREAD();
1675
1676 if (th->top_wrapper) {
1677 rb_warning("main.include in the wrapped load is effective only in wrapper module");
1678 return rb_mod_include(argc, argv, th->top_wrapper);
1679 }
1680 return rb_mod_include(argc, argv, rb_cObject);
1681}
1682
1683/*
1684 * call-seq:
1685 * using(module) -> self
1686 *
1687 * Import class refinements from <i>module</i> into the scope where
1688 * #using is called.
1689 */
1690
1691static VALUE
1692top_using(VALUE self, VALUE module)
1693{
1694 const rb_cref_t *cref = rb_vm_cref();
1695 rb_control_frame_t *prev_cfp = previous_frame(GET_EC());
1696
1697 if (CREF_NEXT(cref) || (prev_cfp && rb_vm_frame_method_entry(prev_cfp))) {
1698 rb_raise(rb_eRuntimeError, "main.using is permitted only at toplevel");
1699 }
1700 if (rb_block_given_p()) {
1701 ignored_block(module, "main.");
1702 }
1703 rb_using_module(rb_vm_cref_replace_with_duplicated_cref(), module);
1704 return self;
1705}
1706
1707static const VALUE *
1708errinfo_place(const rb_execution_context_t *ec)
1709{
1710 const rb_control_frame_t *cfp = ec->cfp;
1711 const rb_control_frame_t *end_cfp = RUBY_VM_END_CONTROL_FRAME(ec);
1712
1713 while (RUBY_VM_VALID_CONTROL_FRAME_P(cfp, end_cfp)) {
1714 if (VM_FRAME_RUBYFRAME_P(cfp)) {
1715 if (cfp->iseq->body->type == ISEQ_TYPE_RESCUE) {
1716 return &cfp->ep[VM_ENV_INDEX_LAST_LVAR];
1717 }
1718 else if (cfp->iseq->body->type == ISEQ_TYPE_ENSURE &&
1719 !THROW_DATA_P(cfp->ep[VM_ENV_INDEX_LAST_LVAR]) &&
1720 !FIXNUM_P(cfp->ep[VM_ENV_INDEX_LAST_LVAR])) {
1721 return &cfp->ep[VM_ENV_INDEX_LAST_LVAR];
1722 }
1723 }
1724 cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
1725 }
1726 return 0;
1727}
1728
1729VALUE
1730rb_ec_get_errinfo(const rb_execution_context_t *ec)
1731{
1732 const VALUE *ptr = errinfo_place(ec);
1733 if (ptr) {
1734 return *ptr;
1735 }
1736 else {
1737 return ec->errinfo;
1738 }
1739}
1740
1741static VALUE
1742get_errinfo(void)
1743{
1744 return get_ec_errinfo(GET_EC());
1745}
1746
1747static VALUE
1748errinfo_getter(ID id, VALUE *_)
1749{
1750 return get_errinfo();
1751}
1752
1753VALUE
1755{
1756 return GET_EC()->errinfo;
1757}
1758
1759void
1761{
1762 if (!NIL_P(err) && !rb_obj_is_kind_of(err, rb_eException)) {
1763 rb_raise(rb_eTypeError, "assigning non-exception to $!");
1764 }
1765 GET_EC()->errinfo = err;
1766}
1767
1768static VALUE
1769errat_getter(ID id, VALUE *_)
1770{
1771 VALUE err = get_errinfo();
1772 if (!NIL_P(err)) {
1773 return rb_get_backtrace(err);
1774 }
1775 else {
1776 return Qnil;
1777 }
1778}
1779
1780static void
1781errat_setter(VALUE val, ID id, VALUE *var)
1782{
1783 VALUE err = get_errinfo();
1784 if (NIL_P(err)) {
1785 rb_raise(rb_eArgError, "$! not set");
1786 }
1787 set_backtrace(err, val);
1788}
1789
1790/*
1791 * call-seq:
1792 * __method__ -> symbol
1793 *
1794 * Returns the name at the definition of the current method as a
1795 * Symbol.
1796 * If called outside of a method, it returns <code>nil</code>.
1797 *
1798 */
1799
1800static VALUE
1801rb_f_method_name(VALUE _)
1802{
1803 ID fname = prev_frame_func(); /* need *method* ID */
1804
1805 if (fname) {
1806 return ID2SYM(fname);
1807 }
1808 else {
1809 return Qnil;
1810 }
1811}
1812
1813/*
1814 * call-seq:
1815 * __callee__ -> symbol
1816 *
1817 * Returns the called name of the current method as a Symbol.
1818 * If called outside of a method, it returns <code>nil</code>.
1819 *
1820 */
1821
1822static VALUE
1823rb_f_callee_name(VALUE _)
1824{
1825 ID fname = prev_frame_callee(); /* need *callee* ID */
1826
1827 if (fname) {
1828 return ID2SYM(fname);
1829 }
1830 else {
1831 return Qnil;
1832 }
1833}
1834
1835/*
1836 * call-seq:
1837 * __dir__ -> string
1838 *
1839 * Returns the canonicalized absolute path of the directory of the file from
1840 * which this method is called. It means symlinks in the path is resolved.
1841 * If <code>__FILE__</code> is <code>nil</code>, it returns <code>nil</code>.
1842 * The return value equals to <code>File.dirname(File.realpath(__FILE__))</code>.
1843 *
1844 */
1845static VALUE
1846f_current_dirname(VALUE _)
1847{
1848 VALUE base = rb_current_realfilepath();
1849 if (NIL_P(base)) {
1850 return Qnil;
1851 }
1852 base = rb_file_dirname(base);
1853 return base;
1854}
1855
1856/*
1857 * call-seq:
1858 * global_variables -> array
1859 *
1860 * Returns an array of the names of global variables. This includes
1861 * special regexp global variables such as <tt>$~</tt> and <tt>$+</tt>,
1862 * but does not include the numbered regexp global variables (<tt>$1</tt>,
1863 * <tt>$2</tt>, etc.).
1864 *
1865 * global_variables.grep /std/ #=> [:$stdin, :$stdout, :$stderr]
1866 */
1867
1868static VALUE
1869f_global_variables(VALUE _)
1870{
1871 return rb_f_global_variables();
1872}
1873
1874/*
1875 * call-seq:
1876 * trace_var(symbol, cmd ) -> nil
1877 * trace_var(symbol) {|val| block } -> nil
1878 *
1879 * Controls tracing of assignments to global variables. The parameter
1880 * +symbol+ identifies the variable (as either a string name or a
1881 * symbol identifier). _cmd_ (which may be a string or a
1882 * +Proc+ object) or block is executed whenever the variable
1883 * is assigned. The block or +Proc+ object receives the
1884 * variable's new value as a parameter. Also see
1885 * Kernel::untrace_var.
1886 *
1887 * trace_var :$_, proc {|v| puts "$_ is now '#{v}'" }
1888 * $_ = "hello"
1889 * $_ = ' there'
1890 *
1891 * <em>produces:</em>
1892 *
1893 * $_ is now 'hello'
1894 * $_ is now ' there'
1895 */
1896
1897static VALUE
1898f_trace_var(int c, const VALUE *a, VALUE _)
1899{
1900 return rb_f_trace_var(c, a);
1901}
1902
1903/*
1904 * call-seq:
1905 * untrace_var(symbol [, cmd] ) -> array or nil
1906 *
1907 * Removes tracing for the specified command on the given global
1908 * variable and returns +nil+. If no command is specified,
1909 * removes all tracing for that variable and returns an array
1910 * containing the commands actually removed.
1911 */
1912
1913static VALUE
1914f_untrace_var(int c, const VALUE *a, VALUE _)
1915{
1916 return rb_f_untrace_var(c, a);
1917}
1918
1919void
1920Init_eval(void)
1921{
1922 rb_define_virtual_variable("$@", errat_getter, errat_setter);
1923 rb_define_virtual_variable("$!", errinfo_getter, 0);
1924
1925 rb_gvar_ractor_local("$@");
1926 rb_gvar_ractor_local("$!");
1927
1928 rb_define_global_function("raise", f_raise, -1);
1929 rb_define_global_function("fail", f_raise, -1);
1930
1931 rb_define_global_function("global_variables", f_global_variables, 0);
1932
1933 rb_define_global_function("__method__", rb_f_method_name, 0);
1934 rb_define_global_function("__callee__", rb_f_callee_name, 0);
1935 rb_define_global_function("__dir__", f_current_dirname, 0);
1936
1937 rb_define_method(rb_cModule, "include", rb_mod_include, -1);
1938 rb_define_method(rb_cModule, "prepend", rb_mod_prepend, -1);
1939
1940 rb_define_private_method(rb_cModule, "append_features", rb_mod_append_features, 1);
1941 rb_define_private_method(rb_cModule, "extend_object", rb_mod_extend_object, 1);
1942 rb_define_private_method(rb_cModule, "prepend_features", rb_mod_prepend_features, 1);
1943 rb_define_private_method(rb_cModule, "refine", rb_mod_refine, 1);
1944 rb_define_private_method(rb_cModule, "using", mod_using, 1);
1945 rb_define_singleton_method(rb_cModule, "used_modules",
1946 rb_mod_s_used_modules, 0);
1947 rb_undef_method(rb_cClass, "refine");
1948 rb_define_private_method(rb_cRefinement, "import_methods", refinement_import_methods, -1);
1949
1950 rb_undef_method(rb_cClass, "module_function");
1951
1952 Init_vm_eval();
1953 Init_eval_method();
1954
1955 rb_define_singleton_method(rb_cModule, "nesting", rb_mod_nesting, 0);
1956 rb_define_singleton_method(rb_cModule, "constants", rb_mod_s_constants, -1);
1957
1958 rb_define_private_method(rb_singleton_class(rb_vm_top_self()),
1959 "include", top_include, -1);
1960 rb_define_private_method(rb_singleton_class(rb_vm_top_self()),
1961 "using", top_using, 1);
1962
1963 rb_define_method(rb_mKernel, "extend", rb_obj_extend, -1);
1964
1965 rb_define_global_function("trace_var", f_trace_var, -1);
1966 rb_define_global_function("untrace_var", f_untrace_var, -1);
1967
1968 rb_vm_register_special_exception(ruby_error_reenter, rb_eFatal, "exception reentered");
1969 rb_vm_register_special_exception(ruby_error_stackfatal, rb_eFatal, "machine stack overflow in critical region");
1970
1971 id_signo = rb_intern_const("signo");
1972 id_status = rb_intern_const("status");
1973}
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
Definition: cxxanyargs.hpp:685
#define rb_define_private_method(klass, mid, func, arity)
Defines klass#mid and makes it private.
Definition: cxxanyargs.hpp:677
#define RUBY_EVENT_RAISE
Encountered a raise statement.
Definition: event.h:41
#define RUBY_EVENT_C_RETURN
Return from a method, written in C.
Definition: event.h:40
void rb_include_module(VALUE klass, VALUE module)
Includes a module to a class.
Definition: class.c:1043
void rb_extend_object(VALUE obj, VALUE module)
Extend the object with the module.
Definition: eval.c:1579
void rb_prepend_module(VALUE klass, VALUE module)
Identical to rb_include_module(), except it "prepends" the passed module to the klass,...
Definition: class.c:1289
void rb_class_modify_check(VALUE klass)
Asserts that klass is not a frozen class.
Definition: eval.c:422
void rb_need_block(void)
Declares that the current method needs a block.
Definition: eval.c:871
ID rb_frame_last_func(void)
Returns the ID of the last method in the call stack.
Definition: eval.c:1080
void rb_undef_method(VALUE klass, const char *name)
Defines an undef of a method.
Definition: class.c:1938
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a method.
Definition: class.c:1914
int rb_keyword_given_p(void)
Determines if the current method is given a keyword argument.
Definition: eval.c:863
int rb_block_given_p(void)
Determines if the current method is given a block.
Definition: eval.c:850
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
Keyword argument deconstructor.
Definition: class.c:2195
void rb_define_global_function(const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a global function.
Definition: class.c:2110
#define FL_SINGLETON
Old name of RUBY_FL_SINGLETON.
Definition: fl_type.h:58
#define Qundef
Old name of RUBY_Qundef.
#define INT2FIX
Old name of RB_INT2FIX.
Definition: long.h:48
#define OBJ_FROZEN
Old name of RB_OBJ_FROZEN.
Definition: fl_type.h:145
#define UNREACHABLE
Old name of RBIMPL_UNREACHABLE.
Definition: assume.h:30
#define ID2SYM
Old name of RB_ID2SYM.
Definition: symbol.h:44
#define SPECIAL_CONST_P
Old name of RB_SPECIAL_CONST_P.
#define OBJ_FREEZE
Old name of RB_OBJ_FREEZE.
Definition: fl_type.h:143
#define UNREACHABLE_RETURN
Old name of RBIMPL_UNREACHABLE_RETURN.
Definition: assume.h:31
#define FIX2INT
Old name of RB_FIX2INT.
Definition: int.h:41
#define T_MODULE
Old name of RUBY_T_MODULE.
Definition: value_type.h:70
#define T_ICLASS
Old name of RUBY_T_ICLASS.
Definition: value_type.h:66
#define T_HASH
Old name of RUBY_T_HASH.
Definition: value_type.h:65
#define FL_SET
Old name of RB_FL_SET.
Definition: fl_type.h:137
#define rb_exc_new3
Old name of rb_exc_new_str.
Definition: error.h:38
#define Qtrue
Old name of RUBY_Qtrue.
#define NUM2INT
Old name of RB_NUM2INT.
Definition: int.h:44
#define Qnil
Old name of RUBY_Qnil.
#define Qfalse
Old name of RUBY_Qfalse.
#define T_OBJECT
Old name of RUBY_T_OBJECT.
Definition: value_type.h:75
#define NIL_P
Old name of RB_NIL_P.
#define T_CLASS
Old name of RUBY_T_CLASS.
Definition: value_type.h:58
#define BUILTIN_TYPE
Old name of RB_BUILTIN_TYPE.
Definition: value_type.h:85
#define FL_TEST
Old name of RB_FL_TEST.
Definition: fl_type.h:139
#define FIXNUM_P
Old name of RB_FIXNUM_P.
#define CONST_ID
Old name of RUBY_CONST_ID.
Definition: symbol.h:47
void ruby_stop(int ex)
Calls ruby_cleanup() and exits the process.
Definition: eval.c:289
int ruby_exec_node(void *n)
Identical to ruby_run_node(), except it returns an opaque execution status.
Definition: eval.c:325
int ruby_setup(void)
Initializes the VM and builtin libraries.
Definition: eval.c:65
void ruby_finalize(void)
Runs the VM finalization processes.
Definition: eval.c:168
void ruby_init_stack(volatile VALUE *addr)
Set stack bottom of Ruby implementation.
int ruby_cleanup(int ex)
Destructs the VM.
Definition: eval.c:176
void * ruby_process_options(int argc, char **argv)
Identical to ruby_options(), except it raises ruby-level exceptions on failure.
Definition: ruby.c:2730
void ruby_prog_init(void)
Defines built-in variables.
Definition: ruby.c:2683
void ruby_sig_finalize(void)
Clear signal handlers.
Definition: signal.c:1497
#define ruby_debug
This variable controls whether the interpreter is in debug mode.
Definition: error.h:470
VALUE rb_eLocalJumpError
LocalJumpError exception.
Definition: eval.c:48
void rb_raise(VALUE exc, const char *fmt,...)
Exception entry point.
Definition: error.c:3021
VALUE rb_rescue2(VALUE(*b_proc)(VALUE), VALUE data1, VALUE(*r_proc)(VALUE, VALUE), VALUE data2,...)
An equivalent of rescue clause.
Definition: eval.c:879
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
Definition: eval.c:671
void rb_set_errinfo(VALUE err)
Sets the current exception ($!) to the given value.
Definition: eval.c:1760
VALUE rb_vrescue2(VALUE(*b_proc)(VALUE), VALUE data1, VALUE(*r_proc)(VALUE, VALUE), VALUE data2, va_list args)
Identical to rb_rescue2(), except it takes va_list instead of variadic number of arguments.
Definition: eval.c:890
void rb_exc_fatal(VALUE mesg)
Raises a fatal error in the current thread.
Definition: eval.c:684
void rb_warn(const char *fmt,...)
Identical to rb_warning(), except it reports always regardless of runtime -W flag.
Definition: error.c:418
VALUE rb_rescue(VALUE(*b_proc)(VALUE), VALUE data1, VALUE(*r_proc)(VALUE, VALUE), VALUE data2)
Identical to rb_rescue2(), except it does not take a list of exception classes.
Definition: eval.c:950
VALUE rb_ensure(VALUE(*b_proc)(VALUE), VALUE data1, VALUE(*e_proc)(VALUE), VALUE data2)
An equivalent to ensure clause.
Definition: eval.c:979
VALUE rb_errinfo(void)
This is the same as $! in Ruby.
Definition: eval.c:1754
VALUE rb_eSysStackError
SystemStackError exception.
Definition: eval.c:49
VALUE rb_eThreadError
ThreadError exception.
Definition: eval.c:868
void rb_warning(const char *fmt,...)
Issues a warning.
Definition: error.c:449
static VALUE rb_class_of(VALUE obj)
Object to class mapping function.
Definition: globals.h:172
#define RB_OBJ_WRITE(old, slot, young)
Declaration of a "back" pointer.
Definition: rgengc.h:220
int ruby_run_node(void *n)
Runs the given compiled source and exits this process.
Definition: eval.c:312
void ruby_init(void)
Calls ruby_setup() and check error.
Definition: eval.c:98
void * ruby_options(int argc, char **argv)
Processes command line arguments and compiles the Ruby source to execute.
Definition: eval.c:109
int ruby_executable_node(void *n, int *status)
Checks the return value of ruby_options().
Definition: eval.c:295
VALUE rb_funcall(VALUE recv, ID mid, int n,...)
Calls a method.
Definition: vm_eval.c:1102
VALUE rb_funcallv_kw(VALUE recv, ID mid, int argc, const VALUE *argv, int kw_splat)
Identical to rb_funcallv(), except you can specify how to handle the last element of the given array.
Definition: vm_eval.c:1069
VALUE rb_ary_new(void)
Allocates a new, empty array.
Definition: array.c:750
VALUE rb_ary_push(VALUE ary, VALUE elem)
Special case of rb_ary_cat() that it adds only one element.
Definition: array.c:1308
#define UNLIMITED_ARGUMENTS
This macro is used in conjunction with rb_check_arity().
Definition: error.h:35
static int rb_check_arity(int argc, int min, int max)
Ensures that the passed integer is in the passed range.
Definition: error.h:294
ID rb_frame_callee(void)
Identical to rb_frame_this_func(), except it returns the named used to call the method.
Definition: eval.c:1041
ID rb_frame_this_func(void)
Queries the name of the Ruby level method that is calling this function.
Definition: eval.c:1035
void rb_obj_call_init(VALUE obj, int argc, const VALUE *argv)
Calls initialize method of the passed object with the passed arguments.
Definition: eval.c:1566
void rb_interrupt(void)
Raises an instance of rb_eInterrupt.
Definition: eval.c:690
VALUE rb_make_exception(int argc, const VALUE *argv)
Constructs an exception object from the list of arguments, in a manner similar to Ruby's raise.
Definition: eval.c:817
void rb_jump_tag(int state)
This function is to re-throw global escapes.
Definition: eval.c:841
void rb_obj_call_init_kw(VALUE, int, const VALUE *, int)
Identical to rb_obj_call_init(), except you can specify how to handle the last element of the given a...
Definition: eval.c:1572
VALUE rb_file_dirname(VALUE fname)
Strips a file path's last component (and trailing separators if any).
Definition: file.c:4785
void rb_hash_foreach(VALUE hash, int(*func)(VALUE key, VALUE val, VALUE arg), VALUE arg)
Iterates over a hash.
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
Inserts or replaces ("upsert"s) the objects into the given hash table.
Definition: hash.c:2903
VALUE rb_hash_lookup(VALUE hash, VALUE key)
Identical to rb_hash_aref(), except it always returns RUBY_Qnil for misshits.
Definition: hash.c:2108
VALUE rb_hash_dup(VALUE hash)
Duplicates a hash.
Definition: hash.c:1585
VALUE rb_protect(VALUE(*func)(VALUE args), VALUE args, int *state)
Protects a function call from potential global escapes from the function.
void ruby_default_signal(int sig)
Pretends as if there was no custom signal handler.
Definition: signal.c:407
#define rb_exc_new_cstr(exc, str)
Identical to rb_exc_new(), except it assumes the passed pointer is a pointer to a C string.
Definition: string.h:1733
VALUE rb_check_string_type(VALUE obj)
Try converting an object to its stringised representation using its to_str method,...
Definition: string.c:2659
VALUE rb_obj_as_string(VALUE obj)
Try converting an object to its stringised representation using its to_s method, if any.
Definition: string.c:1657
VALUE rb_f_untrace_var(int argc, const VALUE *argv)
Deletes the passed tracer from the passed global variable, or if omitted, deletes everything.
Definition: variable.c:657
VALUE rb_const_list(void *)
This is another mysterious API that comes with no documents at all.
Definition: variable.c:2949
VALUE rb_attr_get(VALUE obj, ID name)
Identical to rb_ivar_get()
Definition: variable.c:1293
VALUE rb_ivar_set(VALUE obj, ID name, VALUE val)
Identical to rb_iv_set(), except it accepts the name as an ID instead of a C string.
Definition: variable.c:1575
VALUE rb_f_trace_var(int argc, const VALUE *argv)
Traces a global variable.
Definition: variable.c:611
VALUE rb_mod_constants(int argc, const VALUE *argv, VALUE recv)
Resembles Module#constants.
Definition: variable.c:2981
VALUE rb_ivar_get(VALUE obj, ID name)
Identical to rb_iv_get(), except it accepts the name as an ID instead of a C string.
Definition: variable.c:1285
void * rb_mod_const_of(VALUE, void *)
This is a variant of rb_mod_const_at().
Definition: variable.c:2927
void * rb_mod_const_at(VALUE, void *)
This API is mysterious.
Definition: variable.c:2910
VALUE rb_ivar_defined(VALUE obj, ID name)
Queries if the instance variable is defined at the object.
Definition: variable.c:1592
VALUE rb_f_global_variables(void)
Queries the list of global variables.
Definition: variable.c:811
VALUE rb_class_path(VALUE mod)
Identical to rb_mod_name(), except it returns #<Class: ...> style inspection for anonymous modules.
Definition: variable.c:172
VALUE rb_check_funcall(VALUE recv, ID mid, int argc, const VALUE *argv)
Identical to rb_funcallv(), except it returns RUBY_Qundef instead of raising rb_eNoMethodError.
Definition: vm_eval.c:664
static ID rb_intern_const(const char *str)
This is a "tiny optimisation" over rb_intern().
Definition: symbol.h:276
ID rb_intern(const char *name)
Finds or creates a symbol of the given name.
Definition: symbol.c:782
VALUE rb_id2str(ID id)
Identical to rb_id2name(), except it returns a Ruby's String instead of C's.
Definition: symbol.c:935
void rb_define_virtual_variable(const char *name, rb_gvar_getter_t *getter, rb_gvar_setter_t *setter)
Defines a global variable that is purely function-backended.
Definition: variable.c:594
int ruby_vm_destruct(ruby_vm_t *vm)
Destructs the passed VM.
Definition: vm.c:2696
VALUE rb_sprintf(const char *fmt,...)
Ruby's extended sprintf(3).
Definition: sprintf.c:1201
#define RBASIC(obj)
Convenient casting macro.
Definition: rbasic.h:40
#define RCLASS_SUPER
Just another name of rb_class_get_superclass.
Definition: rclass.h:46
#define RHASH_EMPTY_P(h)
Checks if the hash is empty.
Definition: rhash.h:92
const char * rb_obj_classname(VALUE obj)
Queries the name of the class of the passed object.
Definition: variable.c:309
#define RB_NO_KEYWORDS
Do not pass keywords.
Definition: scan_args.h:69
Scheduler APIs.
VALUE rb_fiber_scheduler_set(VALUE scheduler)
Destructively assigns the passed scheduler to that of the current thread that is calling this functio...
Definition: scheduler.c:91
#define RTEST
This is an old name of RB_TEST.
#define _(args)
This was a transition path from K&R to ANSI.
Definition: stdarg.h:35
CREF (Class REFerence)
const rb_iseq_t * iseqptr
iseq pointer, should be separated from iseqval
rb_cref_t * cref
class reference, should be marked
uintptr_t VALUE
Type that represents a Ruby object.
Definition: value.h:40
static void Check_Type(VALUE v, enum ruby_value_type t)
Identical to RB_TYPE_P(), except it raises exceptions on predication failure.
Definition: value_type.h:432
static bool RB_TYPE_P(VALUE obj, enum ruby_value_type t)
Queries if the given object is of given type.
Definition: value_type.h:375