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