Ruby 3.5.0dev (2025-10-10 revision b999ca0fce8116e9a218731bbbc171a849e53a86)
eval.c (b999ca0fce8116e9a218731bbbc171a849e53a86)
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 "internal.h"
22#include "internal/class.h"
23#include "internal/cont.h"
24#include "internal/error.h"
25#include "internal/eval.h"
26#include "internal/gc.h"
27#include "internal/hash.h"
28#include "internal/inits.h"
29#include "internal/io.h"
30#include "internal/object.h"
31#include "internal/thread.h"
32#include "internal/variable.h"
34#include "iseq.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, enum ruby_tag_type 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 /*
73 * Disable THP early before mallocs happen because we want this to
74 * affect as many future pages as possible for CoW-friendliness
75 */
76#if defined(__linux__) && defined(PR_SET_THP_DISABLE)
77 prctl(PR_SET_THP_DISABLE, 1, 0, 0, 0);
78#endif
79 Init_BareVM();
80 rb_vm_encoded_insn_data_table_init();
81 Init_enable_namespace();
82 Init_vm_objects();
83 Init_root_namespace();
84 Init_fstring_table();
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 rb_execution_context_t *ec = GET_EC();
104 rb_ec_error_print(ec, ec->errinfo);
105 }
106 exit(EXIT_FAILURE);
107 }
108}
109
110void *
111ruby_options(int argc, char **argv)
112{
113 rb_execution_context_t *ec = GET_EC();
114 enum ruby_tag_type state;
115 void *volatile iseq = 0;
116
117 EC_PUSH_TAG(ec);
118 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
119 iseq = ruby_process_options(argc, argv);
120 }
121 else {
122 rb_ec_clear_current_thread_trace_func(ec);
123 int exitcode = error_handle(ec, ec->errinfo, state);
124 ec->errinfo = Qnil; /* just been handled */
125 iseq = (void *)INT2FIX(exitcode);
126 }
127 EC_POP_TAG();
128 return iseq;
129}
130
131static void
132rb_ec_fiber_scheduler_finalize(rb_execution_context_t *ec)
133{
134 enum ruby_tag_type state;
135
136 EC_PUSH_TAG(ec);
137 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
139 }
140 else {
141 state = error_handle(ec, ec->errinfo, state);
142 }
143 EC_POP_TAG();
144}
145
146static void
147rb_ec_teardown(rb_execution_context_t *ec)
148{
149 // If the user code defined a scheduler for the top level thread, run it:
150 rb_ec_fiber_scheduler_finalize(ec);
151
152 EC_PUSH_TAG(ec);
153 if (EC_EXEC_TAG() == TAG_NONE) {
154 rb_vm_trap_exit(rb_ec_vm_ptr(ec));
155 }
156 EC_POP_TAG();
157 rb_ec_exec_end_proc(ec);
158 rb_ec_clear_all_trace_func(ec);
159}
160
161static void
162rb_ec_finalize(rb_execution_context_t *ec)
163{
165 ec->errinfo = Qnil;
166 rb_objspace_call_finalizer();
167}
168
169void
171{
172 rb_execution_context_t *ec = GET_EC();
173 rb_ec_teardown(ec);
174 rb_ec_finalize(ec);
175}
176
177int
179{
180 return rb_ec_cleanup(GET_EC(), (enum ruby_tag_type)ex);
181}
182
183static int
184rb_ec_cleanup(rb_execution_context_t *ec, enum ruby_tag_type ex)
185{
186 int state;
187 volatile VALUE save_error = Qundef;
188 volatile int sysex = EXIT_SUCCESS;
189 volatile int signaled = 0;
190 rb_thread_t *th = rb_ec_thread_ptr(ec);
191 rb_thread_t *const volatile th0 = th;
192 volatile int step = 0;
193 volatile VALUE message = Qnil;
194 VALUE buf;
195
196 rb_threadptr_interrupt(th);
197 rb_threadptr_check_signal(th);
198
199 EC_PUSH_TAG(ec);
200 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
201 RUBY_VM_CHECK_INTS(ec);
202
203 step_0: step++;
204 save_error = ec->errinfo;
205 if (THROW_DATA_P(ec->errinfo)) ec->errinfo = Qnil;
206
207 /* exits with failure but silently when an exception raised
208 * here */
209 rb_ec_teardown(ec);
210
211 step_1: step++;
212 VALUE err = ec->errinfo;
213 volatile int mode0 = 0, mode1 = 0;
214 if (err != save_error && !NIL_P(err)) {
215 mode0 = exiting_split(err, &sysex, &signaled);
216 }
217
218 /* exceptions after here will be ignored */
219
220 /* build error message including causes */
221 err = ATOMIC_VALUE_EXCHANGE(save_error, Qnil);
222
223 if (!NIL_P(err) && !THROW_DATA_P(err)) {
224 mode1 = exiting_split(err, (mode0 & EXITING_WITH_STATUS) ? NULL : &sysex, &signaled);
225 if (mode1 & EXITING_WITH_MESSAGE) {
226 buf = rb_str_new(NULL, 0);
227 rb_ec_error_print_detailed(ec, err, buf, Qundef);
228 message = buf;
229 }
230 }
231
232 step_2: step++;
233 /* protect from Thread#raise */
234 th->status = THREAD_KILLED;
235
236 rb_ractor_terminate_all();
237
238 step_3: step++;
239 if (!NIL_P(buf = message)) {
240 warn_print_str(buf);
241 }
242 else if (!NIL_OR_UNDEF_P(err = save_error) ||
243 (ex != TAG_NONE && !((mode0|mode1) & EXITING_WITH_STATUS))) {
244 sysex = error_handle(ec, err, ex);
245 }
246 }
247 else {
248 th = th0;
249 switch (step) {
250 case 0: goto step_0;
251 case 1: goto step_1;
252 case 2: goto step_2;
253 case 3: goto step_3;
254 }
255 }
256
257 rb_ec_finalize(ec);
258
259 /* unlock again if finalizer took mutexes. */
260 rb_threadptr_unlock_all_locking_mutexes(th);
261 th = th0;
262 EC_POP_TAG();
263 th = th0;
264 rb_thread_stop_timer_thread();
265 ruby_vm_destruct(th->vm);
266 // For YJIT, call this after ruby_vm_destruct() frees jit_cont for the root fiber.
267 rb_jit_cont_finish();
268
269 if (signaled) ruby_default_signal(signaled);
270
271 return sysex;
272}
273
274static int
275rb_ec_exec_node(rb_execution_context_t *ec, void *n)
276{
277 volatile int state;
278 rb_iseq_t *iseq = (rb_iseq_t *)n;
279 if (!n) return 0;
280
281 EC_PUSH_TAG(ec);
282 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
283 rb_iseq_eval_main(iseq);
284 }
285 EC_POP_TAG();
286 return state;
287}
288
289void
291{
292 exit(ruby_cleanup(ex));
293}
294
295int
296ruby_executable_node(void *n, int *status)
297{
298 VALUE v = (VALUE)n;
299 int s;
300
301 switch (v) {
302 case Qtrue: s = EXIT_SUCCESS; break;
303 case Qfalse: s = EXIT_FAILURE; break;
304 default:
305 if (!FIXNUM_P(v)) return TRUE;
306 s = FIX2INT(v);
307 }
308 if (status) *status = s;
309 return FALSE;
310}
311
312int
313ruby_run_node(void *n)
314{
315 rb_execution_context_t *ec = GET_EC();
316 int status;
317 if (!ruby_executable_node(n, &status)) {
318 rb_ec_cleanup(ec, (NIL_P(ec->errinfo) ? TAG_NONE : TAG_RAISE));
319 return status;
320 }
321 return rb_ec_cleanup(ec, rb_ec_exec_node(ec, n));
322}
323
324int
326{
327 return rb_ec_exec_node(GET_EC(), n);
328}
329
330/*
331 * call-seq:
332 * Module.nesting -> array
333 *
334 * Returns the list of +Modules+ nested at the point of call.
335 *
336 * module M1
337 * module M2
338 * $a = Module.nesting
339 * end
340 * end
341 * $a #=> [M1::M2, M1]
342 * $a[0].name #=> "M1::M2"
343 */
344
345static VALUE
346rb_mod_nesting(VALUE _)
347{
348 VALUE ary = rb_ary_new();
349 const rb_cref_t *cref = rb_vm_cref();
350
351 while (cref && CREF_NEXT(cref)) {
352 VALUE klass = CREF_CLASS(cref);
353 if (!CREF_PUSHED_BY_EVAL(cref) &&
354 !NIL_P(klass)) {
355 rb_ary_push(ary, klass);
356 }
357 cref = CREF_NEXT(cref);
358 }
359 return ary;
360}
361
362/*
363 * call-seq:
364 * Module.constants -> array
365 * Module.constants(inherited) -> array
366 *
367 * In the first form, returns an array of the names of all
368 * constants accessible from the point of call.
369 * This list includes the names of all modules and classes
370 * defined in the global scope.
371 *
372 * Module.constants.first(4)
373 * # => [:ARGF, :ARGV, :ArgumentError, :Array]
374 *
375 * Module.constants.include?(:SEEK_SET) # => false
376 *
377 * class IO
378 * Module.constants.include?(:SEEK_SET) # => true
379 * end
380 *
381 * The second form calls the instance method +constants+.
382 */
383
384static VALUE
385rb_mod_s_constants(int argc, VALUE *argv, VALUE mod)
386{
387 const rb_cref_t *cref = rb_vm_cref();
388 VALUE klass;
389 VALUE cbase = 0;
390 void *data = 0;
391
392 if (argc > 0 || mod != rb_cModule) {
393 return rb_mod_constants(argc, argv, mod);
394 }
395
396 while (cref) {
397 klass = CREF_CLASS(cref);
398 if (!CREF_PUSHED_BY_EVAL(cref) &&
399 !NIL_P(klass)) {
400 data = rb_mod_const_at(CREF_CLASS(cref), data);
401 if (!cbase) {
402 cbase = klass;
403 }
404 }
405 cref = CREF_NEXT(cref);
406 }
407
408 if (cbase) {
409 data = rb_mod_const_of(cbase, data);
410 }
411 return rb_const_list(data);
412}
413
420void
422{
423 if (SPECIAL_CONST_P(klass)) {
424 Check_Type(klass, T_CLASS);
425 }
426 if (RB_TYPE_P(klass, T_MODULE)) {
427 // TODO: shouldn't this only happen in a few places?
428 rb_class_set_initialized(klass);
429 }
430 if (OBJ_FROZEN(klass)) {
431 const char *desc;
432
433 if (RCLASS_SINGLETON_P(klass)) {
434 desc = "object";
435 klass = RCLASS_ATTACHED_OBJECT(klass);
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 *, enum ruby_tag_type, 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 (UNDEF_P(*cause)) {
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) && !UNDEF_P(*cause) && *cause != mesg) {
531#if 0 /* maybe critical for some cases */
532 rb_exc_check_circular_cause(*cause);
533#else
534 VALUE c = *cause;
535 while (!NIL_P(c)) {
536 if (c == mesg) {
537 rb_raise(rb_eArgError, "circular causes");
538 }
539 if (THROW_DATA_P(c)) {
540 break;
541 }
542 c = rb_attr_get(c, id_cause);
543 }
544#endif
545 }
546 return mesg;
547}
548
549static void
550setup_exception(rb_execution_context_t *ec, enum ruby_tag_type tag, volatile VALUE mesg, VALUE cause)
551{
552 VALUE e;
553 int line;
554 const char *file = rb_source_location_cstr(&line);
555 const char *const volatile file0 = file;
556
557 if ((file && !NIL_P(mesg)) || !UNDEF_P(cause)) {
558 volatile int state = 0;
559
560 EC_PUSH_TAG(ec);
561 if (EC_EXEC_TAG() == TAG_NONE && !(state = rb_ec_set_raised(ec))) {
562 VALUE bt = rb_get_backtrace(mesg);
563 if (!NIL_P(bt) || UNDEF_P(cause)) {
564 if (OBJ_FROZEN(mesg)) {
565 mesg = rb_obj_dup(mesg);
566 }
567 }
568 if (!UNDEF_P(cause) && !THROW_DATA_P(cause)) {
569 exc_setup_cause(mesg, cause);
570 }
571 if (NIL_P(bt)) {
572 VALUE at = rb_ec_backtrace_object(ec);
573 rb_ivar_set(mesg, idBt_locations, at);
574 set_backtrace(mesg, at);
575 }
576 rb_ec_reset_raised(ec);
577 }
578 EC_POP_TAG();
579 file = file0;
580 if (state) goto fatal;
581 }
582
583 if (!NIL_P(mesg)) {
584 ec->errinfo = mesg;
585 }
586
587 if (RTEST(ruby_debug) && !NIL_P(e = ec->errinfo) &&
589 enum ruby_tag_type state;
590
591 mesg = e;
592 EC_PUSH_TAG(ec);
593 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
594 ec->errinfo = Qnil;
595 e = rb_obj_as_string(mesg);
596 ec->errinfo = mesg;
597 if (file && line) {
598 e = rb_sprintf("Exception '%"PRIsVALUE"' at %s:%d - %"PRIsVALUE"\n",
599 rb_obj_class(mesg), file, line, e);
600 }
601 else if (file) {
602 e = rb_sprintf("Exception '%"PRIsVALUE"' at %s - %"PRIsVALUE"\n",
603 rb_obj_class(mesg), file, e);
604 }
605 else {
606 e = rb_sprintf("Exception '%"PRIsVALUE"' - %"PRIsVALUE"\n",
607 rb_obj_class(mesg), e);
608 }
609 warn_print_str(e);
610 }
611 EC_POP_TAG();
612 if (state == TAG_FATAL && ec->errinfo == exception_error) {
613 ec->errinfo = mesg;
614 }
615 else if (state) {
616 rb_ec_reset_raised(ec);
617 EC_JUMP_TAG(ec, state);
618 }
619 }
620
621 if (rb_ec_set_raised(ec)) {
622 goto fatal;
623 }
624
625 if (tag != TAG_FATAL) {
626 RUBY_DTRACE_HOOK(RAISE, rb_obj_classname(ec->errinfo));
627 EXEC_EVENT_HOOK(ec, RUBY_EVENT_RAISE, ec->cfp->self, 0, 0, 0, mesg);
628 }
629 return;
630
631 fatal:
632 ec->errinfo = exception_error;
633 rb_ec_reset_raised(ec);
634 EC_JUMP_TAG(ec, TAG_FATAL);
635}
636
638void
639rb_ec_setup_exception(const rb_execution_context_t *ec, VALUE mesg, VALUE cause)
640{
641 if (UNDEF_P(cause)) {
642 cause = get_ec_errinfo(ec);
643 }
644 if (cause != mesg) {
645 if (THROW_DATA_P(cause)) {
646 cause = Qnil;
647 }
648
649 rb_ivar_set(mesg, id_cause, cause);
650 }
651}
652
653static void
654rb_longjmp(rb_execution_context_t *ec, enum ruby_tag_type tag, volatile VALUE mesg, VALUE cause)
655{
656 mesg = exc_setup_message(ec, mesg, &cause);
657 setup_exception(ec, tag, mesg, cause);
658 rb_ec_raised_clear(ec);
659 EC_JUMP_TAG(ec, tag);
660}
661
662static VALUE make_exception(int argc, const VALUE *argv, int isstr);
663
664NORETURN(static void rb_exc_exception(VALUE mesg, enum ruby_tag_type tag, VALUE cause));
665
666static void
667rb_exc_exception(VALUE mesg, enum ruby_tag_type tag, VALUE cause)
668{
669 if (!NIL_P(mesg)) {
670 mesg = make_exception(1, &mesg, FALSE);
671 }
672 rb_longjmp(GET_EC(), tag, mesg, cause);
673}
674
682void
684{
685 rb_exc_exception(mesg, TAG_RAISE, Qundef);
686}
687
695void
697{
698 rb_exc_exception(mesg, TAG_FATAL, Qnil);
699}
700
701void
702rb_interrupt(void)
703{
705}
706
707static int
708extract_raise_options(int argc, VALUE *argv, VALUE *cause)
709{
710 // Keyword arguments:
711 static ID keywords[1] = {0};
712 if (!keywords[0]) {
713 CONST_ID(keywords[0], "cause");
714 }
715
716 if (argc > 0) {
717 VALUE options;
718 argc = rb_scan_args(argc, argv, "*:", NULL, &options);
719
720 if (!NIL_P(options)) {
721 if (!RHASH_EMPTY_P(options)) {
722 // Extract optional cause keyword argument, leaving any other options alone:
723 rb_get_kwargs(options, keywords, 0, -2, cause);
724
725 // If there were any other options, add them back to the arguments:
726 if (!RHASH_EMPTY_P(options)) argv[argc++] = options;
727 }
728 }
729 }
730
731 return argc;
732}
733
742VALUE
743rb_exception_setup(int argc, VALUE *argv)
744{
745 rb_execution_context_t *ec = GET_EC();
746
747 // Extract cause keyword argument:
748 VALUE cause = Qundef;
749 argc = extract_raise_options(argc, argv, &cause);
750
751 // Validate cause-only case:
752 if (argc == 0 && !UNDEF_P(cause)) {
753 rb_raise(rb_eArgError, "only cause is given with no arguments");
754 }
755
756 // Create exception:
757 VALUE exception;
758 if (argc == 0) {
759 exception = rb_exc_new(rb_eRuntimeError, 0, 0);
760 }
761 else {
762 exception = rb_make_exception(argc, argv);
763 }
764
765 VALUE resolved_cause = Qnil;
766
767 // Resolve cause with validation:
768 if (UNDEF_P(cause)) {
769 // No explicit cause - use automatic cause chaining from calling context:
770 resolved_cause = rb_ec_get_errinfo(ec);
771
772 // Prevent self-referential cause (e.g. `raise $!`):
773 if (resolved_cause == exception) {
774 resolved_cause = Qnil;
775 }
776 }
777 else if (NIL_P(cause)) {
778 // Explicit nil cause - prevent chaining:
779 resolved_cause = Qnil;
780 }
781 else {
782 // Explicit cause - validate and assign:
783 if (!rb_obj_is_kind_of(cause, rb_eException)) {
784 rb_raise(rb_eTypeError, "exception object expected");
785 }
786
787 if (cause == exception) {
788 // Prevent self-referential cause (e.g. `raise error, cause: error`) - although I'm not sure this is good behaviour, it's inherited from `Kernel#raise`.
789 resolved_cause = Qnil;
790 }
791 else {
792 // Check for circular causes:
793 VALUE current_cause = cause;
794 while (!NIL_P(current_cause)) {
795 // We guarantee that the cause chain is always terminated. Then, creating an exception with an existing cause is not circular as long as exception is not an existing cause of any other exception.
796 if (current_cause == exception) {
797 rb_raise(rb_eArgError, "circular causes");
798 }
799 if (THROW_DATA_P(current_cause)) {
800 break;
801 }
802 current_cause = rb_attr_get(current_cause, id_cause);
803 }
804 resolved_cause = cause;
805 }
806 }
807
808 // Apply cause to exception object (duplicate if frozen):
809 if (!UNDEF_P(resolved_cause)) {
810 if (OBJ_FROZEN(exception)) {
811 exception = rb_obj_dup(exception);
812 }
813 rb_ivar_set(exception, id_cause, resolved_cause);
814 }
815
816 return exception;
817}
818
819VALUE
820rb_f_raise(int argc, VALUE *argv)
821{
822 VALUE cause = Qundef;
823 argc = extract_raise_options(argc, argv, &cause);
824
825 VALUE exception;
826
827 // Bare re-raise case:
828 if (argc == 0) {
829 // Cause was extracted, but no arguments were provided:
830 if (!UNDEF_P(cause)) {
831 rb_raise(rb_eArgError, "only cause is given with no arguments");
832 }
833
834 // Otherwise, re-raise the current exception:
835 exception = get_errinfo();
836 if (!NIL_P(exception)) {
837 argc = 1;
838 argv = &exception;
839 }
840 }
841
842 rb_raise_jump(rb_make_exception(argc, argv), cause);
843
845}
846
847/*
848 * call-seq:
849 * raise(exception, message = exception.to_s, backtrace = nil, cause: $!)
850 * raise(message = nil, cause: $!)
851 *
852 * Raises an exception;
853 * see {Exceptions}[rdoc-ref:exceptions.md].
854 *
855 * Argument +exception+ sets the class of the new exception;
856 * it should be class Exception or one of its subclasses
857 * (most commonly, RuntimeError or StandardError),
858 * or an instance of one of those classes:
859 *
860 * begin
861 * raise(StandardError)
862 * rescue => x
863 * p x.class
864 * end
865 * # => StandardError
866 *
867 * Argument +message+ sets the stored message in the new exception,
868 * which may be retrieved by method Exception#message;
869 * the message must be
870 * a {string-convertible object}[rdoc-ref:implicit_conversion.rdoc@String-Convertible+Objects]
871 * or +nil+:
872 *
873 * begin
874 * raise(StandardError, 'Boom')
875 * rescue => x
876 * p x.message
877 * end
878 * # => "Boom"
879 *
880 * If argument +message+ is not given,
881 * the message is the exception class name.
882 *
883 * See {Messages}[rdoc-ref:exceptions.md@Messages].
884 *
885 * Argument +backtrace+ might be used to modify the backtrace of the new exception,
886 * as reported by Exception#backtrace and Exception#backtrace_locations;
887 * the backtrace must be an array of Thread::Backtrace::Location, an array of
888 * strings, a single string, or +nil+.
889 *
890 * Using the array of Thread::Backtrace::Location instances is the most consistent option
891 * and should be preferred when possible. The necessary value might be obtained
892 * from #caller_locations, or copied from Exception#backtrace_locations of another
893 * error:
894 *
895 * begin
896 * do_some_work()
897 * rescue ZeroDivisionError => ex
898 * raise(LogicalError, "You have an error in your math", ex.backtrace_locations)
899 * end
900 *
901 * The ways, both Exception#backtrace and Exception#backtrace_locations of the
902 * raised error are set to the same backtrace.
903 *
904 * When the desired stack of locations is not available and should
905 * be constructed from scratch, an array of strings or a singular
906 * string can be used. In this case, only Exception#backtrace is set:
907 *
908 * begin
909 * raise(StandardError, 'Boom', %w[dsl.rb:3 framework.rb:1])
910 * rescue => ex
911 * p ex.backtrace
912 * # => ["dsl.rb:3", "framework.rb:1"]
913 * p ex.backtrace_locations
914 * # => nil
915 * end
916 *
917 * If argument +backtrace+ is not given,
918 * the backtrace is set according to an array of Thread::Backtrace::Location objects,
919 * as derived from the call stack.
920 *
921 * See {Backtraces}[rdoc-ref:exceptions.md@Backtraces].
922 *
923 * Keyword argument +cause+ sets the stored cause in the new exception,
924 * which may be retrieved by method Exception#cause;
925 * the cause must be an exception object (Exception or one of its subclasses),
926 * or +nil+:
927 *
928 * begin
929 * raise(StandardError, cause: RuntimeError.new)
930 * rescue => x
931 * p x.cause
932 * end
933 * # => #<RuntimeError: RuntimeError>
934 *
935 * If keyword argument +cause+ is not given,
936 * the cause is the value of <tt>$!</tt>.
937 *
938 * See {Cause}[rdoc-ref:exceptions.md@Cause].
939 *
940 * In the alternate calling sequence,
941 * where argument +exception+ _not_ given,
942 * raises a new exception of the class given by <tt>$!</tt>,
943 * or of class RuntimeError if <tt>$!</tt> is +nil+:
944 *
945 * begin
946 * raise
947 * rescue => x
948 * p x
949 * end
950 * # => RuntimeError
951 *
952 * With argument +exception+ not given,
953 * argument +message+ and keyword argument +cause+ may be given,
954 * but argument +backtrace+ may not be given.
955 */
956
957static VALUE
958f_raise(int c, VALUE *v, VALUE _)
959{
960 return rb_f_raise(c, v);
961}
962
963static VALUE
964make_exception(int argc, const VALUE *argv, int isstr)
965{
966 VALUE mesg, exc;
967
968 mesg = Qnil;
969 switch (argc) {
970 case 0:
971 return Qnil;
972 case 1:
973 exc = argv[0];
974 if (isstr &&! NIL_P(exc)) {
975 mesg = rb_check_string_type(exc);
976 if (!NIL_P(mesg)) {
977 return rb_exc_new3(rb_eRuntimeError, mesg);
978 }
979 }
980
981 case 2:
982 case 3:
983 break;
984 default:
985 rb_error_arity(argc, 0, 3);
986 }
987 if (NIL_P(mesg)) {
988 mesg = rb_check_funcall(argv[0], idException, argc != 1, &argv[1]);
989 }
990 if (UNDEF_P(mesg)) {
991 rb_raise(rb_eTypeError, "exception class/object expected");
992 }
993 if (!rb_obj_is_kind_of(mesg, rb_eException)) {
994 rb_raise(rb_eTypeError, "exception object expected");
995 }
996 if (argc == 3) {
997 set_backtrace(mesg, argv[2]);
998 }
999
1000 return mesg;
1001}
1002
1003VALUE
1004rb_make_exception(int argc, const VALUE *argv)
1005{
1006 return make_exception(argc, argv, TRUE);
1007}
1008
1011static void
1012rb_raise_jump(VALUE mesg, VALUE cause)
1013{
1014 rb_execution_context_t *ec = GET_EC();
1015 const rb_control_frame_t *cfp = ec->cfp;
1016 const rb_callable_method_entry_t *me = rb_vm_frame_method_entry(cfp);
1017 VALUE klass = me->owner;
1018 VALUE self = cfp->self;
1019 ID mid = me->called_id;
1020
1021 rb_vm_pop_frame(ec);
1022 EXEC_EVENT_HOOK(ec, RUBY_EVENT_C_RETURN, self, me->def->original_id, mid, klass, Qnil);
1023
1024 rb_longjmp(ec, TAG_RAISE, mesg, cause);
1025}
1026
1027void
1028rb_jump_tag(int tag)
1029{
1030 if (UNLIKELY(tag < TAG_RETURN || tag > TAG_FATAL)) {
1031 unknown_longjmp_status(tag);
1032 }
1033 EC_JUMP_TAG(GET_EC(), tag);
1034}
1035
1036int
1038{
1039 if (rb_vm_frame_block_handler(GET_EC()->cfp) == VM_BLOCK_HANDLER_NONE) {
1040 return FALSE;
1041 }
1042 else {
1043 return TRUE;
1044 }
1045}
1046
1047int rb_vm_cframe_keyword_p(const rb_control_frame_t *cfp);
1048
1049int
1051{
1052 return rb_vm_cframe_keyword_p(GET_EC()->cfp);
1053}
1054
1056
1057void
1059{
1060 if (!rb_block_given_p()) {
1061 rb_vm_localjump_error("no block given", Qnil, 0);
1062 }
1063}
1064
1065VALUE
1066rb_rescue2(VALUE (* b_proc) (VALUE), VALUE data1,
1067 VALUE (* r_proc) (VALUE, VALUE), VALUE data2, ...)
1068{
1069 va_list ap;
1070 va_start(ap, data2);
1071 VALUE ret = rb_vrescue2(b_proc, data1, r_proc, data2, ap);
1072 va_end(ap);
1073 return ret;
1074}
1075
1076VALUE
1077rb_vrescue2(VALUE (* b_proc) (VALUE), VALUE data1,
1078 VALUE (* r_proc) (VALUE, VALUE), VALUE data2,
1079 va_list args)
1080{
1081 enum ruby_tag_type state;
1082 rb_execution_context_t * volatile ec = GET_EC();
1083 rb_control_frame_t *volatile cfp = ec->cfp;
1084 volatile VALUE result = Qfalse;
1085 volatile VALUE e_info = ec->errinfo;
1086
1087 EC_PUSH_TAG(ec);
1088 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
1089 retry_entry:
1090 result = (*b_proc) (data1);
1091 }
1092 else if (result) {
1093 /* escape from r_proc */
1094 if (state == TAG_RETRY) {
1095 state = TAG_NONE;
1096 ec->errinfo = Qnil;
1097 result = Qfalse;
1098 goto retry_entry;
1099 }
1100 }
1101 else {
1102 rb_vm_rewind_cfp(ec, cfp);
1103
1104 if (state == TAG_RAISE) {
1105 int handle = FALSE;
1106 VALUE eclass;
1107 va_list ap;
1108
1109 result = Qnil;
1110 /* reuses args when raised again after retrying in r_proc */
1111 va_copy(ap, args);
1112 while ((eclass = va_arg(ap, VALUE)) != 0) {
1113 if (rb_obj_is_kind_of(ec->errinfo, eclass)) {
1114 handle = TRUE;
1115 break;
1116 }
1117 }
1118 va_end(ap);
1119
1120 if (handle) {
1121 state = TAG_NONE;
1122 if (r_proc) {
1123 result = (*r_proc) (data2, ec->errinfo);
1124 }
1125 ec->errinfo = e_info;
1126 }
1127 }
1128 }
1129 EC_POP_TAG();
1130 if (state)
1131 EC_JUMP_TAG(ec, state);
1132
1133 return result;
1134}
1135
1136VALUE
1137rb_rescue(VALUE (* b_proc)(VALUE), VALUE data1,
1138 VALUE (* r_proc)(VALUE, VALUE), VALUE data2)
1139{
1140 return rb_rescue2(b_proc, data1, r_proc, data2, rb_eStandardError,
1141 (VALUE)0);
1142}
1143
1144VALUE
1145rb_protect(VALUE (* proc) (VALUE), VALUE data, int *pstate)
1146{
1147 volatile VALUE result = Qnil;
1148 volatile enum ruby_tag_type state;
1149 rb_execution_context_t * volatile ec = GET_EC();
1150 rb_control_frame_t *volatile cfp = ec->cfp;
1151
1152 EC_PUSH_TAG(ec);
1153 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
1154 result = (*proc)(data);
1155 }
1156 else {
1157 rb_vm_rewind_cfp(ec, cfp);
1158 }
1159 EC_POP_TAG();
1160
1161 if (pstate != NULL) *pstate = state;
1162 return result;
1163}
1164
1165VALUE
1166rb_ensure(VALUE (*b_proc)(VALUE), VALUE data1, VALUE (*e_proc)(VALUE), VALUE data2)
1167{
1168 enum ruby_tag_type state;
1169 volatile VALUE result = Qnil;
1170 VALUE errinfo;
1171 rb_execution_context_t * volatile ec = GET_EC();
1172 EC_PUSH_TAG(ec);
1173 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
1174 result = (*b_proc) (data1);
1175 }
1176 EC_POP_TAG();
1177 errinfo = ec->errinfo;
1178 if (!NIL_P(errinfo) && !RB_TYPE_P(errinfo, T_OBJECT)) {
1179 ec->errinfo = Qnil;
1180 }
1181 (*e_proc)(data2);
1182 ec->errinfo = errinfo;
1183 if (state)
1184 EC_JUMP_TAG(ec, state);
1185 return result;
1186}
1187
1188static ID
1189frame_func_id(const rb_control_frame_t *cfp)
1190{
1191 const rb_callable_method_entry_t *me = rb_vm_frame_method_entry(cfp);
1192
1193 if (me) {
1194 return me->def->original_id;
1195 }
1196 else {
1197 return 0;
1198 }
1199}
1200
1201static ID
1202frame_called_id(rb_control_frame_t *cfp)
1203{
1204 const rb_callable_method_entry_t *me = rb_vm_frame_method_entry(cfp);
1205
1206 if (me) {
1207 return me->called_id;
1208 }
1209 else {
1210 return 0;
1211 }
1212}
1213
1214ID
1215rb_frame_this_func(void)
1216{
1217 return frame_func_id(GET_EC()->cfp);
1218}
1219
1220ID
1221rb_frame_callee(void)
1222{
1223 return frame_called_id(GET_EC()->cfp);
1224}
1225
1226static rb_control_frame_t *
1227previous_frame(const rb_execution_context_t *ec)
1228{
1229 rb_control_frame_t *prev_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(ec->cfp);
1230 /* check if prev_cfp can be accessible */
1231 if ((void *)(ec->vm_stack + ec->vm_stack_size) == (void *)(prev_cfp)) {
1232 return 0;
1233 }
1234 return prev_cfp;
1235}
1236
1237static ID
1238prev_frame_callee(void)
1239{
1240 rb_control_frame_t *prev_cfp = previous_frame(GET_EC());
1241 if (!prev_cfp) return 0;
1242 return frame_called_id(prev_cfp);
1243}
1244
1245static ID
1246prev_frame_func(void)
1247{
1248 rb_control_frame_t *prev_cfp = previous_frame(GET_EC());
1249 if (!prev_cfp) return 0;
1250 return frame_func_id(prev_cfp);
1251}
1252
1259ID
1260rb_frame_last_func(void)
1261{
1262 const rb_execution_context_t *ec = GET_EC();
1263 const rb_control_frame_t *cfp = ec->cfp;
1264 ID mid;
1265
1266 while (!(mid = frame_func_id(cfp)) &&
1267 (cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp),
1268 !RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(ec, cfp)));
1269 return mid;
1270}
1271
1272/*
1273 * call-seq:
1274 * append_features(mod) -> mod
1275 *
1276 * When this module is included in another, Ruby calls
1277 * #append_features in this module, passing it the receiving module
1278 * in _mod_. Ruby's default implementation is to add the constants,
1279 * methods, and module variables of this module to _mod_ if this
1280 * module has not already been added to _mod_ or one of its
1281 * ancestors. See also Module#include.
1282 */
1283
1284static VALUE
1285rb_mod_append_features(VALUE module, VALUE include)
1286{
1287 if (!CLASS_OR_MODULE_P(include)) {
1288 Check_Type(include, T_CLASS);
1289 }
1290 rb_include_module(include, module);
1291
1292 return module;
1293}
1294
1295static VALUE refinement_import_methods(int argc, VALUE *argv, VALUE refinement);
1296
1297/*
1298 * call-seq:
1299 * include(module, ...) -> self
1300 *
1301 * Invokes Module.append_features on each parameter in reverse order.
1302 */
1303
1304static VALUE
1305rb_mod_include(int argc, VALUE *argv, VALUE module)
1306{
1307 int i;
1308 ID id_append_features, id_included;
1309
1310 CONST_ID(id_append_features, "append_features");
1311 CONST_ID(id_included, "included");
1312
1313 if (BUILTIN_TYPE(module) == T_MODULE && FL_TEST(module, RMODULE_IS_REFINEMENT)) {
1314 rb_raise(rb_eTypeError, "Refinement#include has been removed");
1315 }
1316
1318 for (i = 0; i < argc; i++) {
1319 Check_Type(argv[i], T_MODULE);
1320 if (FL_TEST(argv[i], RMODULE_IS_REFINEMENT)) {
1321 rb_raise(rb_eTypeError, "Cannot include refinement");
1322 }
1323 }
1324 while (argc--) {
1325 rb_funcall(argv[argc], id_append_features, 1, module);
1326 rb_funcall(argv[argc], id_included, 1, module);
1327 }
1328 return module;
1329}
1330
1331/*
1332 * call-seq:
1333 * prepend_features(mod) -> mod
1334 *
1335 * When this module is prepended in another, Ruby calls
1336 * #prepend_features in this module, passing it the receiving module
1337 * in _mod_. Ruby's default implementation is to overlay the
1338 * constants, methods, and module variables of this module to _mod_
1339 * if this module has not already been added to _mod_ or one of its
1340 * ancestors. See also Module#prepend.
1341 */
1342
1343static VALUE
1344rb_mod_prepend_features(VALUE module, VALUE prepend)
1345{
1346 if (!CLASS_OR_MODULE_P(prepend)) {
1347 Check_Type(prepend, T_CLASS);
1348 }
1349 rb_prepend_module(prepend, module);
1350
1351 return module;
1352}
1353
1354/*
1355 * call-seq:
1356 * prepend(module, ...) -> self
1357 *
1358 * Invokes Module.prepend_features on each parameter in reverse order.
1359 */
1360
1361static VALUE
1362rb_mod_prepend(int argc, VALUE *argv, VALUE module)
1363{
1364 int i;
1365 ID id_prepend_features, id_prepended;
1366
1367 if (BUILTIN_TYPE(module) == T_MODULE && FL_TEST(module, RMODULE_IS_REFINEMENT)) {
1368 rb_raise(rb_eTypeError, "Refinement#prepend has been removed");
1369 }
1370
1371 CONST_ID(id_prepend_features, "prepend_features");
1372 CONST_ID(id_prepended, "prepended");
1373
1375 for (i = 0; i < argc; i++) {
1376 Check_Type(argv[i], T_MODULE);
1377 if (FL_TEST(argv[i], RMODULE_IS_REFINEMENT)) {
1378 rb_raise(rb_eTypeError, "Cannot prepend refinement");
1379 }
1380 }
1381 while (argc--) {
1382 rb_funcall(argv[argc], id_prepend_features, 1, module);
1383 rb_funcall(argv[argc], id_prepended, 1, module);
1384 }
1385 return module;
1386}
1387
1388static void
1389ensure_class_or_module(VALUE obj)
1390{
1391 if (!RB_TYPE_P(obj, T_CLASS) && !RB_TYPE_P(obj, T_MODULE)) {
1392 rb_raise(rb_eTypeError,
1393 "wrong argument type %"PRIsVALUE" (expected Class or Module)",
1394 rb_obj_class(obj));
1395 }
1396}
1397
1398static VALUE
1399hidden_identity_hash_new(void)
1400{
1401 VALUE hash = rb_ident_hash_new();
1402
1403 RBASIC_CLEAR_CLASS(hash); /* hide from ObjectSpace */
1404 return hash;
1405}
1406
1407static VALUE
1408refinement_superclass(VALUE superclass)
1409{
1410 if (RB_TYPE_P(superclass, T_MODULE)) {
1411 /* FIXME: Should ancestors of superclass be used here? */
1412 return rb_include_class_new(RCLASS_ORIGIN(superclass), rb_cBasicObject);
1413 }
1414 else {
1415 return superclass;
1416 }
1417}
1418
1422static void
1423rb_using_refinement(rb_cref_t *cref, VALUE klass, VALUE module)
1424{
1425 VALUE iclass, c, superclass = klass;
1426
1427 ensure_class_or_module(klass);
1428 Check_Type(module, T_MODULE);
1429 if (NIL_P(CREF_REFINEMENTS(cref))) {
1430 CREF_REFINEMENTS_SET(cref, hidden_identity_hash_new());
1431 }
1432 else {
1433 if (CREF_OMOD_SHARED(cref)) {
1434 CREF_REFINEMENTS_SET(cref, rb_hash_dup(CREF_REFINEMENTS(cref)));
1435 CREF_OMOD_SHARED_UNSET(cref);
1436 }
1437 if (!NIL_P(c = rb_hash_lookup(CREF_REFINEMENTS(cref), klass))) {
1438 superclass = c;
1439 while (c && RB_TYPE_P(c, T_ICLASS)) {
1440 if (RBASIC(c)->klass == module) {
1441 /* already used refinement */
1442 return;
1443 }
1444 c = RCLASS_SUPER(c);
1445 }
1446 }
1447 }
1448 superclass = refinement_superclass(superclass);
1449 c = iclass = rb_include_class_new(module, superclass);
1450 RCLASS_SET_REFINED_CLASS(c, klass);
1451
1452 RCLASS_WRITE_M_TBL(c, RCLASS_M_TBL(module));
1453
1454 rb_hash_aset(CREF_REFINEMENTS(cref), klass, iclass);
1455}
1456
1457static int
1458using_refinement(VALUE klass, VALUE module, VALUE arg)
1459{
1460 rb_cref_t *cref = (rb_cref_t *) arg;
1461
1462 rb_using_refinement(cref, klass, module);
1463 return ST_CONTINUE;
1464}
1465
1466static void
1467using_module_recursive(const rb_cref_t *cref, VALUE klass)
1468{
1469 ID id_refinements;
1470 VALUE super, module, refinements;
1471
1472 super = RCLASS_SUPER(klass);
1473 if (super) {
1474 using_module_recursive(cref, super);
1475 }
1476 switch (BUILTIN_TYPE(klass)) {
1477 case T_MODULE:
1478 module = klass;
1479 break;
1480
1481 case T_ICLASS:
1482 module = RBASIC(klass)->klass;
1483 break;
1484
1485 default:
1486 rb_raise(rb_eTypeError, "wrong argument type %s (expected Module)",
1487 rb_obj_classname(klass));
1488 break;
1489 }
1490 CONST_ID(id_refinements, "__refinements__");
1491 refinements = rb_attr_get(module, id_refinements);
1492 if (NIL_P(refinements)) return;
1493 rb_hash_foreach(refinements, using_refinement, (VALUE) cref);
1494}
1495
1499static void
1500rb_using_module(const rb_cref_t *cref, VALUE module)
1501{
1502 Check_Type(module, T_MODULE);
1503 using_module_recursive(cref, module);
1504 rb_clear_all_refinement_method_cache();
1505}
1506
1507void
1508rb_vm_using_module(VALUE module)
1509{
1510 rb_using_module(rb_vm_cref_replace_with_duplicated_cref(), module);
1511}
1512
1513/*
1514 * call-seq:
1515 * target -> class_or_module
1516 *
1517 * Return the class or module refined by the receiver.
1518 *
1519 * module M
1520 * refine String do
1521 * end
1522 * end
1523 *
1524 * M.refinements[0].target # => String
1525 */
1526VALUE
1527rb_refinement_module_get_refined_class(VALUE module)
1528{
1529 ID id_refined_class;
1530
1531 CONST_ID(id_refined_class, "__refined_class__");
1532 return rb_attr_get(module, id_refined_class);
1533}
1534
1535static void
1536add_activated_refinement(VALUE activated_refinements,
1537 VALUE klass, VALUE refinement)
1538{
1539 VALUE iclass, c, superclass = klass;
1540
1541 if (!NIL_P(c = rb_hash_lookup(activated_refinements, klass))) {
1542 superclass = c;
1543 while (c && RB_TYPE_P(c, T_ICLASS)) {
1544 if (RBASIC(c)->klass == refinement) {
1545 /* already used refinement */
1546 return;
1547 }
1548 c = RCLASS_SUPER(c);
1549 }
1550 }
1551 superclass = refinement_superclass(superclass);
1552 c = iclass = rb_include_class_new(refinement, superclass);
1553 RCLASS_SET_REFINED_CLASS(c, klass);
1554 refinement = RCLASS_SUPER(refinement);
1555 while (refinement && refinement != klass) {
1556 c = rb_class_set_super(c, rb_include_class_new(refinement, RCLASS_SUPER(c)));
1557 RCLASS_SET_REFINED_CLASS(c, klass);
1558 refinement = RCLASS_SUPER(refinement);
1559 }
1560 rb_hash_aset(activated_refinements, klass, iclass);
1561}
1562
1563void
1564rb_refinement_setup(struct rb_refinements_data *data, VALUE module, VALUE klass)
1565{
1566 VALUE refinement;
1567 ID id_refinements, id_activated_refinements,
1568 id_refined_class, id_defined_at;
1569 VALUE refinements, activated_refinements;
1570
1571 CONST_ID(id_refinements, "__refinements__");
1572 refinements = rb_attr_get(module, id_refinements);
1573 if (NIL_P(refinements)) {
1574 refinements = hidden_identity_hash_new();
1575 rb_ivar_set(module, id_refinements, refinements);
1576 }
1577 CONST_ID(id_activated_refinements, "__activated_refinements__");
1578 activated_refinements = rb_attr_get(module, id_activated_refinements);
1579 if (NIL_P(activated_refinements)) {
1580 activated_refinements = hidden_identity_hash_new();
1581 rb_ivar_set(module, id_activated_refinements,
1582 activated_refinements);
1583 }
1584 refinement = rb_hash_lookup(refinements, klass);
1585 if (NIL_P(refinement)) {
1586 VALUE superclass = refinement_superclass(klass);
1587 refinement = rb_refinement_new();
1588 rb_class_set_super(refinement, superclass);
1589 RUBY_ASSERT(BUILTIN_TYPE(refinement) == T_MODULE);
1590 FL_SET(refinement, RMODULE_IS_REFINEMENT);
1591 CONST_ID(id_refined_class, "__refined_class__");
1592 rb_ivar_set(refinement, id_refined_class, klass);
1593 CONST_ID(id_defined_at, "__defined_at__");
1594 rb_ivar_set(refinement, id_defined_at, module);
1595 rb_hash_aset(refinements, klass, refinement);
1596 add_activated_refinement(activated_refinements, klass, refinement);
1597 }
1598
1599 data->refinement = refinement;
1600 data->refinements = activated_refinements;
1601}
1602
1603/*
1604 * call-seq:
1605 * refine(mod) { block } -> module
1606 *
1607 * Refine <i>mod</i> in the receiver.
1608 *
1609 * Returns a module, where refined methods are defined.
1610 */
1611
1612static VALUE
1613rb_mod_refine(VALUE module, VALUE klass)
1614{
1615 /* module is the receiver of #refine, klass is a module to be refined (`mod` in the doc) */
1616 rb_thread_t *th = GET_THREAD();
1617 VALUE block_handler = rb_vm_frame_block_handler(th->ec->cfp);
1618 struct rb_refinements_data data;
1619
1620 if (block_handler == VM_BLOCK_HANDLER_NONE) {
1621 rb_raise(rb_eArgError, "no block given");
1622 }
1623 if (vm_block_handler_type(block_handler) != block_handler_type_iseq) {
1624 rb_raise(rb_eArgError, "can't pass a Proc as a block to Module#refine");
1625 }
1626
1627 ensure_class_or_module(klass);
1628
1629 rb_refinement_setup(&data, module, klass);
1630
1631 rb_yield_refine_block(data.refinement, data.refinements);
1632 return data.refinement;
1633}
1634
1635static void
1636ignored_block(VALUE module, const char *klass)
1637{
1638 const char *anon = "";
1639 Check_Type(module, T_MODULE);
1640 if (!RTEST(rb_search_class_path(module))) {
1641 anon = ", maybe for Module.new";
1642 }
1643 rb_warn("%s""using doesn't call the given block""%s.", klass, anon);
1644}
1645
1646/*
1647 * call-seq:
1648 * using(module) -> self
1649 *
1650 * Import class refinements from <i>module</i> into the current class or
1651 * module definition.
1652 */
1653
1654static VALUE
1655mod_using(VALUE self, VALUE module)
1656{
1657 rb_control_frame_t *prev_cfp = previous_frame(GET_EC());
1658
1659 if (prev_frame_func()) {
1660 rb_raise(rb_eRuntimeError,
1661 "Module#using is not permitted in methods");
1662 }
1663 if (prev_cfp && prev_cfp->self != self) {
1664 rb_raise(rb_eRuntimeError, "Module#using is not called on self");
1665 }
1666 if (rb_block_given_p()) {
1667 ignored_block(module, "Module#");
1668 }
1669 rb_using_module(rb_vm_cref_replace_with_duplicated_cref(), module);
1670 return self;
1671}
1672
1673
1674/*
1675 * call-seq:
1676 * refinements -> array
1677 *
1678 * Returns an array of +Refinement+ defined within the receiver.
1679 *
1680 * module A
1681 * refine Integer do
1682 * end
1683 *
1684 * refine String do
1685 * end
1686 * end
1687 *
1688 * p A.refinements
1689 *
1690 * <em>produces:</em>
1691 *
1692 * [#<refinement:Integer@A>, #<refinement:String@A>]
1693 */
1694static VALUE
1695mod_refinements(VALUE self)
1696{
1697 ID id_refinements;
1698 VALUE refinements;
1699
1700 CONST_ID(id_refinements, "__refinements__");
1701 refinements = rb_attr_get(self, id_refinements);
1702 if (NIL_P(refinements)) {
1703 return rb_ary_new();
1704 }
1705 return rb_hash_values(refinements);
1706}
1707
1708static int
1709used_modules_i(VALUE _, VALUE mod, VALUE ary)
1710{
1711 ID id_defined_at;
1712 CONST_ID(id_defined_at, "__defined_at__");
1713 while (BUILTIN_TYPE(rb_class_of(mod)) == T_MODULE && FL_TEST(rb_class_of(mod), RMODULE_IS_REFINEMENT)) {
1714 rb_ary_push(ary, rb_attr_get(rb_class_of(mod), id_defined_at));
1715 mod = RCLASS_SUPER(mod);
1716 }
1717 return ST_CONTINUE;
1718}
1719
1720/*
1721 * call-seq:
1722 * used_modules -> array
1723 *
1724 * Returns an array of all modules used in the current scope. The ordering
1725 * of modules in the resulting array is not defined.
1726 *
1727 * module A
1728 * refine Object do
1729 * end
1730 * end
1731 *
1732 * module B
1733 * refine Object do
1734 * end
1735 * end
1736 *
1737 * using A
1738 * using B
1739 * p Module.used_modules
1740 *
1741 * <em>produces:</em>
1742 *
1743 * [B, A]
1744 */
1745static VALUE
1746rb_mod_s_used_modules(VALUE _)
1747{
1748 const rb_cref_t *cref = rb_vm_cref();
1749 VALUE ary = rb_ary_new();
1750
1751 while (cref) {
1752 if (!NIL_P(CREF_REFINEMENTS(cref))) {
1753 rb_hash_foreach(CREF_REFINEMENTS(cref), used_modules_i, ary);
1754 }
1755 cref = CREF_NEXT(cref);
1756 }
1757
1758 return rb_funcall(ary, rb_intern("uniq"), 0);
1759}
1760
1761static int
1762used_refinements_i(VALUE _, VALUE mod, VALUE ary)
1763{
1764 while (BUILTIN_TYPE(rb_class_of(mod)) == T_MODULE && FL_TEST(rb_class_of(mod), RMODULE_IS_REFINEMENT)) {
1765 rb_ary_push(ary, rb_class_of(mod));
1766 mod = RCLASS_SUPER(mod);
1767 }
1768 return ST_CONTINUE;
1769}
1770
1771/*
1772 * call-seq:
1773 * used_refinements -> array
1774 *
1775 * Returns an array of all modules used in the current scope. The ordering
1776 * of modules in the resulting array is not defined.
1777 *
1778 * module A
1779 * refine Object do
1780 * end
1781 * end
1782 *
1783 * module B
1784 * refine Object do
1785 * end
1786 * end
1787 *
1788 * using A
1789 * using B
1790 * p Module.used_refinements
1791 *
1792 * <em>produces:</em>
1793 *
1794 * [#<refinement:Object@B>, #<refinement:Object@A>]
1795 */
1796static VALUE
1797rb_mod_s_used_refinements(VALUE _)
1798{
1799 const rb_cref_t *cref = rb_vm_cref();
1800 VALUE ary = rb_ary_new();
1801
1802 while (cref) {
1803 if (!NIL_P(CREF_REFINEMENTS(cref))) {
1804 rb_hash_foreach(CREF_REFINEMENTS(cref), used_refinements_i, ary);
1805 }
1806 cref = CREF_NEXT(cref);
1807 }
1808
1809 return ary;
1810}
1811
1813 rb_cref_t *cref;
1814 VALUE refinement;
1815 VALUE module;
1816};
1817
1818/* vm.c */
1819rb_cref_t *rb_vm_cref_dup_without_refinements(const rb_cref_t *cref);
1820
1821static enum rb_id_table_iterator_result
1822refinement_import_methods_i(ID key, VALUE value, void *data)
1823{
1824 const rb_method_entry_t *me = (const rb_method_entry_t *)value;
1826
1827 if (me->def->type != VM_METHOD_TYPE_ISEQ) {
1828 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));
1829 }
1830 rb_cref_t *new_cref = rb_vm_cref_dup_without_refinements(me->def->body.iseq.cref);
1831 CREF_REFINEMENTS_SET(new_cref, CREF_REFINEMENTS(arg->cref));
1832 rb_add_method_iseq(arg->refinement, key, me->def->body.iseq.iseqptr, new_cref, METHOD_ENTRY_VISI(me));
1833 return ID_TABLE_CONTINUE;
1834}
1835
1836/*
1837 * Note: docs for the method are in class.c
1838 */
1839
1840static VALUE
1841refinement_import_methods(int argc, VALUE *argv, VALUE refinement)
1842{
1843 int i;
1845
1847 for (i = 0; i < argc; i++) {
1848 Check_Type(argv[i], T_MODULE);
1849 if (RCLASS_SUPER(argv[i])) {
1850 rb_warn("%"PRIsVALUE" has ancestors, but Refinement#import_methods doesn't import their methods", rb_class_path(argv[i]));
1851 }
1852 }
1853 arg.cref = rb_vm_cref_replace_with_duplicated_cref();
1854 arg.refinement = refinement;
1855 for (i = 0; i < argc; i++) {
1856 arg.module = argv[i];
1857 struct rb_id_table *m_tbl = RCLASS_M_TBL(argv[i]);
1858 if (!m_tbl) continue;
1859 rb_id_table_foreach(m_tbl, refinement_import_methods_i, &arg);
1860 }
1861 return refinement;
1862}
1863
1864void
1865rb_obj_call_init(VALUE obj, int argc, const VALUE *argv)
1866{
1867 rb_obj_call_init_kw(obj, argc, argv, RB_NO_KEYWORDS);
1868}
1869
1870void
1871rb_obj_call_init_kw(VALUE obj, int argc, const VALUE *argv, int kw_splat)
1872{
1873 PASS_PASSED_BLOCK_HANDLER();
1874 rb_funcallv_kw(obj, idInitialize, argc, argv, kw_splat);
1875}
1876
1877void
1879{
1881}
1882
1883/*
1884 * call-seq:
1885 * extend_object(obj) -> obj
1886 *
1887 * Extends the specified object by adding this module's constants and
1888 * methods (which are added as singleton methods). This is the callback
1889 * method used by Object#extend.
1890 *
1891 * module Picky
1892 * def Picky.extend_object(o)
1893 * if String === o
1894 * puts "Can't add Picky to a String"
1895 * else
1896 * puts "Picky added to #{o.class}"
1897 * super
1898 * end
1899 * end
1900 * end
1901 * (s = Array.new).extend Picky # Call Object.extend
1902 * (s = "quick brown fox").extend Picky
1903 *
1904 * <em>produces:</em>
1905 *
1906 * Picky added to Array
1907 * Can't add Picky to a String
1908 */
1909
1910static VALUE
1911rb_mod_extend_object(VALUE mod, VALUE obj)
1912{
1913 rb_extend_object(obj, mod);
1914 return obj;
1915}
1916
1917/*
1918 * call-seq:
1919 * obj.extend(module, ...) -> obj
1920 *
1921 * Adds to _obj_ the instance methods from each module given as a
1922 * parameter.
1923 *
1924 * module Mod
1925 * def hello
1926 * "Hello from Mod.\n"
1927 * end
1928 * end
1929 *
1930 * class Klass
1931 * def hello
1932 * "Hello from Klass.\n"
1933 * end
1934 * end
1935 *
1936 * k = Klass.new
1937 * k.hello #=> "Hello from Klass.\n"
1938 * k.extend(Mod) #=> #<Klass:0x401b3bc8>
1939 * k.hello #=> "Hello from Mod.\n"
1940 */
1941
1942static VALUE
1943rb_obj_extend(int argc, VALUE *argv, VALUE obj)
1944{
1945 int i;
1946 ID id_extend_object, id_extended;
1947
1948 CONST_ID(id_extend_object, "extend_object");
1949 CONST_ID(id_extended, "extended");
1950
1952 for (i = 0; i < argc; i++) {
1953 Check_Type(argv[i], T_MODULE);
1954 if (FL_TEST(argv[i], RMODULE_IS_REFINEMENT)) {
1955 rb_raise(rb_eTypeError, "Cannot extend object with refinement");
1956 }
1957 }
1958 while (argc--) {
1959 rb_funcall(argv[argc], id_extend_object, 1, obj);
1960 rb_funcall(argv[argc], id_extended, 1, obj);
1961 }
1962 return obj;
1963}
1964
1965VALUE
1966rb_top_main_class(const char *method)
1967{
1968 VALUE klass = GET_THREAD()->top_wrapper;
1969
1970 if (!klass) return rb_cObject;
1971 rb_warning("main.%s in the wrapped load is effective only in wrapper module", method);
1972 return klass;
1973}
1974
1975/*
1976 * call-seq:
1977 * include(module, ...) -> self
1978 *
1979 * Invokes Module.append_features on each parameter in turn.
1980 * Effectively adds the methods and constants in each module to the
1981 * receiver.
1982 */
1983
1984static VALUE
1985top_include(int argc, VALUE *argv, VALUE self)
1986{
1987 return rb_mod_include(argc, argv, rb_top_main_class("include"));
1988}
1989
1990/*
1991 * call-seq:
1992 * using(module) -> self
1993 *
1994 * Import class refinements from <i>module</i> into the scope where
1995 * #using is called.
1996 */
1997
1998static VALUE
1999top_using(VALUE self, VALUE module)
2000{
2001 const rb_cref_t *cref = CREF_NEXT(rb_vm_cref());
2002 rb_control_frame_t *prev_cfp = previous_frame(GET_EC());
2003 rb_thread_t *th = GET_THREAD();
2004
2005 if ((th->top_wrapper ? CREF_NEXT(cref) : cref) ||
2006 (prev_cfp && rb_vm_frame_method_entry(prev_cfp))) {
2007 rb_raise(rb_eRuntimeError, "main.using is permitted only at toplevel");
2008 }
2009 if (rb_block_given_p()) {
2010 ignored_block(module, "main.");
2011 }
2012 rb_using_module(rb_vm_cref_replace_with_duplicated_cref(), module);
2013 return self;
2014}
2015
2016static const VALUE *
2017errinfo_place(const rb_execution_context_t *ec)
2018{
2019 const rb_control_frame_t *cfp = ec->cfp;
2020 const rb_control_frame_t *end_cfp = RUBY_VM_END_CONTROL_FRAME(ec);
2021
2022 while (RUBY_VM_VALID_CONTROL_FRAME_P(cfp, end_cfp)) {
2023 if (VM_FRAME_RUBYFRAME_P(cfp)) {
2024 if (ISEQ_BODY(cfp->iseq)->type == ISEQ_TYPE_RESCUE) {
2025 return &cfp->ep[VM_ENV_INDEX_LAST_LVAR];
2026 }
2027 else if (ISEQ_BODY(cfp->iseq)->type == ISEQ_TYPE_ENSURE &&
2028 !THROW_DATA_P(cfp->ep[VM_ENV_INDEX_LAST_LVAR]) &&
2029 !FIXNUM_P(cfp->ep[VM_ENV_INDEX_LAST_LVAR])) {
2030 return &cfp->ep[VM_ENV_INDEX_LAST_LVAR];
2031 }
2032 }
2033 cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
2034 }
2035 return 0;
2036}
2037
2038VALUE
2039rb_ec_get_errinfo(const rb_execution_context_t *ec)
2040{
2041 const VALUE *ptr = errinfo_place(ec);
2042 if (ptr) {
2043 return *ptr;
2044 }
2045 else {
2046 return ec->errinfo;
2047 }
2048}
2049
2050static VALUE
2051get_errinfo(void)
2052{
2053 return get_ec_errinfo(GET_EC());
2054}
2055
2056static VALUE
2057errinfo_getter(ID id, VALUE *_)
2058{
2059 return get_errinfo();
2060}
2061
2062VALUE
2064{
2065 return GET_EC()->errinfo;
2066}
2067
2068void
2069rb_set_errinfo(VALUE err)
2070{
2071 if (!NIL_P(err) && !rb_obj_is_kind_of(err, rb_eException)) {
2072 rb_raise(rb_eTypeError, "assigning non-exception to $!");
2073 }
2074 GET_EC()->errinfo = err;
2075}
2076
2077static VALUE
2078errat_getter(ID id, VALUE *_)
2079{
2080 VALUE err = get_errinfo();
2081 if (!NIL_P(err)) {
2082 return rb_get_backtrace(err);
2083 }
2084 else {
2085 return Qnil;
2086 }
2087}
2088
2089static void
2090errat_setter(VALUE val, ID id, VALUE *var)
2091{
2092 VALUE err = get_errinfo();
2093 if (NIL_P(err)) {
2094 rb_raise(rb_eArgError, "$! not set");
2095 }
2096 set_backtrace(err, val);
2097}
2098
2099/*
2100 * call-seq:
2101 * __method__ -> symbol
2102 *
2103 * Returns the name at the definition of the current method as a
2104 * Symbol.
2105 * If called outside of a method, it returns <code>nil</code>.
2106 *
2107 */
2108
2109static VALUE
2110rb_f_method_name(VALUE _)
2111{
2112 ID fname = prev_frame_func(); /* need *method* ID */
2113
2114 if (fname) {
2115 return ID2SYM(fname);
2116 }
2117 else {
2118 return Qnil;
2119 }
2120}
2121
2122/*
2123 * call-seq:
2124 * __callee__ -> symbol
2125 *
2126 * Returns the called name of the current method as a Symbol.
2127 * If called outside of a method, it returns <code>nil</code>.
2128 *
2129 */
2130
2131static VALUE
2132rb_f_callee_name(VALUE _)
2133{
2134 ID fname = prev_frame_callee(); /* need *callee* ID */
2135
2136 if (fname) {
2137 return ID2SYM(fname);
2138 }
2139 else {
2140 return Qnil;
2141 }
2142}
2143
2144/*
2145 * call-seq:
2146 * __dir__ -> string
2147 *
2148 * Returns the canonicalized absolute path of the directory of the file from
2149 * which this method is called. It means symlinks in the path is resolved.
2150 * If <code>__FILE__</code> is <code>nil</code>, it returns <code>nil</code>.
2151 * The return value equals to <code>File.dirname(File.realpath(__FILE__))</code>.
2152 *
2153 */
2154static VALUE
2155f_current_dirname(VALUE _)
2156{
2157 VALUE base = rb_current_realfilepath();
2158 if (NIL_P(base)) {
2159 return Qnil;
2160 }
2161 base = rb_file_dirname(base);
2162 return base;
2163}
2164
2165/*
2166 * call-seq:
2167 * global_variables -> array
2168 *
2169 * Returns an array of the names of global variables. This includes
2170 * special regexp global variables such as <tt>$~</tt> and <tt>$+</tt>,
2171 * but does not include the numbered regexp global variables (<tt>$1</tt>,
2172 * <tt>$2</tt>, etc.).
2173 *
2174 * global_variables.grep /std/ #=> [:$stdin, :$stdout, :$stderr]
2175 */
2176
2177static VALUE
2178f_global_variables(VALUE _)
2179{
2180 return rb_f_global_variables();
2181}
2182
2183/*
2184 * call-seq:
2185 * trace_var(symbol, cmd ) -> nil
2186 * trace_var(symbol) {|val| block } -> nil
2187 *
2188 * Controls tracing of assignments to global variables. The parameter
2189 * +symbol+ identifies the variable (as either a string name or a
2190 * symbol identifier). _cmd_ (which may be a string or a
2191 * +Proc+ object) or block is executed whenever the variable
2192 * is assigned. The block or +Proc+ object receives the
2193 * variable's new value as a parameter. Also see
2194 * #untrace_var.
2195 *
2196 * trace_var :$_, proc {|v| puts "$_ is now '#{v}'" }
2197 * $_ = "hello"
2198 * $_ = ' there'
2199 *
2200 * <em>produces:</em>
2201 *
2202 * $_ is now 'hello'
2203 * $_ is now ' there'
2204 */
2205
2206static VALUE
2207f_trace_var(int c, const VALUE *a, VALUE _)
2208{
2209 return rb_f_trace_var(c, a);
2210}
2211
2212/*
2213 * call-seq:
2214 * untrace_var(symbol [, cmd] ) -> array or nil
2215 *
2216 * Removes tracing for the specified command on the given global
2217 * variable and returns +nil+. If no command is specified,
2218 * removes all tracing for that variable and returns an array
2219 * containing the commands actually removed.
2220 */
2221
2222static VALUE
2223f_untrace_var(int c, const VALUE *a, VALUE _)
2224{
2225 return rb_f_untrace_var(c, a);
2226}
2227
2228void
2229Init_eval(void)
2230{
2231 rb_define_virtual_variable("$@", errat_getter, errat_setter);
2232 rb_define_virtual_variable("$!", errinfo_getter, 0);
2233
2234 rb_gvar_ractor_local("$@");
2235 rb_gvar_ractor_local("$!");
2236
2237 rb_define_global_function("raise", f_raise, -1);
2238 rb_define_global_function("fail", f_raise, -1);
2239
2240 rb_define_global_function("global_variables", f_global_variables, 0);
2241
2242 rb_define_global_function("__method__", rb_f_method_name, 0);
2243 rb_define_global_function("__callee__", rb_f_callee_name, 0);
2244 rb_define_global_function("__dir__", f_current_dirname, 0);
2245
2246 rb_define_method(rb_cModule, "include", rb_mod_include, -1);
2247 rb_define_method(rb_cModule, "prepend", rb_mod_prepend, -1);
2248
2249 rb_define_private_method(rb_cModule, "append_features", rb_mod_append_features, 1);
2250 rb_define_private_method(rb_cModule, "extend_object", rb_mod_extend_object, 1);
2251 rb_define_private_method(rb_cModule, "prepend_features", rb_mod_prepend_features, 1);
2252 rb_define_private_method(rb_cModule, "refine", rb_mod_refine, 1);
2253 rb_define_private_method(rb_cModule, "using", mod_using, 1);
2254 rb_define_method(rb_cModule, "refinements", mod_refinements, 0);
2255 rb_define_singleton_method(rb_cModule, "used_modules",
2256 rb_mod_s_used_modules, 0);
2257 rb_define_singleton_method(rb_cModule, "used_refinements",
2258 rb_mod_s_used_refinements, 0);
2259 rb_undef_method(rb_cClass, "refine");
2260 rb_define_private_method(rb_cRefinement, "import_methods", refinement_import_methods, -1);
2261 rb_define_method(rb_cRefinement, "target", rb_refinement_module_get_refined_class, 0);
2262 rb_undef_method(rb_cRefinement, "append_features");
2263 rb_undef_method(rb_cRefinement, "prepend_features");
2264 rb_undef_method(rb_cRefinement, "extend_object");
2265
2266 rb_undef_method(rb_cClass, "module_function");
2267
2268 Init_vm_eval();
2269 Init_eval_method();
2270
2271 rb_define_singleton_method(rb_cModule, "nesting", rb_mod_nesting, 0);
2272 rb_define_singleton_method(rb_cModule, "constants", rb_mod_s_constants, -1);
2273
2275 "include", top_include, -1);
2277 "using", top_using, 1);
2278
2279 rb_define_method(rb_mKernel, "extend", rb_obj_extend, -1);
2280
2281 rb_define_global_function("trace_var", f_trace_var, -1);
2282 rb_define_global_function("untrace_var", f_untrace_var, -1);
2283
2284 rb_vm_register_special_exception(ruby_error_reenter, rb_eFatal, "exception reentered");
2285 rb_vm_register_special_exception(ruby_error_stackfatal, rb_eFatal, "machine stack overflow in critical region");
2286
2287 id_signo = rb_intern_const("signo");
2288 id_status = rb_intern_const("status");
2289}
2290
2291int
2292rb_errno(void)
2293{
2294 return *rb_orig_errno_ptr();
2295}
2296
2297void
2298rb_errno_set(int e)
2299{
2300 *rb_orig_errno_ptr() = e;
2301}
2302
2303int *
2304rb_errno_ptr(void)
2305{
2306 return rb_orig_errno_ptr();
2307}
#define RUBY_ASSERT(...)
Asserts that the given expression is truthy if and only if RUBY_DEBUG is truthy.
Definition assert.h:219
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
#define rb_define_private_method(klass, mid, func, arity)
Defines klass#mid and makes it private.
#define rb_define_global_function(mid, func, arity)
Defines rb_mKernel #mid.
#define RUBY_EVENT_RAISE
Encountered a raise statement.
Definition event.h:45
#define RUBY_EVENT_C_RETURN
Return from a method, written in C.
Definition event.h:44
void rb_include_module(VALUE klass, VALUE module)
Includes a module to a class.
Definition class.c:1701
VALUE rb_refinement_new(void)
Creates a new, anonymous refinement.
Definition class.c:1589
void rb_extend_object(VALUE obj, VALUE module)
Extend the object with the module.
Definition eval.c:1878
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:1951
VALUE rb_singleton_class(VALUE obj)
Finds or creates the singleton class of the passed object.
Definition class.c:2805
void rb_class_modify_check(VALUE klass)
Asserts that klass is not a frozen class.
Definition eval.c:421
void rb_need_block(void)
Declares that the current method needs a block.
Definition eval.c:1058
void rb_undef_method(VALUE klass, const char *name)
Defines an undef of a method.
Definition class.c:2673
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Retrieves argument from argc and argv to given VALUE references according to the format string.
Definition class.c:3143
int rb_keyword_given_p(void)
Determines if the current method is given a keyword argument.
Definition eval.c:1050
int rb_block_given_p(void)
Determines if the current method is given a block.
Definition eval.c:1037
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
Keyword argument deconstructor.
Definition class.c:2932
#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:136
#define UNREACHABLE
Old name of RBIMPL_UNREACHABLE.
Definition assume.h:28
#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:134
#define UNREACHABLE_RETURN
Old name of RBIMPL_UNREACHABLE_RETURN.
Definition assume.h:29
#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 FL_SET
Old name of RB_FL_SET.
Definition fl_type.h:128
#define rb_exc_new3
Old name of rb_exc_new_str.
Definition error.h:38
#define Qtrue
Old name of RUBY_Qtrue.
#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:130
#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:290
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:170
int ruby_cleanup(int ex)
Destructs the VM.
Definition eval.c:178
void * ruby_process_options(int argc, char **argv)
Identical to ruby_options(), except it raises ruby-level exceptions on failure.
Definition ruby.c:3179
void ruby_prog_init(void)
Defines built-in variables.
Definition ruby.c:3132
void ruby_sig_finalize(void)
Clear signal handlers.
Definition signal.c:1457
#define ruby_debug
This variable controls whether the interpreter is in debug mode.
Definition error.h:486
VALUE rb_eLocalJumpError
LocalJumpError exception.
Definition eval.c:48
VALUE rb_rescue2(VALUE(*b_proc)(VALUE), VALUE data1, VALUE(*r_proc)(VALUE, VALUE), VALUE data2,...)
An equivalent of rescue clause.
Definition eval.c:1066
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
Definition eval.c:683
VALUE rb_eSystemExit
SystemExit exception.
Definition error.c:1423
VALUE rb_eStandardError
StandardError exception.
Definition error.c:1427
VALUE rb_eTypeError
TypeError exception.
Definition error.c:1430
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:1077
void rb_frozen_error_raise(VALUE frozen_obj, const char *fmt,...)
Raises an instance of rb_eFrozenError.
Definition error.c:4120
VALUE rb_eFatal
fatal exception.
Definition error.c:1426
VALUE rb_eInterrupt
Interrupt exception.
Definition error.c:1424
void rb_exc_fatal(VALUE mesg)
Raises a fatal error in the current thread.
Definition eval.c:696
VALUE rb_eRuntimeError
RuntimeError exception.
Definition error.c:1428
void rb_warn(const char *fmt,...)
Identical to rb_warning(), except it reports unless $VERBOSE is nil.
Definition error.c:466
VALUE rb_exc_new(VALUE etype, const char *ptr, long len)
Creates an instance of the passed exception class.
Definition error.c:1468
VALUE rb_eException
Mother of all exceptions.
Definition error.c:1422
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:1137
VALUE rb_ensure(VALUE(*b_proc)(VALUE), VALUE data1, VALUE(*e_proc)(VALUE), VALUE data2)
An equivalent to ensure clause.
Definition eval.c:1166
VALUE rb_errinfo(void)
This is the same as $! in Ruby.
Definition eval.c:2063
VALUE rb_eSysStackError
SystemStackError exception.
Definition eval.c:49
VALUE rb_eThreadError
ThreadError exception.
Definition eval.c:1055
void rb_warning(const char *fmt,...)
Issues a warning.
Definition error.c:497
VALUE rb_cClass
Class class.
Definition object.c:63
VALUE rb_mKernel
Kernel module.
Definition object.c:60
VALUE rb_cRefinement
Refinement class.
Definition object.c:64
static VALUE rb_class_of(VALUE obj)
Object to class mapping function.
Definition globals.h:175
VALUE rb_obj_class(VALUE obj)
Queries the class of an object.
Definition object.c:265
VALUE rb_obj_dup(VALUE obj)
Duplicates the given object.
Definition object.c:583
VALUE rb_cBasicObject
BasicObject class.
Definition object.c:59
VALUE rb_cModule
Module class.
Definition object.c:62
VALUE rb_obj_is_kind_of(VALUE obj, VALUE klass)
Queries if the given object is an instance (of possibly descendants) of the given class.
Definition object.c:910
void ruby_init(void)
Calls ruby_setup() and check error.
Definition eval.c:98
int ruby_executable_node(void *n, int *status)
Checks the return value of ruby_options().
Definition eval.c:296
VALUE rb_funcall(VALUE recv, ID mid, int n,...)
Calls a method.
Definition vm_eval.c:1117
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:1084
VALUE rb_ary_new(void)
Allocates a new, empty array.
VALUE rb_ary_push(VALUE ary, VALUE elem)
Special case of rb_ary_cat() that it adds only one element.
#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:284
void ruby_default_signal(int sig)
Pretends as if there was no custom signal handler.
Definition signal.c:411
#define rb_str_new(str, len)
Allocates an instance of rb_cString.
Definition string.h:1497
#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:1669
VALUE rb_check_string_type(VALUE obj)
Try converting an object to its stringised representation using its to_str method,...
Definition string.c:2925
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:1825
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:913
VALUE rb_const_list(void *)
This is another mysterious API that comes with no documents at all.
Definition variable.c:3646
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:1985
VALUE rb_f_trace_var(int argc, const VALUE *argv)
Traces a global variable.
Definition variable.c:867
VALUE rb_mod_constants(int argc, const VALUE *argv, VALUE recv)
Resembles Module#constants.
Definition variable.c:3678
void * rb_mod_const_of(VALUE, void *)
This is a variant of rb_mod_const_at().
Definition variable.c:3624
void * rb_mod_const_at(VALUE, void *)
This API is mysterious.
Definition variable.c:3609
VALUE rb_ivar_defined(VALUE obj, ID name)
Queries if the instance variable is defined at the object.
Definition variable.c:2064
VALUE rb_f_global_variables(void)
Queries the list of global variables.
Definition variable.c:1108
VALUE rb_class_path(VALUE mod)
Identical to rb_mod_name(), except it returns #<Class: ...> style inspection for anonymous modules.
Definition variable.c:379
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:686
static ID rb_intern_const(const char *str)
This is a "tiny optimisation" over rb_intern().
Definition symbol.h:284
int ruby_vm_destruct(ruby_vm_t *vm)
Destructs the passed VM.
Definition vm.c:3286
void rb_hash_foreach(VALUE q, int_type *w, VALUE e)
Iteration over the given hash.
void rb_define_virtual_variable(const char *q, type *w, void_type *e)
Define a function-backended global variable.
#define RBASIC(obj)
Convenient casting macro.
Definition rbasic.h:40
#define RCLASS_SUPER
Just another name of rb_class_get_superclass.
Definition rclass.h:44
#define RHASH_EMPTY_P(h)
Checks if the hash is empty.
Definition rhash.h:79
const char * rb_obj_classname(VALUE obj)
Queries the name of the class of the passed object.
Definition variable.c:513
static int * rb_orig_errno_ptr(void)
Not sure if it is necessary for extension libraries but this is where the "bare" errno is located.
Definition ruby.h:381
#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:425
#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
Definition method.h:63
CREF (Class REFerence)
Definition method.h:45
Definition method.h:55
rb_cref_t * cref
class reference, should be marked
Definition method.h:144
const rb_iseq_t * iseqptr
iseq pointer, should be separated from iseqval
Definition method.h:143
uintptr_t ID
Type that represents a Ruby identifier such as a variable name.
Definition value.h:52
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:433
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:376