14#include "ruby/internal/config.h"
16#ifdef HAVE_SYS_PRCTL_H
20#include "eval_intern.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"
36#include "probes_helper.h"
39#include "ractor_core.h"
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);
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);
51ID ruby_static_id_signo, ruby_static_id_status;
52extern ID ruby_static_id_cause;
53#define id_cause ruby_static_id_cause
55#define exception_error GET_VM()->special_exceptions[ruby_error_reenter]
57#include "eval_error.c"
60#define CLASS_OR_MODULE_P(obj) \
61 (!SPECIAL_CONST_P(obj) && \
62 (BUILTIN_TYPE(obj) == T_CLASS || BUILTIN_TYPE(obj) == T_MODULE))
67 enum ruby_tag_type state;
76#if defined(__linux__) && defined(PR_SET_THP_DISABLE)
77 prctl(PR_SET_THP_DISABLE, 1, 0, 0, 0);
80 rb_vm_encoded_insn_data_table_init();
86 EC_PUSH_TAG(GET_EC());
87 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
90 GET_VM()->running = 1;
103 rb_execution_context_t *ec = GET_EC();
104 rb_ec_error_print(ec, ec->errinfo);
111ruby_options(
int argc,
char **argv)
113 rb_execution_context_t *ec = GET_EC();
114 enum ruby_tag_type state;
115 void *
volatile iseq = 0;
118 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
122 rb_ec_clear_current_thread_trace_func(ec);
123 int exitcode = error_handle(ec, ec->errinfo, state);
125 iseq = (
void *)
INT2FIX(exitcode);
132rb_ec_fiber_scheduler_finalize(rb_execution_context_t *ec)
134 enum ruby_tag_type state;
137 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
141 state = error_handle(ec, ec->errinfo, state);
147rb_ec_teardown(rb_execution_context_t *ec)
149 enum ruby_tag_type state = TAG_NONE;
153 rb_ec_fiber_scheduler_finalize(ec);
156 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
157 rb_vm_trap_exit(rb_ec_vm_ptr(ec));
160 trap_errinfo = ec->errinfo;
164 rb_ec_exec_end_proc(ec);
165 if (!
NIL_P(trap_errinfo)) {
166 error_handle(ec, trap_errinfo, state);
167 ec->errinfo = trap_errinfo;
169 rb_ec_clear_all_trace_func(ec);
173rb_ec_finalize(rb_execution_context_t *ec)
177 rb_objspace_call_finalizer();
183 rb_execution_context_t *ec = GET_EC();
191 return rb_ec_cleanup(GET_EC(), (
enum ruby_tag_type)ex);
195rb_ec_cleanup(rb_execution_context_t *ec,
enum ruby_tag_type ex)
199 volatile int sysex = EXIT_SUCCESS;
200 volatile int signaled = 0;
201 rb_thread_t *th = rb_ec_thread_ptr(ec);
202 rb_thread_t *
const volatile th0 = th;
203 volatile int step = 0;
207 rb_threadptr_interrupt(th);
208 rb_threadptr_check_signal(th);
211 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
212 RUBY_VM_CHECK_INTS(ec);
215 save_error = ec->errinfo;
216 if (THROW_DATA_P(ec->errinfo)) ec->errinfo =
Qnil;
223 VALUE err = ec->errinfo;
224 volatile int mode0 = 0, mode1 = 0;
225 if (err != save_error && !
NIL_P(err)) {
226 mode0 = exiting_split(err, &sysex, &signaled);
232 err = ATOMIC_VALUE_EXCHANGE(save_error,
Qnil);
234 if (!
NIL_P(err) && !THROW_DATA_P(err)) {
235 mode1 = exiting_split(err, (mode0 & EXITING_WITH_STATUS) ? NULL : &sysex, &signaled);
236 if (mode1 & EXITING_WITH_MESSAGE) {
238 rb_ec_error_print_detailed(ec, err, buf,
Qundef);
245 th->status = THREAD_KILLED;
247 rb_ractor_terminate_all();
250 if (!
NIL_P(buf = message)) {
253 else if (!NIL_OR_UNDEF_P(err = save_error) ||
254 (ex != TAG_NONE && !((mode0|mode1) & EXITING_WITH_STATUS))) {
255 sysex = error_handle(ec, err, ex);
271 rb_threadptr_unlock_all_locking_mutexes(th);
275 rb_thread_stop_timer_thread();
278 rb_jit_cont_finish();
286rb_ec_exec_node(rb_execution_context_t *ec,
void *n)
289 rb_iseq_t *iseq = (rb_iseq_t *)n;
293 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
294 rb_iseq_eval_main(iseq);
313 case Qtrue: s = EXIT_SUCCESS;
break;
314 case Qfalse: s = EXIT_FAILURE;
break;
319 if (status) *status = s;
324ruby_run_node(
void *n)
326 rb_execution_context_t *ec = GET_EC();
329 rb_ec_cleanup(ec, (
NIL_P(ec->errinfo) ? TAG_NONE : TAG_RAISE));
332 return rb_ec_cleanup(ec, rb_ec_exec_node(ec, n));
338 return rb_ec_exec_node(GET_EC(), n);
360 const rb_cref_t *cref = rb_vm_cref();
362 while (cref && CREF_NEXT(cref)) {
363 VALUE klass = CREF_CLASS(cref);
364 if (!CREF_PUSHED_BY_EVAL(cref) &&
368 cref = CREF_NEXT(cref);
396rb_mod_s_constants(
int argc,
VALUE *argv,
VALUE mod)
398 const rb_cref_t *cref = rb_vm_cref();
408 klass = CREF_CLASS(cref);
409 if (!CREF_PUSHED_BY_EVAL(cref) &&
416 cref = CREF_NEXT(cref);
439 rb_class_set_initialized(klass);
442 if (RCLASS_SINGLETON_P(klass)) {
443 klass = RCLASS_ATTACHED_OBJECT(klass);
449NORETURN(
static void rb_longjmp(rb_execution_context_t *,
enum ruby_tag_type,
volatile VALUE,
VALUE));
450static VALUE get_errinfo(
void);
451#define get_ec_errinfo(ec) rb_ec_get_errinfo(ec)
459 CONST_ID(id_true_cause,
"true_cause");
461 cause = rb_attr_get(
rb_eFatal, id_true_cause);
470 if (!
NIL_P(cause) && cause != exc) {
480exc_setup_message(
const rb_execution_context_t *ec,
VALUE mesg,
VALUE *cause)
487 if (INTERNAL_EXCEPTION_P(mesg)) EC_JUMP_TAG(ec, TAG_FATAL);
495 if (UNDEF_P(*cause)) {
501 *cause = get_ec_errinfo(ec);
511 if (!nocircular && !
NIL_P(*cause) && !UNDEF_P(*cause) && *cause != mesg) {
513 rb_exc_check_circular_cause(*cause);
518 rb_raise(rb_eArgError,
"circular causes");
520 if (THROW_DATA_P(c)) {
523 c = rb_attr_get(c, id_cause);
531setup_exception(rb_execution_context_t *ec,
enum ruby_tag_type tag,
volatile VALUE mesg,
VALUE cause)
535 const char *file = rb_source_location_cstr(&line);
536 const char *
const volatile file0 = file;
538 if ((file && !
NIL_P(mesg)) || !UNDEF_P(cause)) {
539 volatile int state = 0;
542 if (EC_EXEC_TAG() == TAG_NONE && !(state = rb_ec_set_raised(ec))) {
543 VALUE bt = rb_get_backtrace(mesg);
544 if (!
NIL_P(bt) || UNDEF_P(cause)) {
549 if (!UNDEF_P(cause) && !THROW_DATA_P(cause)) {
550 exc_setup_cause(mesg, cause);
553 VALUE at = rb_ec_backtrace_object(ec);
555 set_backtrace(mesg, at);
557 rb_ec_reset_raised(ec);
561 if (state)
goto fatal;
570 enum ruby_tag_type state;
574 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
579 e = rb_sprintf(
"Exception '%"PRIsVALUE
"' at %s:%d - %"PRIsVALUE
"\n",
583 e = rb_sprintf(
"Exception '%"PRIsVALUE
"' at %s - %"PRIsVALUE
"\n",
587 e = rb_sprintf(
"Exception '%"PRIsVALUE
"' - %"PRIsVALUE
"\n",
593 if (state == TAG_FATAL && ec->errinfo == exception_error) {
597 rb_ec_reset_raised(ec);
598 EC_JUMP_TAG(ec, state);
602 if (rb_ec_set_raised(ec)) {
606 if (tag != TAG_FATAL) {
613 ec->errinfo = exception_error;
614 rb_ec_reset_raised(ec);
615 EC_JUMP_TAG(ec, TAG_FATAL);
620rb_ec_setup_exception(
const rb_execution_context_t *ec,
VALUE mesg,
VALUE cause)
622 if (UNDEF_P(cause)) {
623 cause = get_ec_errinfo(ec);
626 if (THROW_DATA_P(cause)) {
635rb_longjmp(rb_execution_context_t *ec,
enum ruby_tag_type tag,
volatile VALUE mesg,
VALUE cause)
637 mesg = exc_setup_message(ec, mesg, &cause);
638 setup_exception(ec, tag, mesg, cause);
639 rb_ec_raised_clear(ec);
640 EC_JUMP_TAG(ec, tag);
643static VALUE make_exception(
int argc,
const VALUE *argv,
int isstr);
645NORETURN(
static void rb_exc_exception(
VALUE mesg,
enum ruby_tag_type tag,
VALUE cause));
648rb_exc_exception(
VALUE mesg,
enum ruby_tag_type tag,
VALUE cause)
651 mesg = make_exception(1, &mesg, FALSE);
653 rb_longjmp(GET_EC(), tag, mesg, cause);
666 rb_exc_exception(mesg, TAG_RAISE,
Qundef);
679 rb_exc_exception(mesg, TAG_FATAL,
Qnil);
689extract_raise_options(
int argc,
VALUE *argv,
VALUE *cause)
692 static ID keywords[1] = {0};
701 if (!
NIL_P(options)) {
724rb_exception_setup(
int argc,
VALUE *argv)
726 rb_execution_context_t *ec = GET_EC();
730 argc = extract_raise_options(argc, argv, &cause);
733 if (argc == 0 && !UNDEF_P(cause)) {
734 rb_raise(rb_eArgError,
"only cause is given with no arguments");
743 exception = rb_make_exception(argc, argv);
749 if (UNDEF_P(cause)) {
751 resolved_cause = rb_ec_get_errinfo(ec);
754 if (resolved_cause == exception) {
755 resolved_cause =
Qnil;
758 else if (
NIL_P(cause)) {
760 resolved_cause =
Qnil;
768 if (cause == exception) {
770 resolved_cause =
Qnil;
774 VALUE current_cause = cause;
775 while (!
NIL_P(current_cause)) {
777 if (current_cause == exception) {
778 rb_raise(rb_eArgError,
"circular causes");
780 if (THROW_DATA_P(current_cause)) {
783 current_cause = rb_attr_get(current_cause, id_cause);
785 resolved_cause = cause;
790 if (!UNDEF_P(resolved_cause)) {
801rb_f_raise(
int argc,
VALUE *argv)
804 argc = extract_raise_options(argc, argv, &cause);
811 if (!UNDEF_P(cause)) {
812 rb_raise(rb_eArgError,
"only cause is given with no arguments");
816 exception = get_errinfo();
817 if (!
NIL_P(exception)) {
823 rb_raise_jump(rb_make_exception(argc, argv), cause);
944 return rb_f_raise(c, v);
948make_exception(
int argc,
const VALUE *argv,
int isstr)
958 if (isstr &&!
NIL_P(exc)) {
969 rb_error_arity(argc, 0, 3);
981 set_backtrace(mesg, argv[2]);
988rb_make_exception(
int argc,
const VALUE *argv)
990 return make_exception(argc, argv, TRUE);
998 rb_execution_context_t *ec = GET_EC();
999 const rb_control_frame_t *cfp = ec->cfp;
1000 const rb_callable_method_entry_t *me = rb_vm_frame_method_entry(cfp);
1001 VALUE klass = me->owner;
1002 VALUE self = cfp->self;
1003 ID mid = me->called_id;
1005 rb_vm_pop_frame(ec);
1008 rb_longjmp(ec, TAG_RAISE, mesg, cause);
1014 if (UNLIKELY(tag < TAG_RETURN || tag > TAG_FATAL)) {
1015 unknown_longjmp_status(tag);
1017 EC_JUMP_TAG(GET_EC(), tag);
1023 if (rb_vm_frame_block_handler(GET_EC()->cfp) == VM_BLOCK_HANDLER_NONE) {
1031int rb_vm_cframe_keyword_p(
const rb_control_frame_t *cfp);
1036 return rb_vm_cframe_keyword_p(GET_EC()->cfp);
1045 rb_vm_localjump_error(
"no block given",
Qnil, 0);
1054 va_start(ap, data2);
1065 enum ruby_tag_type state;
1066 rb_execution_context_t *
volatile ec = GET_EC();
1067 rb_control_frame_t *
volatile cfp = ec->cfp;
1069 volatile VALUE e_info = ec->errinfo;
1072 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
1074 result = (*b_proc) (data1);
1078 if (state == TAG_RETRY) {
1086 rb_vm_rewind_cfp(ec, cfp);
1088 if (state == TAG_RAISE) {
1096 while ((eclass = va_arg(ap,
VALUE)) != 0) {
1107 result = (*r_proc) (data2, ec->errinfo);
1109 ec->errinfo = e_info;
1115 EC_JUMP_TAG(ec, state);
1132 volatile enum ruby_tag_type state;
1133 rb_execution_context_t *
volatile ec = GET_EC();
1134 rb_control_frame_t *
volatile cfp = ec->cfp;
1137 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
1138 result = (*proc)(data);
1141 rb_vm_rewind_cfp(ec, cfp);
1145 if (pstate != NULL) *pstate = state;
1152 enum ruby_tag_type state;
1156 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
1157 result = (*b_proc) (data1);
1160 errinfo = ec->errinfo;
1165 ec->errinfo = errinfo;
1167 EC_JUMP_TAG(ec, state);
1174 return rb_ec_ensure(GET_EC(), b_proc, data1, e_proc, data2);
1178frame_func_id(
const rb_control_frame_t *cfp)
1180 const rb_callable_method_entry_t *me = rb_vm_frame_method_entry(cfp);
1183 return me->def->original_id;
1191frame_called_id(rb_control_frame_t *cfp)
1193 const rb_callable_method_entry_t *me = rb_vm_frame_method_entry(cfp);
1196 return me->called_id;
1206 return frame_func_id(GET_EC()->cfp);
1212 return frame_called_id(GET_EC()->cfp);
1215static rb_control_frame_t *
1216previous_frame(
const rb_execution_context_t *ec)
1218 rb_control_frame_t *prev_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(ec->cfp);
1220 if ((
void *)(ec->vm_stack + ec->vm_stack_size) == (
void *)(prev_cfp)) {
1227prev_frame_callee(
void)
1229 rb_control_frame_t *prev_cfp = previous_frame(GET_EC());
1230 if (!prev_cfp)
return 0;
1231 return frame_called_id(prev_cfp);
1235prev_frame_func(
void)
1237 rb_control_frame_t *prev_cfp = previous_frame(GET_EC());
1238 if (!prev_cfp)
return 0;
1239 return frame_func_id(prev_cfp);
1251 const rb_execution_context_t *ec = GET_EC();
1252 const rb_control_frame_t *cfp = ec->cfp;
1255 while (!(mid = frame_func_id(cfp)) &&
1256 (cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp),
1257 !RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(ec, cfp)));
1274rb_mod_append_features(
VALUE module,
VALUE include)
1276 if (!CLASS_OR_MODULE_P(include)) {
1284static VALUE refinement_import_methods(
int argc,
VALUE *argv,
VALUE refinement);
1294rb_mod_include(
int argc,
VALUE *argv,
VALUE module)
1297 ID id_append_features, id_included;
1299 CONST_ID(id_append_features,
"append_features");
1303 rb_raise(
rb_eTypeError,
"Refinement#include has been removed");
1307 for (i = 0; i < argc; i++) {
1309 if (
FL_TEST(argv[i], RMODULE_IS_REFINEMENT)) {
1314 rb_funcall(argv[argc], id_append_features, 1, module);
1315 rb_funcall(argv[argc], id_included, 1, module);
1333rb_mod_prepend_features(
VALUE module,
VALUE prepend)
1335 if (!CLASS_OR_MODULE_P(prepend)) {
1351rb_mod_prepend(
int argc,
VALUE *argv,
VALUE module)
1354 ID id_prepend_features, id_prepended;
1357 rb_raise(
rb_eTypeError,
"Refinement#prepend has been removed");
1360 CONST_ID(id_prepend_features,
"prepend_features");
1361 CONST_ID(id_prepended,
"prepended");
1364 for (i = 0; i < argc; i++) {
1366 if (
FL_TEST(argv[i], RMODULE_IS_REFINEMENT)) {
1371 rb_funcall(argv[argc], id_prepend_features, 1, module);
1372 rb_funcall(argv[argc], id_prepended, 1, module);
1378ensure_class_or_module(
VALUE obj)
1382 "wrong argument type %"PRIsVALUE
" (expected Class or Module)",
1388hidden_identity_hash_new(
void)
1390 VALUE hash = rb_ident_hash_new();
1392 RBASIC_CLEAR_CLASS(hash);
1397refinement_superclass(
VALUE superclass)
1401 return rb_include_class_new(RCLASS_ORIGIN(superclass),
rb_cBasicObject);
1412rb_using_refinement(rb_cref_t *cref,
VALUE klass,
VALUE module)
1414 VALUE iclass, c, superclass = klass;
1416 ensure_class_or_module(klass);
1418 if (
NIL_P(CREF_REFINEMENTS(cref))) {
1419 CREF_REFINEMENTS_SET(cref, hidden_identity_hash_new());
1422 if (CREF_OMOD_SHARED(cref)) {
1423 CREF_REFINEMENTS_SET(cref, rb_hash_dup(CREF_REFINEMENTS(cref)));
1424 CREF_OMOD_SHARED_UNSET(cref);
1426 if (!
NIL_P(c = rb_hash_lookup(CREF_REFINEMENTS(cref), klass))) {
1429 if (
RBASIC(c)->klass == module) {
1437 superclass = refinement_superclass(superclass);
1438 c = iclass = rb_include_class_new(module, superclass);
1439 RCLASS_SET_REFINED_CLASS(c, klass);
1441 RCLASS_WRITE_M_TBL(c, RCLASS_M_TBL(module));
1443 rb_class_subclass_add(klass, iclass);
1445 rb_hash_aset(CREF_REFINEMENTS(cref), klass, iclass);
1451 rb_cref_t *cref = (rb_cref_t *) arg;
1453 rb_using_refinement(cref, klass, module);
1458using_module_recursive(
const rb_cref_t *cref,
VALUE klass)
1461 VALUE super, module, refinements;
1465 using_module_recursive(cref, super);
1473 module = RBASIC(klass)->klass;
1477 rb_raise(
rb_eTypeError,
"wrong argument type %s (expected Module)",
1481 CONST_ID(id_refinements,
"__refinements__");
1482 refinements = rb_attr_get(module, id_refinements);
1483 if (
NIL_P(refinements))
return;
1491rb_using_module(
const rb_cref_t *cref,
VALUE module)
1494 using_module_recursive(cref, module);
1495 rb_clear_all_refinement_method_cache();
1499rb_vm_using_module(
VALUE module)
1501 rb_using_module(rb_vm_cref_replace_with_duplicated_cref(), module);
1518rb_refinement_module_get_refined_class(
VALUE module)
1520 ID id_refined_class;
1522 CONST_ID(id_refined_class,
"__refined_class__");
1523 return rb_attr_get(module, id_refined_class);
1527add_activated_refinement(
VALUE activated_refinements,
1530 VALUE iclass, c, superclass = klass;
1532 if (!
NIL_P(c = rb_hash_lookup(activated_refinements, klass))) {
1535 if (
RBASIC(c)->klass == refinement) {
1542 superclass = refinement_superclass(superclass);
1543 c = iclass = rb_include_class_new(refinement, superclass);
1544 RCLASS_SET_REFINED_CLASS(c, klass);
1545 rb_class_subclass_add(klass, iclass);
1547 while (refinement && refinement != klass) {
1548 c = rb_class_set_super(c, rb_include_class_new(refinement,
RCLASS_SUPER(c)));
1549 RCLASS_SET_REFINED_CLASS(c, klass);
1550 rb_class_subclass_add(klass, c);
1553 rb_hash_aset(activated_refinements, klass, iclass);
1560 ID id_refinements, id_activated_refinements,
1561 id_refined_class, id_defined_at;
1562 VALUE refinements, activated_refinements;
1564 CONST_ID(id_refinements,
"__refinements__");
1565 refinements = rb_attr_get(module, id_refinements);
1566 if (
NIL_P(refinements)) {
1567 refinements = hidden_identity_hash_new();
1570 CONST_ID(id_activated_refinements,
"__activated_refinements__");
1571 activated_refinements = rb_attr_get(module, id_activated_refinements);
1572 if (
NIL_P(activated_refinements)) {
1573 activated_refinements = hidden_identity_hash_new();
1575 activated_refinements);
1577 refinement = rb_hash_lookup(refinements, klass);
1578 if (
NIL_P(refinement)) {
1579 VALUE superclass = refinement_superclass(klass);
1581 rb_class_set_super(refinement, superclass);
1583 FL_SET(refinement, RMODULE_IS_REFINEMENT);
1584 CONST_ID(id_refined_class,
"__refined_class__");
1586 CONST_ID(id_defined_at,
"__defined_at__");
1588 rb_hash_aset(refinements, klass, refinement);
1589 add_activated_refinement(activated_refinements, klass, refinement);
1592 data->refinement = refinement;
1593 data->refinements = activated_refinements;
1609 rb_thread_t *th = GET_THREAD();
1610 VALUE block_handler = rb_vm_frame_block_handler(th->ec->cfp);
1613 if (block_handler == VM_BLOCK_HANDLER_NONE) {
1614 rb_raise(rb_eArgError,
"no block given");
1616 if (vm_block_handler_type(block_handler) != block_handler_type_iseq) {
1617 rb_raise(rb_eArgError,
"can't pass a Proc as a block to Module#refine");
1620 ensure_class_or_module(klass);
1622 rb_refinement_setup(&data, module, klass);
1624 rb_yield_refine_block(data.refinement, data.refinements);
1625 return data.refinement;
1629ignored_block(
VALUE module,
const char *klass)
1631 const char *anon =
"";
1633 if (!
RTEST(rb_search_class_path(module))) {
1634 anon =
", maybe for Module.new";
1636 rb_warn(
"%s""using doesn't call the given block""%s.", klass, anon);
1650 rb_control_frame_t *prev_cfp = previous_frame(GET_EC());
1652 if (prev_frame_func()) {
1654 "Module#using is not permitted in methods");
1656 if (prev_cfp && prev_cfp->self != self) {
1660 ignored_block(module,
"Module#");
1662 rb_using_module(rb_vm_cref_replace_with_duplicated_cref(), module);
1688mod_refinements(
VALUE self)
1693 CONST_ID(id_refinements,
"__refinements__");
1694 refinements = rb_attr_get(self, id_refinements);
1695 if (
NIL_P(refinements)) {
1698 return rb_hash_values(refinements);
1705 CONST_ID(id_defined_at,
"__defined_at__");
1739rb_mod_s_used_modules(
VALUE _)
1741 const rb_cref_t *cref = rb_vm_cref();
1745 if (!
NIL_P(CREF_REFINEMENTS(cref))) {
1748 cref = CREF_NEXT(cref);
1751 return rb_funcall(ary, rb_intern(
"uniq"), 0);
1790rb_mod_s_used_refinements(
VALUE _)
1792 const rb_cref_t *cref = rb_vm_cref();
1796 if (!
NIL_P(CREF_REFINEMENTS(cref))) {
1799 cref = CREF_NEXT(cref);
1812rb_cref_t *rb_vm_cref_dup_without_refinements(
const rb_cref_t *cref);
1814static enum rb_id_table_iterator_result
1815refinement_import_methods_i(
ID key,
VALUE value,
void *data)
1817 const rb_method_entry_t *me = (
const rb_method_entry_t *)value;
1820 if (me->def->type != VM_METHOD_TYPE_ISEQ) {
1821 rb_raise(rb_eArgError,
"Can't import method which is not defined with Ruby code: %"PRIsVALUE
"#%"PRIsVALUE,
rb_class_path(arg->module), rb_id2str(key));
1823 rb_cref_t *new_cref = rb_vm_cref_dup_without_refinements(me->def->body.iseq.
cref);
1824 CREF_REFINEMENTS_SET(new_cref, CREF_REFINEMENTS(arg->cref));
1825 rb_add_method_iseq(arg->refinement, key, me->def->body.iseq.
iseqptr, new_cref, METHOD_ENTRY_VISI(me));
1826 return ID_TABLE_CONTINUE;
1834refinement_import_methods(
int argc,
VALUE *argv,
VALUE refinement)
1840 for (i = 0; i < argc; i++) {
1843 rb_warn(
"%"PRIsVALUE
" has ancestors, but Refinement#import_methods doesn't import their methods",
rb_class_path(argv[i]));
1846 arg.cref = rb_vm_cref_replace_with_duplicated_cref();
1847 arg.refinement = refinement;
1848 for (i = 0; i < argc; i++) {
1849 arg.module = argv[i];
1850 struct rb_id_table *m_tbl = RCLASS_M_TBL(argv[i]);
1851 if (!m_tbl)
continue;
1852 rb_id_table_foreach(m_tbl, refinement_import_methods_i, &arg);
1864rb_obj_call_init_kw(
VALUE obj,
int argc,
const VALUE *argv,
int kw_splat)
1866 PASS_PASSED_BLOCK_HANDLER();
1936rb_obj_extend(
int argc,
VALUE *argv,
VALUE obj)
1939 ID id_extend_object, id_extended;
1941 CONST_ID(id_extend_object,
"extend_object");
1945 for (i = 0; i < argc; i++) {
1947 if (
FL_TEST(argv[i], RMODULE_IS_REFINEMENT)) {
1948 rb_raise(
rb_eTypeError,
"Cannot extend object with refinement");
1952 rb_funcall(argv[argc], id_extend_object, 1, obj);
1959rb_top_main_class(
const char *method)
1961 VALUE klass = GET_THREAD()->top_wrapper;
1963 if (!klass)
return rb_cObject;
1964 rb_warning(
"main.%s in the wrapped load is effective only in wrapper module", method);
1978top_include(
int argc,
VALUE *argv,
VALUE self)
1980 return rb_mod_include(argc, argv, rb_top_main_class(
"include"));
1994 const rb_cref_t *cref = CREF_NEXT(rb_vm_cref());
1995 rb_control_frame_t *prev_cfp = previous_frame(GET_EC());
1996 rb_thread_t *th = GET_THREAD();
1998 if ((th->top_wrapper ? CREF_NEXT(cref) : cref) ||
1999 (prev_cfp && rb_vm_frame_method_entry(prev_cfp))) {
2003 ignored_block(module,
"main.");
2005 rb_using_module(rb_vm_cref_replace_with_duplicated_cref(), module);
2010errinfo_place(
const rb_execution_context_t *ec)
2012 const rb_control_frame_t *cfp = ec->cfp;
2013 const rb_control_frame_t *end_cfp = RUBY_VM_END_CONTROL_FRAME(ec);
2015 while (RUBY_VM_VALID_CONTROL_FRAME_P(cfp, end_cfp)) {
2016 if (VM_FRAME_RUBYFRAME_P(cfp)) {
2017 if (ISEQ_BODY(cfp->iseq)->type == ISEQ_TYPE_RESCUE) {
2018 return &cfp->ep[VM_ENV_INDEX_LAST_LVAR];
2020 else if (ISEQ_BODY(cfp->iseq)->type == ISEQ_TYPE_ENSURE &&
2021 !THROW_DATA_P(cfp->ep[VM_ENV_INDEX_LAST_LVAR]) &&
2022 !
FIXNUM_P(cfp->ep[VM_ENV_INDEX_LAST_LVAR])) {
2023 return &cfp->ep[VM_ENV_INDEX_LAST_LVAR];
2026 cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
2032rb_ec_get_errinfo(
const rb_execution_context_t *ec)
2034 const VALUE *ptr = errinfo_place(ec);
2046 return get_ec_errinfo(GET_EC());
2052 return get_errinfo();
2058 return GET_EC()->errinfo;
2067 GET_EC()->errinfo = err;
2073 VALUE err = get_errinfo();
2075 return rb_get_backtrace(err);
2085 VALUE err = get_errinfo();
2087 rb_raise(rb_eArgError,
"$! not set");
2089 set_backtrace(err, val);
2105 ID fname = prev_frame_func();
2127 ID fname = prev_frame_callee();
2148f_current_dirname(
VALUE _)
2150 VALUE base = rb_current_realfilepath();
2154 base = rb_file_dirname(base);
2171f_global_variables(
VALUE _)
2225 rb_define_virtual_variable("$!", errinfo_getter, 0);
2227 rb_gvar_ractor_local(
"$@");
2228 rb_gvar_ractor_local("$!");
2230 rb_gvar_box_dynamic(
"$@");
2231 rb_gvar_box_dynamic("$!");
2252 rb_mod_s_used_modules, 0);
2254 rb_mod_s_used_refinements, 0);
2271 "include", top_include, -1);
2273 "using", top_using, 1);
2280 rb_vm_register_special_exception(ruby_error_reenter,
rb_eFatal,
"exception reentered");
2281 rb_vm_register_special_exception(ruby_error_stackfatal,
rb_eFatal,
"machine stack overflow in critical region");
#define RUBY_ASSERT(...)
Asserts that the given expression is truthy if and only if RUBY_DEBUG is truthy.
#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.
#define RUBY_EVENT_C_RETURN
Return from a method, written in C.
void rb_include_module(VALUE klass, VALUE module)
Includes a module to a class.
VALUE rb_refinement_new(void)
Creates a new, anonymous refinement.
void rb_extend_object(VALUE obj, VALUE module)
Extend the object with the module.
void rb_prepend_module(VALUE klass, VALUE module)
Identical to rb_include_module(), except it "prepends" the passed module to the klass,...
VALUE rb_singleton_class(VALUE obj)
Finds or creates the singleton class of the passed object.
void rb_class_modify_check(VALUE klass)
Asserts that klass is not a frozen class.
void rb_need_block(void)
Declares that the current method needs a block.
ID rb_frame_last_func(void)
Returns the ID of the last method in the call stack.
void rb_undef_method(VALUE klass, const char *name)
Defines an undef of a method.
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.
int rb_keyword_given_p(void)
Determines if the current method is given a keyword argument.
int rb_block_given_p(void)
Determines if the current method is given a block.
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
Keyword argument deconstructor.
#define Qundef
Old name of RUBY_Qundef.
#define INT2FIX
Old name of RB_INT2FIX.
#define OBJ_FROZEN
Old name of RB_OBJ_FROZEN.
#define ID2SYM
Old name of RB_ID2SYM.
#define SPECIAL_CONST_P
Old name of RB_SPECIAL_CONST_P.
#define OBJ_FREEZE
Old name of RB_OBJ_FREEZE.
#define UNREACHABLE_RETURN
Old name of RBIMPL_UNREACHABLE_RETURN.
#define FIX2INT
Old name of RB_FIX2INT.
#define T_MODULE
Old name of RUBY_T_MODULE.
#define T_ICLASS
Old name of RUBY_T_ICLASS.
#define FL_SET
Old name of RB_FL_SET.
#define rb_exc_new3
Old name of rb_exc_new_str.
#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.
#define NIL_P
Old name of RB_NIL_P.
#define T_CLASS
Old name of RUBY_T_CLASS.
#define BUILTIN_TYPE
Old name of RB_BUILTIN_TYPE.
#define FL_TEST
Old name of RB_FL_TEST.
#define FIXNUM_P
Old name of RB_FIXNUM_P.
#define CONST_ID
Old name of RUBY_CONST_ID.
void ruby_stop(int ex)
Calls ruby_cleanup() and exits the process.
int ruby_exec_node(void *n)
Identical to ruby_run_node(), except it returns an opaque execution status.
int ruby_setup(void)
Initializes the VM and builtin libraries.
void ruby_finalize(void)
Runs the VM finalization processes.
int ruby_cleanup(int ex)
Destructs the VM.
void * ruby_process_options(int argc, char **argv)
Identical to ruby_options(), except it raises ruby-level exceptions on failure.
void ruby_prog_init(void)
Defines built-in variables.
void ruby_sig_finalize(void)
Clear signal handlers.
#define ruby_debug
This variable controls whether the interpreter is in debug mode.
VALUE rb_eLocalJumpError
LocalJumpError exception.
VALUE rb_rescue2(VALUE(*b_proc)(VALUE), VALUE data1, VALUE(*r_proc)(VALUE, VALUE), VALUE data2,...)
An equivalent of rescue clause.
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
VALUE rb_eSystemExit
SystemExit exception.
VALUE rb_eStandardError
StandardError exception.
void rb_set_errinfo(VALUE err)
Sets the current exception ($!) to the given value.
VALUE rb_eTypeError
TypeError exception.
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.
VALUE rb_eFatal
fatal exception.
VALUE rb_eInterrupt
Interrupt exception.
void rb_exc_fatal(VALUE mesg)
Raises a fatal error in the current thread.
VALUE rb_eRuntimeError
RuntimeError exception.
void rb_warn(const char *fmt,...)
Identical to rb_warning(), except it reports unless $VERBOSE is nil.
VALUE rb_exc_new(VALUE etype, const char *ptr, long len)
Creates an instance of the passed exception class.
void rb_error_frozen_object(VALUE frozen_obj)
Identical to rb_error_frozen(), except it takes arbitrary Ruby object instead of C's string.
VALUE rb_eException
Mother of all exceptions.
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.
VALUE rb_ensure(VALUE(*b_proc)(VALUE), VALUE data1, VALUE(*e_proc)(VALUE), VALUE data2)
An equivalent to ensure clause.
VALUE rb_errinfo(void)
This is the same as $! in Ruby.
VALUE rb_eSysStackError
SystemStackError exception.
VALUE rb_eThreadError
ThreadError exception.
void rb_warning(const char *fmt,...)
Issues a warning.
VALUE rb_cClass
Class class.
VALUE rb_mKernel
Kernel module.
VALUE rb_cRefinement
Refinement class.
static VALUE rb_class_of(VALUE obj)
Object to class mapping function.
VALUE rb_obj_class(VALUE obj)
Queries the class of an object.
VALUE rb_obj_dup(VALUE obj)
Duplicates the given object.
VALUE rb_cBasicObject
BasicObject class.
VALUE rb_cModule
Module class.
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.
void ruby_init(void)
Calls ruby_setup() and check error.
int ruby_executable_node(void *n, int *status)
Checks the return value of ruby_options().
VALUE rb_funcall(VALUE recv, ID mid, int n,...)
Calls a method.
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.
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().
static int rb_check_arity(int argc, int min, int max)
Ensures that the passed integer is in the passed range.
ID rb_frame_callee(void)
Identical to rb_frame_this_func(), except it returns the named used to call the method.
ID rb_frame_this_func(void)
Queries the name of the Ruby level method that is calling this function.
void rb_interrupt(void)
Raises an instance of rb_eInterrupt.
void ruby_default_signal(int sig)
Pretends as if there was no custom signal handler.
#define rb_str_new(str, len)
Allocates an instance of rb_cString.
#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.
VALUE rb_check_string_type(VALUE obj)
Try converting an object to its stringised representation using its to_str method,...
VALUE rb_obj_as_string(VALUE obj)
Try converting an object to its stringised representation using its to_s method, if any.
VALUE rb_f_untrace_var(int argc, const VALUE *argv)
Deletes the passed tracer from the passed global variable, or if omitted, deletes everything.
VALUE rb_const_list(void *)
This is another mysterious API that comes with no documents at all.
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.
VALUE rb_f_trace_var(int argc, const VALUE *argv)
Traces a global variable.
VALUE rb_mod_constants(int argc, const VALUE *argv, VALUE recv)
Resembles Module#constants.
void * rb_mod_const_of(VALUE, void *)
This is a variant of rb_mod_const_at().
void * rb_mod_const_at(VALUE, void *)
This API is mysterious.
VALUE rb_ivar_defined(VALUE obj, ID name)
Queries if the instance variable is defined at the object.
VALUE rb_f_global_variables(void)
Queries the list of global variables.
VALUE rb_class_path(VALUE mod)
Identical to rb_mod_name(), except it returns #<Class: ...> style inspection for anonymous modules.
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.
static ID rb_intern_const(const char *str)
This is a "tiny optimisation" over rb_intern().
int ruby_vm_destruct(ruby_vm_t *vm)
Destructs the passed VM.
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.
#define RCLASS_SUPER
Just another name of rb_class_get_superclass.
#define RHASH_EMPTY_P(h)
Checks if the hash is empty.
const char * rb_obj_classname(VALUE obj)
Queries the name of the class of the passed object.
int * rb_errno_ptr(void)
The location of errno.
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.
int rb_errno(void)
Identical to system errno.
#define RB_NO_KEYWORDS
Do not pass keywords.
VALUE rb_fiber_scheduler_set(VALUE scheduler)
Destructively assigns the passed scheduler to that of the current thread that is calling this functio...
#define RTEST
This is an old name of RB_TEST.
#define _(args)
This was a transition path from K&R to ANSI.
rb_cref_t * cref
class reference, should be marked
const rb_iseq_t * iseqptr
iseq pointer, should be separated from iseqval
uintptr_t ID
Type that represents a Ruby identifier such as a variable name.
uintptr_t VALUE
Type that represents a Ruby object.
static void Check_Type(VALUE v, enum ruby_value_type t)
Identical to RB_TYPE_P(), except it raises exceptions on predication failure.
static bool RB_TYPE_P(VALUE obj, enum ruby_value_type t)
Queries if the given object is of given type.