12#include "eval_intern.h"
14#include "internal/error.h"
15#include "internal/vm.h"
21static VALUE rb_cBacktrace;
22static VALUE rb_cBacktraceLocation;
28 if (!str)
return Qnil;
31#define rb_id2str(id) id2str(id)
33#define BACKTRACE_START 0
34#define ALL_BACKTRACE_LINES -1
37calc_pos(
const rb_iseq_t *iseq,
const VALUE *pc,
int *lineno,
int *node_id)
40 VM_ASSERT(iseq->body);
41 VM_ASSERT(iseq->body->iseq_encoded);
42 VM_ASSERT(iseq->body->iseq_size);
44 if (iseq->body->type == ISEQ_TYPE_TOP) {
45 VM_ASSERT(! iseq->body->local_table);
46 VM_ASSERT(! iseq->body->local_table_size);
49 if (lineno) *lineno =
FIX2INT(iseq->body->location.first_lineno);
50#ifdef USE_ISEQ_NODE_ID
51 if (node_id) *node_id = -1;
56 ptrdiff_t n = pc - iseq->body->iseq_encoded;
57 VM_ASSERT(n <= iseq->body->iseq_size);
65#if VMDEBUG && defined(HAVE_BUILTIN___BUILTIN_TRAP)
72 if (lineno) *lineno = rb_iseq_line_no(iseq, pos);
73#ifdef USE_ISEQ_NODE_ID
74 if (node_id) *node_id = rb_iseq_node_id(iseq, pos);
81calc_lineno(
const rb_iseq_t *iseq,
const VALUE *pc)
84 if (calc_pos(iseq, pc, &lineno, NULL))
return lineno;
88#ifdef USE_ISEQ_NODE_ID
90calc_node_id(
const rb_iseq_t *iseq,
const VALUE *pc)
93 if (calc_pos(iseq, pc, NULL, &node_id))
return node_id;
101 if (VM_FRAME_RUBYFRAME_P(cfp) && cfp->iseq) {
103 int line = calc_lineno(iseq, cfp->pc);
108 return FIX2INT(rb_iseq_first_lineno(iseq));
118 LOCATION_TYPE_ISEQ = 1,
133location_mark(
void *ptr)
143 case LOCATION_TYPE_ISEQ:
146 case LOCATION_TYPE_CFUNC:
157location_memsize(
const void *ptr)
166 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
170rb_frame_info_p(VALUE obj)
172 return rb_typeddata_is_kind_of(obj, &location_data_type);
176location_ptr(VALUE locobj)
187 case LOCATION_TYPE_ISEQ:
188 return calc_lineno(loc->iseq, loc->pc);
189 case LOCATION_TYPE_CFUNC:
190 if (loc->iseq && loc->pc) {
191 return calc_lineno(loc->iseq, loc->pc);
195 rb_bug(
"location_lineno: unreachable");
209location_lineno_m(VALUE
self)
211 return INT2FIX(location_lineno(location_ptr(
self)));
218 case LOCATION_TYPE_ISEQ:
219 return loc->iseq->body->location.label;
220 case LOCATION_TYPE_CFUNC:
223 rb_bug(
"location_label: unreachable");
256location_label_m(VALUE
self)
258 return location_label(location_ptr(
self));
265 case LOCATION_TYPE_ISEQ:
266 return loc->iseq->body->location.base_label;
267 case LOCATION_TYPE_CFUNC:
270 rb_bug(
"location_base_label: unreachable");
281location_base_label_m(VALUE
self)
283 return location_base_label(location_ptr(
self));
290 case LOCATION_TYPE_ISEQ:
292 case LOCATION_TYPE_CFUNC:
295 rb_bug(
"location_iseq: unreachable");
311location_path_m(VALUE
self)
313 const rb_iseq_t *iseq = location_iseq(location_ptr(
self));
314 return iseq ? rb_iseq_path(iseq) :
Qnil;
317#ifdef USE_ISEQ_NODE_ID
322 case LOCATION_TYPE_ISEQ:
323 return calc_node_id(loc->iseq, loc->pc);
324 case LOCATION_TYPE_CFUNC:
325 if (loc->iseq && loc->pc) {
326 return calc_node_id(loc->iseq, loc->pc);
330 rb_bug(
"location_node_id: unreachable");
337rb_get_node_id_from_frame_info(VALUE obj)
339#ifdef USE_ISEQ_NODE_ID
341 return location_node_id(loc);
348rb_get_iseq_from_frame_info(VALUE obj)
351 const rb_iseq_t *iseq = location_iseq(loc);
359 case LOCATION_TYPE_ISEQ:
360 return rb_iseq_realpath(loc->iseq);
361 case LOCATION_TYPE_CFUNC:
363 return rb_iseq_realpath(loc->iseq);
367 rb_bug(
"location_realpath: unreachable");
379location_absolute_path_m(VALUE
self)
381 return location_realpath(location_ptr(
self));
385location_format(VALUE file,
int lineno, VALUE name)
408 case LOCATION_TYPE_ISEQ:
409 file = rb_iseq_path(loc->iseq);
410 name = loc->iseq->body->location.label;
412 lineno = calc_lineno(loc->iseq, loc->pc);
414 case LOCATION_TYPE_CFUNC:
415 if (loc->iseq && loc->pc) {
416 file = rb_iseq_path(loc->iseq);
417 lineno = calc_lineno(loc->iseq, loc->pc);
420 file = GET_VM()->progname;
426 rb_bug(
"location_to_str: unreachable");
429 return location_format(file, lineno, name);
436location_to_str_m(VALUE
self)
438 return location_to_str(location_ptr(
self));
446location_inspect_m(VALUE
self)
459backtrace_mark(
void *ptr)
462 size_t i, s = bt->backtrace_size;
464 for (i=0; i<s; i++) {
465 location_mark_entry(&bt->backtrace[i]);
472backtrace_free(
void *ptr)
483 case LOCATION_TYPE_ISEQ:
486 case LOCATION_TYPE_CFUNC:
497backtrace_update(
void *ptr)
500 size_t i, s = bt->backtrace_size;
502 for (i=0; i<s; i++) {
503 location_update_entry(&bt->backtrace[i]);
510backtrace_memsize(
const void *ptr)
518 {backtrace_mark, backtrace_free, backtrace_memsize, backtrace_update},
519 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
523rb_backtrace_p(VALUE obj)
525 return rb_typeddata_is_kind_of(obj, &backtrace_data_type);
529backtrace_alloc(VALUE klass)
542 if (start_cfp == NULL) {
547 RUBY_VM_NEXT_CONTROL_FRAME(
548 RUBY_VM_NEXT_CONTROL_FRAME(start_cfp));
550 if (start_cfp < last_cfp) {
554 return start_cfp - last_cfp + 1;
560 static const char prefix[] =
"<internal:";
561 const size_t prefix_len =
sizeof(prefix) - 1;
562 VALUE file = rb_iseq_path(cfp->iseq);
563 return strncmp(prefix,
RSTRING_PTR(file), prefix_len) == 0;
569 for (; cfunc_counter > 0; cfunc_counter--, cfunc_loc--) {
570 cfunc_loc->iseq = iseq;
576rb_ec_partial_backtrace_object(
const rb_execution_context_t *ec,
long start_frame,
long num_frames,
int* start_too_large,
bool skip_internal)
582 VALUE btobj = backtrace_alloc(rb_cBacktrace);
584 unsigned long cfunc_counter = 0;
588 if (end_cfp == NULL) {
592 end_cfp = RUBY_VM_NEXT_CONTROL_FRAME(end_cfp);
604 size = end_cfp - cfp + 1;
608 else if (num_frames < 0 || num_frames > size) {
614 bt->backtrace_size = 0;
615 if (num_frames == 0) {
616 if (start_too_large) *start_too_large = 0;
620 for (; cfp != end_cfp && (bt->backtrace_size < num_frames); cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp)) {
623 if (start_frame > 0) {
626 else if (!skip_internal || !is_internal_location(cfp)) {
628 const VALUE *pc = cfp->pc;
629 loc = &bt->backtrace[bt->backtrace_size++];
630 loc->type = LOCATION_TYPE_ISEQ;
633 bt_update_cfunc_loc(cfunc_counter, loc-1, iseq, pc);
638 else if (RUBYVM_CFUNC_FRAME_P(cfp)) {
639 if (start_frame > 0) {
643 loc = &bt->backtrace[bt->backtrace_size++];
644 loc->type = LOCATION_TYPE_CFUNC;
647 loc->mid = rb_vm_frame_method_entry(cfp)->def->original_id;
653 if (cfunc_counter > 0) {
654 for (; cfp != end_cfp; cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp)) {
655 if (cfp->iseq && cfp->pc && (!skip_internal || !is_internal_location(cfp))) {
656 bt_update_cfunc_loc(cfunc_counter, loc, cfp->iseq, cfp->pc);
662 if (start_too_large) *start_too_large = (start_frame > 0 ? -1 : 0);
666MJIT_FUNC_EXPORTED VALUE
669 return rb_ec_partial_backtrace_object(ec, BACKTRACE_START, ALL_BACKTRACE_LINES, NULL, FALSE);
680 for (i=0; i<bt->backtrace_size; i++) {
691 return location_to_str(loc);
695backtrace_to_str_ary(VALUE
self)
700 r = backtrace_collect(bt, location_to_str_dmyarg, 0);
706rb_backtrace_to_str_ary(VALUE
self)
712 bt->strary = backtrace_to_str_ary(
self);
717MJIT_FUNC_EXPORTED
void
718rb_backtrace_use_iseq_first_lineno_for_last_location(VALUE
self)
724 VM_ASSERT(bt->backtrace_size > 0);
726 loc = &bt->backtrace[0];
728 VM_ASSERT(loc->type == LOCATION_TYPE_ISEQ);
741 vloc->btobj = (
VALUE)btobj;
747backtrace_to_location_ary(VALUE
self)
752 r = backtrace_collect(bt, location_create, (
void *)
self);
758rb_backtrace_to_location_ary(VALUE
self)
764 bt->locary = backtrace_to_location_ary(
self);
770backtrace_dump_data(VALUE
self)
772 VALUE str = rb_backtrace_to_str_ary(
self);
777backtrace_load_data(VALUE
self, VALUE str)
836backtrace_limit(VALUE
self)
838 return LONG2NUM(rb_backtrace_length_limit);
844 return backtrace_to_str_ary(rb_ec_partial_backtrace_object(ec, lev, n, NULL, FALSE));
850 return backtrace_to_location_ary(rb_ec_partial_backtrace_object(ec, lev, n, NULL, skip_internal));
857 void (*init)(
void *arg,
size_t size),
868 if (start_cfp == NULL) {
884 RUBY_VM_NEXT_CONTROL_FRAME(
885 RUBY_VM_NEXT_CONTROL_FRAME(start_cfp));
887 if (start_cfp < last_cfp) {
891 size = start_cfp - last_cfp + 1;
897 for (i=0, cfp = start_cfp; i<size; i++, cfp = RUBY_VM_NEXT_CONTROL_FRAME(cfp)) {
904 else if (RUBYVM_CFUNC_FRAME_P(cfp)) {
906 ID mid = me->def->original_id;
908 iter_cfunc(arg, cfp, mid);
916 void (*func)(
void *data, VALUE file,
int lineno, VALUE name);
921oldbt_init(
void *ptr,
size_t dmy)
924 arg->filename = GET_VM()->progname;
932 const VALUE *pc = cfp->pc;
934 VALUE file = arg->filename = rb_iseq_path(iseq);
935 VALUE name = iseq->body->location.label;
936 int lineno = arg->lineno = calc_lineno(iseq, pc);
938 (arg->func)(arg->data, file, lineno, name);
945 VALUE file = arg->filename;
947 int lineno = arg->lineno;
949 (arg->func)(arg->data, file, lineno, name);
953oldbt_print(
void *data, VALUE file,
int lineno, VALUE name)
958 fprintf(fp,
"\tfrom %s:%d:in unknown method\n",
962 fprintf(fp,
"\tfrom %s:%d:in `%s'\n",
968vm_backtrace_print(
FILE *fp)
972 arg.func = oldbt_print;
973 arg.data = (
void *)fp;
974 backtrace_each(GET_EC(),
982oldbt_bugreport(
void *arg, VALUE file,
int line, VALUE method)
986 fprintf(stderr,
"-- Ruby level backtrace information "
987 "----------------------------------------\n");
991 fprintf(stderr,
"%s:%d:in unknown method\n", filename, line);
994 fprintf(stderr,
"%s:%d:in `%s'\n", filename, line,
RSTRING_PTR(method));
999rb_backtrace_print_as_bugreport(
void)
1004 arg.func = oldbt_bugreport;
1005 arg.data = (
int *)&i;
1007 backtrace_each(GET_EC(),
1017 vm_backtrace_print(stderr);
1021 VALUE (*iter)(VALUE recv, VALUE str);
1026oldbt_print_to(
void *data, VALUE file,
int lineno, VALUE name)
1029 VALUE str =
rb_sprintf(
"\tfrom %"PRIsVALUE
":%d:in ", file, lineno);
1037 (*arg->iter)(arg->output, str);
1041rb_backtrace_each(VALUE (*iter)(VALUE recv, VALUE str), VALUE output)
1047 parg.output = output;
1048 arg.func = oldbt_print_to;
1050 backtrace_each(GET_EC(),
1060 return rb_ec_backtrace_str_ary(GET_EC(), BACKTRACE_START, ALL_BACKTRACE_LINES);
1064ec_backtrace_to_ary(
const rb_execution_context_t *ec,
int argc,
const VALUE *argv,
int lev_default,
int lev_plus,
int to_str)
1074 if (argc == 2 &&
NIL_P(vn)) argc--;
1078 lev = lev_default + lev_plus;
1079 n = ALL_BACKTRACE_LINES;
1083 long beg, len, bt_size = backtrace_size(ec);
1088 rb_raise(rb_eArgError,
"negative level (%ld)", lev);
1091 n = ALL_BACKTRACE_LINES;
1096 lev = beg + lev_plus;
1106 rb_raise(rb_eArgError,
"negative level (%ld)", lev);
1109 rb_raise(rb_eArgError,
"negative size (%ld)", n);
1122 btval = rb_ec_partial_backtrace_object(ec, lev, n, &too_large, FALSE);
1129 r = backtrace_to_str_ary(btval);
1132 r = backtrace_to_location_ary(btval);
1139thread_backtrace_to_ary(
int argc,
const VALUE *argv, VALUE thval,
int to_str)
1143 if (target_th->to_kill || target_th->status == THREAD_KILLED)
1146 return ec_backtrace_to_ary(target_th->ec, argc, argv, 0, 0, to_str);
1150rb_vm_thread_backtrace(
int argc,
const VALUE *argv, VALUE thval)
1152 return thread_backtrace_to_ary(argc, argv, thval, 1);
1156rb_vm_thread_backtrace_locations(
int argc,
const VALUE *argv, VALUE thval)
1158 return thread_backtrace_to_ary(argc, argv, thval, 0);
1163 return ec_backtrace_to_ary(ec, argc, argv, 0, 0, 1);
1168 return ec_backtrace_to_ary(ec, argc, argv, 0, 0, 0);
1210rb_f_caller(
int argc, VALUE *argv, VALUE
_)
1212 return ec_backtrace_to_ary(GET_EC(), argc, argv, 1, 1, 1);
1238rb_f_caller_locations(
int argc, VALUE *argv, VALUE
_)
1240 return ec_backtrace_to_ary(GET_EC(), argc, argv, 1, 1, 0);
1245Init_vm_backtrace(
void)
1310 rb_define_method(rb_cBacktraceLocation,
"base_label", location_base_label_m, 0);
1312 rb_define_method(rb_cBacktraceLocation,
"absolute_path", location_absolute_path_m, 0);
1322RUBY_SYMBOL_EXPORT_BEGIN
1324RUBY_SYMBOL_EXPORT_END
1331 long backtrace_size;
1335 CALLER_BINDING_SELF,
1336 CALLER_BINDING_CLASS,
1337 CALLER_BINDING_BINDING,
1338 CALLER_BINDING_ISEQ,
1347collect_caller_bindings_init(
void *arg,
size_t size)
1356 if (rb_vm_control_frame_id_and_class(cfp, 0, 0, &klass)) {
1358 return RBASIC(klass)->klass;
1376 rb_ary_store(frame, CALLER_BINDING_CLASS, get_klass(cfp));
1377 rb_ary_store(frame, CALLER_BINDING_BINDING, GC_GUARDED_PTR(cfp));
1378 rb_ary_store(frame, CALLER_BINDING_ISEQ, cfp->iseq ? (VALUE)cfp->iseq :
Qnil);
1379 rb_ary_store(frame, CALLER_BINDING_CFP, GC_GUARDED_PTR(cfp));
1391 rb_ary_store(frame, CALLER_BINDING_CLASS, get_klass(cfp));
1394 rb_ary_store(frame, CALLER_BINDING_CFP, GC_GUARDED_PTR(cfp));
1409 collect_caller_bindings_init,
1410 collect_caller_bindings_iseq,
1411 collect_caller_bindings_cfunc,
1419 VALUE cfp_val =
rb_ary_entry(entry, CALLER_BINDING_BINDING);
1421 if (!
NIL_P(cfp_val)) {
1423 rb_ary_store(entry, CALLER_BINDING_BINDING, rb_vm_make_binding(ec, cfp));
1440 enum ruby_tag_type state;
1441 volatile VALUE MAYBE_UNUSED(result);
1444 rb_vm_stack_to_heap(ec);
1446 dbg_context.ec = ec;
1447 dbg_context.cfp = dbg_context.ec->cfp;
1448 dbg_context.backtrace = rb_ec_backtrace_location_ary(ec, BACKTRACE_START, ALL_BACKTRACE_LINES, FALSE);
1449 dbg_context.backtrace_size =
RARRAY_LEN(dbg_context.backtrace);
1450 dbg_context.contexts = collect_caller_bindings(ec);
1453 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
1454 result = (*func)(&dbg_context, data);
1461 EC_JUMP_TAG(ec, state);
1470 if (index < 0 || index >= dc->backtrace_size) {
1471 rb_raise(rb_eArgError,
"no such frame");
1479 VALUE frame = frame_get(dc, index);
1486 VALUE frame = frame_get(dc, index);
1493 VALUE frame = frame_get(dc, index);
1500 VALUE frame = frame_get(dc, index);
1509 return dc->backtrace;
1520 for (i=0; i<limit && cfp != end_cfp;) {
1521 if (VM_FRAME_RUBYFRAME_P(cfp)) {
1528 cme = rb_vm_frame_method_entry(cfp);
1529 if (cme && cme->def->type == VM_METHOD_TYPE_ISEQ) {
1530 buff[i] = (
VALUE)cme;
1533 buff[i] = (
VALUE)cfp->iseq;
1536 if (lines) lines[i] = calc_lineno(cfp->iseq, cfp->pc);
1541 cme = rb_vm_frame_method_entry(cfp);
1542 if (cme && cme->def->type == VM_METHOD_TYPE_CFUNC) {
1543 buff[i] = (
VALUE)cme;
1544 if (lines) lines[i] = 0;
1548 cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
1555frame2iseq(VALUE frame)
1557 if (
NIL_P(frame))
return NULL;
1560 switch (imemo_type(frame)) {
1566 switch (cme->def->type) {
1567 case VM_METHOD_TYPE_ISEQ:
1568 return cme->def->body.iseq.
iseqptr;
1577 rb_bug(
"frame2iseq: unreachable");
1583 const rb_iseq_t *iseq = frame2iseq(frame);
1584 return iseq ? rb_iseq_path(iseq) :
Qnil;
1590 if (
NIL_P(frame))
return NULL;
1593 switch (imemo_type(frame)) {
1597 switch (cme->def->type) {
1598 case VM_METHOD_TYPE_CFUNC:
1615 if (cframe(frame)) {
1616 static VALUE cfunc_str =
Qfalse;
1623 const rb_iseq_t *iseq = frame2iseq(frame);
1624 return iseq ? rb_iseq_realpath(iseq) :
Qnil;
1630 const rb_iseq_t *iseq = frame2iseq(frame);
1631 return iseq ? rb_iseq_label(iseq) :
Qnil;
1637 const rb_iseq_t *iseq = frame2iseq(frame);
1638 return iseq ? rb_iseq_base_label(iseq) :
Qnil;
1644 const rb_iseq_t *iseq = frame2iseq(frame);
1645 return iseq ? rb_iseq_first_lineno(iseq) :
Qnil;
1649frame2klass(VALUE frame)
1656 if (imemo_type(frame) == imemo_ment) {
1657 return cme->defined_class;
1666 VALUE klass = frame2klass(frame);
1668 if (klass && !
NIL_P(klass)) {
1670 klass =
RBASIC(klass)->klass;
1687 VALUE klass = frame2klass(frame);
1697 ID mid = cme->def->original_id;
1700 const rb_iseq_t *iseq = frame2iseq(frame);
1701 return iseq ? rb_iseq_method_name(iseq) :
Qnil;
1705qualified_method_name(VALUE frame, VALUE method_name)
1707 if (method_name !=
Qnil) {
1711 if (classpath !=
Qnil) {
1712 return rb_sprintf(
"%"PRIsVALUE
"%s%"PRIsVALUE,
1713 classpath, singleton_p ==
Qtrue ?
"." :
"#", method_name);
1729 return qualified_method_name(frame, method_name);
1737 ID mid = cme->def->original_id;
1738 VALUE method_name = id2str(mid);
1739 return qualified_method_name(frame, method_name);
1746 if (
NIL_P(qualified_method_name) || base_label == qualified_method_name) {
1752 int prefix_len =
rb_long2int(label_length - base_label_length);
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
int rb_profile_frames(int start, int limit, VALUE *buff, int *lines)
Queries mysterious "frame"s of the given range.
VALUE rb_profile_frame_full_label(VALUE frame)
Identical to rb_profile_frame_label(), except it returns a qualified result.
VALUE rb_debug_inspector_frame_iseq_get(const rb_debug_inspector_t *dc, long index)
Queries the instruction sequence of the passed context's upper frame.
VALUE rb_profile_frame_method_name(VALUE frame)
Queries the name of the method of the passed frame.
VALUE rb_profile_frame_qualified_method_name(VALUE frame)
Identical to rb_profile_frame_method_name(), except it "qualifies" the return value with its defining...
VALUE rb_profile_frame_label(VALUE frame)
Queries human-readable "label" string.
VALUE rb_profile_frame_singleton_method_p(VALUE frame)
Queries if the method of the passed frame is a singleton class.
VALUE rb_debug_inspector_backtrace_locations(const rb_debug_inspector_t *dc)
Queries the backtrace object of the context.
VALUE rb_profile_frame_absolute_path(VALUE frame)
Identical to rb_profile_frame_path(), except it tries to expand the returning path.
VALUE rb_debug_inspector_open(rb_debug_inspector_func_t func, void *data)
Prepares, executes, then cleans up a debug session.
VALUE rb_debug_inspector_frame_self_get(const rb_debug_inspector_t *dc, long index)
Queries the current receiver of the passed context's upper frame.
VALUE rb_debug_inspector_frame_binding_get(const rb_debug_inspector_t *dc, long index)
Queries the binding of the passed context's upper frame.
VALUE rb_debug_inspector_frame_class_get(const rb_debug_inspector_t *dc, long index)
Queries the current class of the passed context's upper frame.
VALUE rb_profile_frame_classpath(VALUE frame)
Queries the class path of the method that the passed frame represents.
VALUE rb_profile_frame_path(VALUE frame)
Queries the path of the passed backtrace.
VALUE rb_profile_frame_first_lineno(VALUE frame)
Queries the first line of the method of the passed frame pointer.
VALUE(* rb_debug_inspector_func_t)(const rb_debug_inspector_t *dc, void *data)
Type of the callback function passed to rb_debug_inspector_open().
VALUE rb_profile_frame_base_label(VALUE frame)
Identical to rb_profile_frame_label(), except it does not "qualify" the result.
VALUE rb_enc_sprintf(rb_encoding *enc, const char *fmt,...)
Identical to rb_sprintf(), except it additionally takes an encoding.
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
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.
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a method.
void rb_define_global_function(const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a global function.
#define FL_SINGLETON
Old name of RUBY_FL_SINGLETON.
#define INT2FIX
Old name of RB_INT2FIX.
#define UNREACHABLE
Old name of RBIMPL_UNREACHABLE.
#define T_IMEMO
Old name of RUBY_T_IMEMO.
#define CLASS_OF
Old name of rb_class_of.
#define FIX2INT
Old name of RB_FIX2INT.
#define T_MODULE
Old name of RUBY_T_MODULE.
#define ZALLOC_N
Old name of RB_ZALLOC_N.
#define ASSUME
Old name of RBIMPL_ASSUME.
#define T_ICLASS
Old name of RUBY_T_ICLASS.
#define LONG2NUM
Old name of RB_LONG2NUM.
#define Qtrue
Old name of RUBY_Qtrue.
#define Qnil
Old name of RUBY_Qnil.
#define Qfalse
Old name of RUBY_Qfalse.
#define NIL_P
Old name of RB_NIL_P.
#define T_CLASS
Old name of RUBY_T_CLASS.
#define FL_TEST
Old name of RB_FL_TEST.
#define NUM2LONG
Old name of RB_NUM2LONG.
#define rb_ary_new2
Old name of rb_ary_new_capa.
void rb_raise(VALUE exc, const char *fmt,...)
Exception entry point.
void rb_bug(const char *fmt,...)
Interpreter panic switch.
VALUE rb_cArray
Array class.
VALUE rb_cThread
Thread class.
rb_encoding * rb_enc_compatible(VALUE str1, VALUE str2)
Look for the "common" encoding between the two.
void rb_gc_register_mark_object(VALUE object)
Inform the garbage collector that object is a live Ruby object that should not be moved.
VALUE rb_ary_reverse(VALUE ary)
Destructively reverses the passed array in-place.
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.
VALUE rb_ary_entry(VALUE ary, long off)
Queries an element of an array.
void rb_ary_store(VALUE ary, long key, VALUE val)
Destructively stores the passed value to the passed array's passed index.
void rb_gc_mark(VALUE obj)
Marks an object.
void rb_gc_mark_movable(VALUE obj)
Maybe this is the only function provided for C extensions to control the pinning of objects,...
VALUE rb_gc_location(VALUE obj)
Finds a new "location" of an object.
VALUE rb_range_beg_len(VALUE range, long *begp, long *lenp, long len, int err)
Deconstructs a numerical range.
#define rb_str_new_literal(str)
Just another name of rb_str_new_lit.
VALUE rb_str_cat2(VALUE, const char *)
Just another name of rb_str_cat_cstr.
VALUE rb_str_inspect(VALUE str)
Generates a "readable" version of the receiver.
VALUE rb_str_cat_cstr(VALUE dst, const char *src)
Identical to rb_str_cat(), except it assumes the passed pointer is a pointer to a C string.
VALUE rb_ivar_get(VALUE obj, ID name)
Identical to rb_iv_get(), except it accepts the name as an ID instead of a C string.
VALUE rb_class_path(VALUE mod)
Identical to rb_mod_name(), except it returns #<Class: ...> style inspection for anonymous modules.
void rb_undef_alloc_func(VALUE klass)
Deletes the allocator function of a class.
void rb_define_alloc_func(VALUE klass, rb_alloc_func_t func)
Sets the allocator function of a class.
VALUE rb_make_backtrace(void)
Creates the good old fashioned array-of-strings style backtrace info.
void rb_backtrace(void)
Prints the backtrace out to the standard error.
VALUE rb_id2str(ID id)
Identical to rb_id2name(), except it returns a Ruby's String instead of C's.
VALUE rb_sprintf(const char *fmt,...)
Ruby's extended sprintf(3).
VALUE rb_str_catf(VALUE dst, const char *fmt,...)
Identical to rb_sprintf(), except it renders the output to the specified object rather than creating ...
#define rb_long2int
Just another name of rb_long2int_inline.
void rb_marshal_define_compat(VALUE newclass, VALUE oldclass, VALUE(*dumper)(VALUE), VALUE(*loader)(VALUE, VALUE))
Marshal format compatibility layer.
#define RB_GC_GUARD(v)
Prevents premature destruction of local objects.
#define RARRAY_LEN
Just another name of rb_array_len.
#define RBASIC(obj)
Convenient casting macro.
static long RSTRING_LEN(VALUE str)
Queries the length of the string.
static char * RSTRING_PTR(VALUE str)
Queries the contents pointer of the string.
#define RUBY_TYPED_DEFAULT_FREE
This is a value you can set to rb_data_type_struct::dfree.
#define TypedData_Make_Struct(klass, type, data_type, sval)
Identical to TypedData_Wrap_Struct, except it allocates a new data region internally instead of takin...
const char * rb_class2name(VALUE klass)
Queries the name of the passed class.
#define RTEST
This is an old name of RB_TEST.
#define _(args)
This was a transition path from K&R to ANSI.
This is the struct that holds necessary info for a struct.
const rb_iseq_t * iseqptr
iseq pointer, should be separated from iseqval
uintptr_t VALUE
Type that represents a Ruby object.
static bool RB_TYPE_P(VALUE obj, enum ruby_value_type t)
Queries if the given object is of given type.
void ruby_xfree(void *ptr)
Deallocates a storage instance.