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