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