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