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