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