14#include "internal/thread.h"
26static int vm_collect_local_variables_in_heap(
const VALUE *dfp,
const struct local_var_list *vars);
28static VALUE rb_eUncaughtThrow;
29static ID id_result, id_tag, id_value;
32static VALUE send_internal(
int argc,
const VALUE *argv,
VALUE recv, call_type scope);
36vm_argv_ruby_array(
VALUE *av,
const VALUE *argv,
int *flags,
int *argc,
int kw_splat)
38 *flags |= VM_CALL_ARGS_SPLAT;
49 *flags |= VM_CALL_KW_SPLAT;
50 av[1] = rb_hash_new();
61 return vm_call0_cc(ec, recv,
id, argc, argv, &cc, kw_splat);
68 rb_callable_method_entry_with_refinements(
CLASS_OF(recv),
id, NULL);
70 return rb_vm_call0(ec, recv,
id, argc, argv, me, kw_splat);
81 int flags = kw_splat ? VM_CALL_KW_SPLAT : 0;
85 if (UNLIKELY(vm_cc_cme(cc)->def->type == VM_METHOD_TYPE_ISEQ && argc > VM_ARGC_STACK_MAX)) {
86 use_argv = vm_argv_ruby_array(av, argv, &flags, &argc, kw_splat);
91 .ci = &VM_CI_ON_STACK(
id, flags, argc, NULL),
95 .block_handler = vm_passed_block_handler(ec),
101 return vm_call0_body(ec, &calling, use_argv);
107 calling->cc = &VM_CC_ON_STACK(
Qundef, vm_call_general, {{ 0 }}, cme);
108 return vm_call0_body(ec, calling, argv);
114 ID mid = vm_ci_mid(calling->cd->ci);
121 RUBY_VM_CHECK_INTS(ec);
122 return vm_call0_cme(ec, calling, argv, cme);
126 vm_passed_block_handler_set(ec, calling->block_handler);
127 return method_missing(ec, calling->recv, mid, calling->argc, argv, ex, calling->kw_splat);
137 int len = cfunc->argc;
138 VALUE recv = calling->recv;
139 int argc = calling->argc;
140 ID mid = vm_ci_mid(ci);
141 VALUE block_handler = calling->block_handler;
142 int frame_flags = VM_FRAME_MAGIC_CFUNC | VM_FRAME_FLAG_CFRAME | VM_ENV_FLAG_LOCAL;
144 if (calling->kw_splat) {
149 frame_flags |= VM_FRAME_FLAG_CFRAME_KW;
153 RUBY_DTRACE_CMETHOD_ENTRY_HOOK(ec, me->owner, me->def->original_id);
158 vm_push_frame(ec, 0, frame_flags, recv,
159 block_handler, (
VALUE)me,
160 0, reg_cfp->sp, 0, 0);
164 val = (*cfunc->invoker)(recv, argc, argv, cfunc->func);
166 CHECK_CFP_CONSISTENCY(
"vm_call0_cfunc_with_frame");
170 RUBY_DTRACE_CMETHOD_RETURN_HOOK(ec, me->owner, me->def->original_id);
178 return vm_call0_cfunc_with_frame(ec, calling, argv);
184 if (calling->kw_splat &&
204 switch (vm_cc_cme(cc)->def->type) {
205 case VM_METHOD_TYPE_ISEQ:
210 CHECK_VM_STACK_OVERFLOW(reg_cfp, calling->argc + 1);
211 vm_check_canary(ec, reg_cfp->sp);
213 *reg_cfp->sp++ = calling->recv;
214 for (i = 0; i < calling->argc; i++) {
215 *reg_cfp->sp++ = argv[i];
218 if (ISEQ_BODY(def_iseq_ptr(vm_cc_cme(cc)->def))->param.flags.forwardable) {
219 vm_call_iseq_fwd_setup(ec, reg_cfp, calling);
222 vm_call_iseq_setup(ec, reg_cfp, calling);
224 VM_ENV_FLAGS_SET(ec->cfp->ep, VM_FRAME_FLAG_FINISH);
227 case VM_METHOD_TYPE_NOTIMPLEMENTED:
228 case VM_METHOD_TYPE_CFUNC:
229 ret = vm_call0_cfunc(ec, calling, argv);
231 case VM_METHOD_TYPE_ATTRSET:
232 vm_call_check_arity(calling, 1, argv);
233 VM_CALL_METHOD_ATTR(ret,
234 rb_ivar_set(calling->recv, vm_cc_cme(cc)->def->body.attr.id, argv[0]),
237 case VM_METHOD_TYPE_IVAR:
238 vm_call_check_arity(calling, 0, argv);
239 VM_CALL_METHOD_ATTR(ret,
240 rb_attr_get(calling->recv, vm_cc_cme(cc)->def->body.attr.id),
243 case VM_METHOD_TYPE_BMETHOD:
244 ret = vm_call_bmethod_body(ec, calling, argv);
246 case VM_METHOD_TYPE_ZSUPER:
248 VALUE klass = RCLASS_ORIGIN(vm_cc_cme(cc)->defined_class);
249 return vm_call0_super(ec, calling, argv, klass, MISSING_SUPER);
251 case VM_METHOD_TYPE_REFINED:
255 if (cme->def->body.refined.orig_me) {
257 return vm_call0_cme(ec, calling, argv, orig_cme);
260 VALUE klass = cme->defined_class;
261 return vm_call0_super(ec, calling, argv, klass, 0);
263 case VM_METHOD_TYPE_ALIAS:
268 if (cme == orig_cme) rb_bug(
"same!!");
270 if (vm_cc_markable(cc)) {
271 return vm_call0_cme(ec, calling, argv, orig_cme);
278 case VM_METHOD_TYPE_MISSING:
280 vm_passed_block_handler_set(ec, calling->block_handler);
281 return method_missing(ec, calling->recv, vm_ci_mid(ci), calling->argc,
282 argv, MISSING_NOENTRY, calling->kw_splat);
284 case VM_METHOD_TYPE_OPTIMIZED:
285 switch (vm_cc_cme(cc)->def->body.optimized.type) {
286 case OPTIMIZED_METHOD_TYPE_SEND:
287 ret = send_internal(calling->argc, argv, calling->recv, calling->kw_splat ? CALL_FCALL_KW : CALL_FCALL);
289 case OPTIMIZED_METHOD_TYPE_CALL:
292 GetProcPtr(calling->recv, proc);
293 ret = rb_vm_invoke_proc(ec, proc, calling->argc, argv, calling->kw_splat, calling->block_handler,
294 rb_proc_refinements_cref_for_call(calling->recv));
297 case OPTIMIZED_METHOD_TYPE_STRUCT_AREF:
298 vm_call_check_arity(calling, 0, argv);
299 VM_CALL_METHOD_ATTR(ret,
300 vm_call_opt_struct_aref0(ec, calling),
303 case OPTIMIZED_METHOD_TYPE_STRUCT_ASET:
304 vm_call_check_arity(calling, 1, argv);
305 VM_CALL_METHOD_ATTR(ret,
306 vm_call_opt_struct_aset0(ec, calling, argv[0]),
310 rb_bug(
"vm_call0: unsupported optimized method type (%d)", vm_cc_cme(cc)->def->body.optimized.type);
313 case VM_METHOD_TYPE_UNDEF:
316 rb_bug(
"vm_call0: unsupported method type (%d)", vm_cc_cme(cc)->def->type);
320 RUBY_VM_CHECK_INTS(ec);
327 return rb_vm_call0(ec, recv,
id, argc, argv, me, kw_splat);
333 VALUE recv = ec->cfp->self;
339 if (VM_FRAME_RUBYFRAME_P(cfp)) {
340 rb_bug(
"vm_call_super: should not be reached");
343 klass = RCLASS_ORIGIN(me->defined_class);
345 id = me->def->original_id;
346 me = rb_callable_method_entry(klass,
id);
349 return method_missing(ec, recv,
id, argc, argv, MISSING_SUPER, kw_splat);
351 return rb_vm_call_kw(ec, recv,
id, argc, argv, me, kw_splat);
358 PASS_PASSED_BLOCK_HANDLER_EC(ec);
359 return vm_call_super(ec, argc, argv, kw_splat);
373 if (!ec || !(cfp = ec->cfp)) {
382 if (!rb_ec_raised_p(ec, RAISED_STACKOVERFLOW) &&
383 rb_ec_stack_check(ec)) {
384 rb_ec_raised_set(ec, RAISED_STACKOVERFLOW);
385 rb_ec_stack_overflow(ec, 0);
390rb_check_stack_overflow(
void)
392#ifndef RB_THREAD_LOCAL_SPECIFIER
393 if (!ruby_current_ec_key)
return;
396 if (ec) stack_check(ec);
399NORETURN(
static void uncallable_object(
VALUE recv,
ID mid));
406 return ((klass ^ box_value) >> 3) ^ (
VALUE)mid;
419 vm_search_method_slowpath0(vm->self, &cd, klass);
421 if (UNLIKELY(!vm->global_cc_cache_table_used)) {
422 vm->global_cc_cache_table_used =
true;
424 return vm->global_cc_cache_table[index] = cd.cc;
428scope_to_ci(call_type scope,
ID mid,
int argc,
struct rb_callinfo *ci)
436 flags |= VM_CALL_FCALL;
439 flags |= VM_CALL_VCALL;
442 flags |= VM_CALL_KWARG;
445 flags |= (VM_CALL_KWARG | VM_CALL_FCALL);
448 *ci = VM_CI_ON_STACK(mid, flags, argc, NULL);
454 VALUE klass, box_value;
455 const rb_box_t *box = rb_current_box();
459 if (UNLIKELY(!klass)) uncallable_object(recv, mid);
465 if (BOX_USER_P(box)) {
466 box_value = box->box_object;
472 unsigned int index = (
unsigned int)(gccct_hash(klass, box_value, mid) % VM_GLOBAL_CC_CACHE_TABLE_SIZE);
473 rb_vm_t *vm = rb_ec_vm_ptr(ec);
474 const struct rb_callcache *cc = vm->global_cc_cache_table[index];
477 if (LIKELY(vm_cc_class_check(cc, klass))) {
479 if (LIKELY(!METHOD_ENTRY_INVALIDATED(cme) &&
480 cme->called_id == mid)) {
482 VM_ASSERT(vm_cc_check_cme(cc, rb_callable_method_entry(klass, mid)));
483 RB_DEBUG_COUNTER_INC(gccct_hit);
490 RB_DEBUG_COUNTER_INC(gccct_null);
493 RB_DEBUG_COUNTER_INC(gccct_miss);
494 return gccct_method_search_slowpath(vm, klass, index, ci);
498rb_gccct_clear_table(
void)
501 if (vm->global_cc_cache_table_used) {
502 const struct rb_callcache **
const table = vm->global_cc_cache_table;
504 vm->global_cc_cache_table_used =
false;
528 call_type call_scope,
VALUE self)
530 enum method_missing_reason call_status;
531 call_type scope = call_scope;
548 scope_to_ci(scope, mid, argc, &ci);
550 const struct rb_callcache *cc = gccct_method_search(ec, recv, mid, &ci);
552 if (scope == CALL_PUBLIC) {
553 RB_DEBUG_COUNTER_INC(call0_public);
557 call_status = rb_method_call_status(ec, cme, scope, self);
559 if (UNLIKELY(call_status != MISSING_NONE)) {
560 return method_missing(ec, recv, mid, argc, argv, call_status, kw_splat);
562 else if (UNLIKELY(cc_cme != cme)) {
564 return rb_vm_call_kw(ec, recv, mid, argc, argv, cme, kw_splat);
568 RB_DEBUG_COUNTER_INC(call0_other);
569 call_status = rb_method_call_status(ec, cc ? vm_cc_cme(cc) : NULL, scope, self);
571 if (UNLIKELY(call_status != MISSING_NONE)) {
572 return method_missing(ec, recv, mid, argc, argv, call_status, kw_splat);
577 return vm_call0_cc(ec, recv, mid, argc, argv, cc, kw_splat);
586 unsigned int respond: 1;
587 unsigned int respond_to_missing: 1;
594check_funcall_exec(
VALUE v)
597 return call_method_entry(args->ec, args->defined_class,
598 args->recv, idMethodMissing,
599 args->cme, args->argc, args->argv, args->kw_splat);
606 int ret = args->respond;
608 switch (method_boundp(args->defined_class, args->mid,
609 BOUND_PRIVATE|BOUND_RESPONDS)) {
614 ret = args->respond_to_missing;
630 return vm_respond_to(ec, klass, recv, mid, TRUE);
636 return rb_method_call_status(ec, me, CALL_FCALL, ec->cfp->self) == MISSING_NONE;
646 ret = basic_obj_respond_to_missing(ec, klass, recv,
648 if (!
RTEST(ret))
return def;
649 args.respond = respond > 0;
650 args.respond_to_missing = !UNDEF_P(ret);
652 cme = callable_method_entry(klass, idMethodMissing, &args.defined_class);
654 if (cme && !METHOD_ENTRY_BASIC(cme)) {
657 new_args[0] =
ID2SYM(mid);
661 VM_ASSERT(argc == 0);
666 ec->method_missing_reason = MISSING_NOENTRY;
671 args.argc = argc + 1;
672 args.argv = new_args;
673 args.kw_splat = kw_splat;
675 check_funcall_failed, (
VALUE)&args,
682static VALUE rb_check_funcall_default_kw(
VALUE recv,
ID mid,
int argc,
const VALUE *argv,
VALUE def,
int kw_splat);
687 return rb_check_funcall_default_kw(recv, mid, argc, argv,
Qundef, kw_splat);
697rb_check_funcall_default_kw(
VALUE recv,
ID mid,
int argc,
const VALUE *argv,
VALUE def,
int kw_splat)
699 VM_ASSERT(ruby_thread_has_gvl_p());
704 int respond = check_funcall_respond_to(ec, klass, recv, mid);
709 me = rb_search_method_entry(recv, mid);
710 if (!check_funcall_callable(ec, me)) {
711 VALUE ret = check_funcall_missing(ec, klass, recv, mid, argc, argv,
712 respond, def, kw_splat);
713 if (UNDEF_P(ret)) ret = def;
717 return rb_vm_call_kw(ec, recv, mid, argc, argv, me, kw_splat);
721rb_check_funcall_default(
VALUE recv,
ID mid,
int argc,
const VALUE *argv,
VALUE def)
723 return rb_check_funcall_default_kw(recv, mid, argc, argv, def,
RB_NO_KEYWORDS);
727rb_check_funcall_with_hook_kw(
VALUE recv,
ID mid,
int argc,
const VALUE *argv,
728 rb_check_funcall_hook *hook,
VALUE arg,
int kw_splat)
733 int respond = check_funcall_respond_to(ec, klass, recv, mid);
736 (*hook)(FALSE, recv, mid, argc, argv, arg);
740 me = rb_search_method_entry(recv, mid);
741 if (!check_funcall_callable(ec, me)) {
742 VALUE ret = check_funcall_missing(ec, klass, recv, mid, argc, argv,
743 respond,
Qundef, kw_splat);
744 (*hook)(!UNDEF_P(ret), recv, mid, argc, argv, arg);
748 (*hook)(TRUE, recv, mid, argc, argv, arg);
749 return rb_vm_call_kw(ec, recv, mid, argc, argv, me, kw_splat);
755#define type_case(t) t: return #t
773 case type_case(
T_NIL);
791uncallable_object(
VALUE recv,
ID mid)
796 VALUE mname = rb_id2str(mid);
800 "method '%"PRIsVALUE
"' called on unexpected immediate object (%p)",
801 mname, (
void *)recv);
803 else if ((flags =
RBASIC(recv)->flags) == 0) {
805 "method '%"PRIsVALUE
"' called on terminated object (%p)",
806 mname, (
void *)recv);
810 "method '%"PRIsVALUE
"' called on broken T_?""?""?(0x%02x) object"
811 " (%p flags=0x%"PRIxVALUE
")",
812 mname,
type, (
void *)recv, flags);
816 "method '%"PRIsVALUE
"' called on hidden %s object"
817 " (%p flags=0x%"PRIxVALUE
")",
818 mname, typestr, (
void *)recv, flags);
822 "method '%"PRIsVALUE
"' called on unexpected %s object"
823 " (%p flags=0x%"PRIxVALUE
")",
824 mname, typestr, (
void *)recv, flags);
829rb_search_method_entry(
VALUE recv,
ID mid)
833 if (!klass) uncallable_object(recv, mid);
834 return rb_callable_method_entry(klass, mid);
837static inline enum method_missing_reason
840 if (UNLIKELY(UNDEFINED_METHOD_ENTRY_P(me))) {
843 else if (UNLIKELY(me->def->type == VM_METHOD_TYPE_REFINED)) {
844 me = rb_resolve_refined_method_callable(
Qnil, me);
845 if (UNDEFINED_METHOD_ENTRY_P(me))
goto undefined;
848 rb_method_visibility_t visi = METHOD_ENTRY_VISI(me);
851 if (UNLIKELY(visi != METHOD_VISI_PUBLIC)) {
852 if (me->def->original_id == idMethodMissing) {
855 else if (visi == METHOD_VISI_PRIVATE &&
856 scope == CALL_PUBLIC) {
857 return MISSING_PRIVATE;
860 else if (visi == METHOD_VISI_PROTECTED &&
861 scope == CALL_PUBLIC) {
863 VALUE defined_class = me->owner;
865 defined_class =
RBASIC(defined_class)->klass;
869 return MISSING_PROTECTED;
877 return scope == CALL_VCALL ? MISSING_VCALL : MISSING_NOENTRY;
893rb_call(
VALUE recv,
ID mid,
int argc,
const VALUE *argv, call_type scope)
896 return rb_call0(ec, recv, mid, argc, argv, scope, ec->cfp->self);
900 VALUE obj,
enum method_missing_reason call_status));
942rb_method_missing(
int argc,
const VALUE *argv,
VALUE obj)
945 raise_method_missing(ec, argc, argv, obj, ec->method_missing_reason);
951 int argc,
const VALUE *argv,
int priv)
953 VALUE name = argv[0];
956 format = rb_fstring_lit(
"undefined method '%1$s' for %3$s%4$s");
960 return rb_nomethod_err_new(format, obj, name, args, priv);
963 return rb_name_err_new(format, obj, name);
969 enum method_missing_reason last_call_status)
974 if (UNLIKELY(argc == 0)) {
975 rb_raise(rb_eArgError,
"no method name given");
977 else if (UNLIKELY(!
SYMBOL_P(argv[0]))) {
978 const VALUE e = rb_eArgError;
979 rb_raise(e,
"method name must be a Symbol but %"PRIsVALUE
" is given",
985 if (last_call_status & MISSING_PRIVATE) {
986 format = rb_fstring_lit(
"private method '%1$s' called for %3$s%4$s");
988 else if (last_call_status & MISSING_PROTECTED) {
989 format = rb_fstring_lit(
"protected method '%1$s' called for %3$s%4$s");
991 else if (last_call_status & MISSING_VCALL) {
992 format = rb_fstring_lit(
"undefined local variable or method '%1$s' for %3$s%4$s");
995 else if (last_call_status & MISSING_SUPER) {
996 format = rb_fstring_lit(
"super: no superclass method '%1$s' for %3$s%4$s");
1000 exc = rb_make_no_method_exception(exc, format, obj, argc, argv,
1001 last_call_status & (MISSING_FCALL|MISSING_VCALL));
1002 if (!(last_call_status & MISSING_MISSING)) {
1003 rb_vm_pop_cfunc_frame();
1011 VALUE obj,
int call_status)
1013 vm_passed_block_handler_set(ec, VM_BLOCK_HANDLER_NONE);
1014 raise_method_missing(ec, argc, argv, obj, call_status | MISSING_MISSING);
1020 VALUE *nargv, result, work, klass;
1021 VALUE block_handler = vm_passed_block_handler(ec);
1024 ec->method_missing_reason = call_status;
1026 if (
id == idMethodMissing) {
1035 VM_ASSERT(argc == 0);
1044 if (!klass)
goto missing;
1045 me = rb_callable_method_entry(klass, idMethodMissing);
1046 if (!me || METHOD_ENTRY_BASIC(me))
goto missing;
1047 vm_passed_block_handler_set(ec, block_handler);
1048 result = rb_vm_call_kw(ec, obj, idMethodMissing, argc, argv, me, kw_splat);
1052 raise_method_missing(ec, argc, argv, obj, call_status | MISSING_MISSING);
1057rb_funcallv_scope(
VALUE recv,
ID mid,
int argc,
const VALUE *argv, call_type scope)
1062 scope_to_ci(scope, mid, argc, &ci);
1064 const struct rb_callcache *cc = gccct_method_search(ec, recv, mid, &ci);
1065 VALUE self = ec->cfp->self;
1068 LIKELY(rb_method_call_status(ec, vm_cc_cme(cc), scope, self) == MISSING_NONE)) {
1070 return vm_call0_cc(ec, recv, mid, argc, argv, cc,
false);
1073 return rb_call0(ec, recv, mid, argc, argv, scope, self);
1083 VM_ASSERT(ruby_thread_has_gvl_p());
1086 return rb_funcallv_scope(recv, mid, argc, argv, CALL_FCALL);
1092 VM_ASSERT(ruby_thread_has_gvl_p());
1094 return rb_call(recv, mid, argc, argv, kw_splat ? CALL_FCALL_KW : CALL_FCALL);
1104 if (argc >= 0x100) {
1106 RBASIC_CLEAR_CLASS(args);
1135 for (i = 0; i < n; i++) {
1136 argv[i] = va_arg(ar,
VALUE);
1157rb_check_funcall_basic_kw(
VALUE recv,
ID mid,
VALUE ancestor,
int argc,
const VALUE *argv,
int kw_splat)
1162 if (!klass)
return Qundef;
1164 cme = rb_callable_method_entry(klass, mid);
1165 if (cme && METHOD_ENTRY_BASIC(cme) &&
RBASIC_CLASS(cme->defined_class) == ancestor) {
1167 return rb_vm_call0(ec, recv, mid, argc, argv, cme, kw_splat);
1176 return rb_funcallv_scope(recv, mid, argc, argv, CALL_PUBLIC);
1182 return rb_call(recv, mid, argc, argv, kw_splat ? CALL_PUBLIC_KW : CALL_PUBLIC);
1188 PASS_PASSED_BLOCK_HANDLER();
1195 PASS_PASSED_BLOCK_HANDLER();
1196 return rb_call(recv, mid, argc, argv, kw_splat ? CALL_PUBLIC_KW : CALL_PUBLIC);
1202 if (!
NIL_P(passed_procval)) {
1203 vm_passed_block_handler_set(GET_EC(), passed_procval);
1212 if (!
NIL_P(passed_procval)) {
1213 vm_passed_block_handler_set(GET_EC(), passed_procval);
1216 return rb_call(recv, mid, argc, argv, kw_splat ? CALL_PUBLIC_KW : CALL_PUBLIC);
1223 if (RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(ec, prev_cfp))
return NULL;
1224 if (prev_cfp->sp + 1 != argv)
return NULL;
1225 return prev_cfp->sp + 1;
1229send_internal(
int argc,
const VALUE *argv,
VALUE recv, call_type scope)
1234 VALUE ret, vargv = 0;
1236 int public = scope == CALL_PUBLIC || scope == CALL_PUBLIC_KW;
1242 self = RUBY_VM_PREVIOUS_CONTROL_FRAME(ec->cfp)->self;
1246 rb_raise(rb_eArgError,
"no method name given");
1260 VALUE *tmp_argv = current_vm_stack_arg(ec, argv);
1265 else if (argc > 1) {
1275 id = idMethodMissing;
1276 ec->method_missing_reason = MISSING_NOENTRY;
1281 PASS_PASSED_BLOCK_HANDLER_EC(ec);
1282 ret = rb_call0(ec, recv,
id, argc, argv, scope, self);
1288send_internal_kw(
int argc,
const VALUE *argv,
VALUE recv, call_type scope)
1293 scope = CALL_PUBLIC_KW;
1296 scope = CALL_FCALL_KW;
1302 return send_internal(argc, argv, recv, scope);
1334 return send_internal_kw(argc, argv, recv, CALL_FCALL);
1352rb_f_public_send(
int argc,
VALUE *argv,
VALUE recv)
1354 return send_internal_kw(argc, argv, recv, CALL_PUBLIC);
1360rb_yield_0_kw(
int argc,
const VALUE * argv,
int kw_splat)
1362 return vm_yield(GET_EC(), argc, argv, kw_splat);
1366rb_yield_0(
int argc,
const VALUE * argv)
1372rb_yield_1(
VALUE val)
1374 return rb_yield_0(1, &val);
1381 return rb_yield_0(0, NULL);
1384 return rb_yield_0(1, &val);
1399#undef rb_yield_values
1404 return rb_yield_0(0, 0);
1413 for (i=0; i<n; i++) {
1414 argv[i] = va_arg(args,
VALUE);
1418 return rb_yield_0(n, argv);
1425 return rb_yield_0(argc, argv);
1431 return rb_yield_0_kw(argc, argv, kw_splat);
1440 rb_raise(rb_eArgError,
"not an array");
1453 rb_raise(rb_eArgError,
"not an array");
1461rb_yield_force_blockarg(
VALUE values)
1463 return vm_yield_force_blockarg(GET_EC(), values);
1469 return vm_yield_with_block(GET_EC(), argc, argv,
1470 NIL_P(blockarg) ? VM_BLOCK_HANDLER_NONE : blockarg,
1481 const struct vm_ifunc *
const ifunc,
1484 enum ruby_tag_type state;
1490 state = EC_EXEC_TAG();
1494 VALUE block_handler;
1498 captured->code.ifunc = ifunc;
1499 block_handler = VM_BH_FROM_IFUNC_BLOCK(captured);
1502 block_handler = VM_CF_BLOCK_HANDLER(cfp);
1504 vm_passed_block_handler_set(ec, block_handler);
1506 retval = (*it_proc) (data1);
1508 else if (state == TAG_BREAK || state == TAG_RETRY) {
1512 if (cfp == escape_cfp) {
1513 rb_vm_rewind_cfp(ec, cfp);
1516 ec->tag->state = TAG_NONE;
1519 if (state == TAG_RETRY)
goto iter_retry;
1520 retval = THROW_DATA_VAL(err);
1523 SDR(); fprintf(stderr,
"%p, %p\n", (
void *)cfp, (
void *)escape_cfp);
1529 EC_JUMP_TAG(ec, state);
1538 return rb_iterate0(it_proc, data1,
1539 bl_proc ? rb_vm_ifunc_proc_new(bl_proc, (
void *)data2) : 0,
1552iterate_method(
VALUE obj)
1557 return rb_call(arg->obj, arg->mid, arg->argc, arg->argv, arg->kw_splat ? CALL_FCALL_KW : CALL_FCALL);
1579 arg.kw_splat = kw_splat;
1580 return rb_iterate_internal(iterate_method, (
VALUE)&arg, bl_proc, data2);
1596rb_block_call2(
VALUE obj,
ID mid,
int argc,
const VALUE *argv,
1605 arg.kw_splat = flags & 1;
1607 struct vm_ifunc *ifunc = rb_vm_ifunc_proc_new(bl_proc, (
void *)data2);
1608 if (flags & RB_BLOCK_NO_USE_PACKED_ARGS)
1609 ifunc->flags |= IFUNC_YIELD_OPTIMIZABLE;
1611 return rb_iterate0(iterate_method, (
VALUE)&arg, ifunc, GET_EC());
1615rb_lambda_call(
VALUE obj,
ID mid,
int argc,
const VALUE *argv,
1622 if (!bl_proc) rb_raise(rb_eArgError,
"NULL lambda function");
1628 block = rb_vm_ifunc_new(bl_proc, (
void *)data2, min_argc, max_argc);
1629 return rb_iterate0(iterate_method, (
VALUE)&arg, block, GET_EC());
1633iterate_check_method(
VALUE obj)
1642rb_check_block_call(
VALUE obj,
ID mid,
int argc,
const VALUE *argv,
1652 return rb_iterate_internal(iterate_check_method, (
VALUE)&arg, bl_proc, data2);
1658 return rb_call(obj, idEach, 0, 0, CALL_FCALL);
1663#define EVAL_LOCATION_MARK "eval at "
1664#define EVAL_LOCATION_MARK_LEN (int)rb_strlen_lit(EVAL_LOCATION_MARK)
1667get_eval_default_path(
void)
1669 int location_lineno;
1670 VALUE location_path = rb_source_location(&location_lineno);
1671 if (!
NIL_P(location_path)) {
1672 return rb_fstring(rb_sprintf(
"("EVAL_LOCATION_MARK
"%"PRIsVALUE
":%d)",
1673 location_path, location_lineno));
1676 if (!eval_default_path) {
1677 eval_default_path = rb_fstring_lit(
"(eval)");
1678 rb_vm_register_global_object(eval_default_path);
1680 return eval_default_path;
1684compute_isolated_depth_from_ep(
const VALUE *ep)
1688 if (VM_ENV_FLAGS(ep, VM_ENV_FLAG_ISOLATED))
return depth;
1689 if (VM_ENV_LOCAL_P(ep))
return 0;
1690 ep = VM_ENV_PREV_EP(ep);
1696compute_isolated_depth_from_block(
const struct rb_block *blk)
1698 return compute_isolated_depth_from_ep(vm_block_ep(blk));
1702pm_eval_make_iseq(
VALUE src,
VALUE fname,
int line,
1705 const rb_iseq_t *
const parent = vm_block_iseq(base_block);
1707 VALUE name = rb_fstring_lit(
"<compiled>");
1709 int coverage_enabled = ((rb_get_coverage_mode() & COVERAGE_TARGET_EVAL) != 0) ? 1 : 0;
1710 int isolated_depth = compute_isolated_depth_from_block(base_block);
1713 fname = rb_source_location(&line);
1716 if (!UNDEF_P(fname)) {
1717 if (!
NIL_P(fname)) fname = rb_fstring(fname);
1720 fname = get_eval_default_path();
1721 coverage_enabled = 0;
1725 pm_parse_result_init(&result);
1726 pm_options_line_set(result.
options, line);
1727 result.
node.coverage_enabled = coverage_enabled;
1730 int scopes_count = 0;
1733 }
while ((iseq = ISEQ_BODY(iseq)->parent_iseq));
1734 pm_options_scopes_init(result.
options, scopes_count + 1);
1743#define FORWARDING_POSITIONALS_CHR '*'
1744#define FORWARDING_POSITIONALS_STR "*"
1745#define FORWARDING_KEYWORDS_CHR ':'
1746#define FORWARDING_KEYWORDS_STR ":"
1747#define FORWARDING_BLOCK_CHR '&'
1748#define FORWARDING_BLOCK_STR "&"
1749#define FORWARDING_ALL_CHR '.'
1750#define FORWARDING_ALL_STR "."
1752 for (
int scopes_index = 0; scopes_index < scopes_count; scopes_index++) {
1754 int locals_count = ISEQ_BODY(iseq)->local_table_size;
1757 pm_options_scope_init(options_scope, locals_count);
1761 for (
int local_index = 0; local_index < locals_count; local_index++) {
1762 pm_string_t *scope_local = pm_options_scope_local_mut(options_scope, local_index);
1763 ID local = ISEQ_BODY(iseq)->local_table[local_index];
1766 VALUE name_obj = rb_id2str(local);
1767 const char *name = RSTRING_PTR(name_obj);
1768 size_t length = RSTRING_LEN(name_obj);
1772 if (length == 2 && name[0] ==
'_' && name[1] >=
'1' && name[1] <=
'9') {
1787 char *name_dup =
xmalloc(length);
1788 MEMCPY(name_dup, name,
char, length);
1792 pm_string_owned_init(scope_local, (uint8_t *) name_dup, length);
1794 else if (local == idMULT) {
1796 pm_string_constant_init(scope_local, FORWARDING_POSITIONALS_STR, 1);
1798 else if (local == idPow) {
1800 pm_string_constant_init(scope_local, FORWARDING_KEYWORDS_STR, 1);
1802 else if (local == idAnd) {
1804 pm_string_constant_init(scope_local, FORWARDING_BLOCK_STR, 1);
1806 else if (local == idDot3) {
1808 pm_string_constant_init(scope_local, FORWARDING_ALL_STR, 1);
1812 pm_options_scope_forwarding_set(options_scope, forwarding);
1813 iseq = ISEQ_BODY(iseq)->parent_iseq;
1823 pm_options_scope_init(pm_options_scope_mut(result.
options, scopes_count), 0);
1826 VALUE error = pm_parse_string(&result, src, fname, ruby_vm_keep_script_lines ? &script_lines : NULL);
1829 if (error !=
Qnil) {
1830 pm_parse_result_free(&result);
1840 for (
int scopes_index = 0; scopes_index < scopes_count; scopes_index++) {
1845 parent_scope->coverage_enabled = coverage_enabled;
1846 parent_scope->parser = result.
parser;
1847 int locals_count = ISEQ_BODY(iseq)->local_table_size;
1849 parent_scope->local_table_for_iseq_size = locals_count;
1850 pm_constant_id_list_init(&parent_scope->locals);
1852 for (
int local_index = 0; local_index < locals_count; local_index++) {
1853 const pm_string_t *scope_local = pm_options_scope_local(options_scope, local_index);
1856 const uint8_t *source = pm_string_source(scope_local);
1857 size_t length = pm_string_length(scope_local);
1862 case FORWARDING_POSITIONALS_CHR:
1863 constant_id = PM_CONSTANT_MULT;
1865 case FORWARDING_KEYWORDS_CHR:
1866 constant_id = PM_CONSTANT_POW;
1868 case FORWARDING_BLOCK_CHR:
1869 constant_id = PM_CONSTANT_AND;
1871 case FORWARDING_ALL_CHR:
1872 constant_id = PM_CONSTANT_DOT3;
1875 constant_id = pm_parser_constant_find(result.
parser, source, length);
1880 constant_id = pm_parser_constant_find(result.
parser, source, length);
1883 pm_index_lookup_table_insert(&parent_scope->
index_lookup_table, constant_id, local_index);
1886 pm_constant_id_list_append(result.
arena, &parent_scope->locals, constant_id);
1889 node->previous = parent_scope;
1890 node = parent_scope;
1891 iseq = ISEQ_BODY(iseq)->parent_iseq;
1894#undef FORWARDING_POSITIONALS_CHR
1895#undef FORWARDING_POSITIONALS_STR
1896#undef FORWARDING_KEYWORDS_CHR
1897#undef FORWARDING_KEYWORDS_STR
1898#undef FORWARDING_BLOCK_CHR
1899#undef FORWARDING_BLOCK_STR
1900#undef FORWARDING_ALL_CHR
1901#undef FORWARDING_ALL_STR
1904 iseq = pm_iseq_new_eval(&result.
node, name, fname,
Qnil, line, parent, isolated_depth, &error_state);
1909 pm_scope_node_destroy(prev);
1914 pm_parse_result_free(&result);
1919 rb_jump_tag(error_state);
1922 rb_exec_event_hook_script_compiled(GET_EC(), iseq, src);
1928eval_make_iseq(
VALUE src,
VALUE fname,
int line,
1931 if (rb_ruby_prism_p()) {
1932 return pm_eval_make_iseq(src, fname, line, base_block);
1934 const VALUE parser = rb_parser_new();
1935 const rb_iseq_t *
const parent = vm_block_iseq(base_block);
1940 int coverage_enabled = (rb_get_coverage_mode() & COVERAGE_TARGET_EVAL) != 0;
1941 int isolated_depth = compute_isolated_depth_from_block(base_block);
1944 fname = rb_source_location(&line);
1947 if (!UNDEF_P(fname)) {
1948 if (!
NIL_P(fname)) fname = rb_fstring(fname);
1951 fname = get_eval_default_path();
1952 coverage_enabled = FALSE;
1955 rb_parser_set_context(parser, parent, FALSE);
1956 if (ruby_vm_keep_script_lines) rb_parser_set_script_lines(parser);
1957 ast_value = rb_parser_compile_string_path(parser, fname, src, line);
1959 ast = rb_ruby_ast_data_get(ast_value);
1961 if (ast->body.root) {
1962 ast->body.coverage_enabled = coverage_enabled;
1963 iseq = rb_iseq_new_eval(ast_value,
1964 ISEQ_BODY(parent)->location.label,
1966 parent, isolated_depth);
1968 rb_ast_dispose(ast);
1972 VALUE disasm = rb_iseq_disasm(iseq);
1976 rb_exec_event_hook_script_compiled(GET_EC(), iseq, src);
1993 block.as.captured = *VM_CFP_TO_CAPTURED_BLOCK(cfp);
1994 block.as.captured.self = self;
1995 block.as.captured.code.iseq = CFP_ISEQ(cfp);
1996 block.type = block_type_iseq;
2000 if (rb_zjit_enabled_p) rb_zjit_invalidate_no_ep_escape(CFP_ISEQ(cfp));
2002 iseq = eval_make_iseq(src, file, line, &block);
2008 if (!cref && block.as.captured.code.val) {
2009 rb_cref_t *orig_cref = vm_get_cref(vm_block_ep(&block));
2010 cref = rb_vm_cref_dup(orig_cref);
2012 vm_set_eval_stack(ec, iseq, cref, &block);
2023 const rb_iseq_t *iseq = eval_make_iseq(src, file, line, &bind->block);
2028 vm_set_eval_stack(ec, iseq, NULL, &bind->block);
2031 if (ISEQ_BODY(iseq)->local_table_size > 0) {
2032 vm_bind_update_env(scope, bind, vm_make_env_object(ec, ec->cfp));
2075rb_f_eval(
int argc,
const VALUE *argv,
VALUE self)
2077 VALUE src, scope, vfile, vline;
2081 rb_scan_args(argc, argv,
"13", &src, &scope, &vfile, &vline);
2094 return eval_string_with_cref(self, src, NULL, file, line);
2096 return eval_string_with_scope(scope, src, file, line);
2101ruby_eval_string_from_file(
const char *str,
const char *filename)
2106 VALUE self = cfp ? cfp->self : rb_vm_top_self();
2107 return eval_string_with_cref(self,
rb_str_new2(str), NULL, file, 1);
2113 return ruby_eval_string_from_file(str,
"eval");
2117eval_string_protect(
VALUE str)
2125 return rb_protect(eval_string_protect, (
VALUE)str, pstate);
2135eval_string_wrap_protect(
VALUE data)
2138 rb_cref_t *cref = rb_vm_cref_new_toplevel();
2139 cref->klass_or_self = arg->klass;
2148 VALUE self = th->top_self;
2149 VALUE wrapper = th->top_wrapper;
2157 data.top_self = th->top_self;
2158 data.klass = th->top_wrapper;
2161 val = rb_protect(eval_string_wrap_protect, (
VALUE)&data, &state);
2163 th->top_self = self;
2164 th->top_wrapper = wrapper;
2169 else if (state != TAG_NONE) {
2170 EC_JUMP_TAG(th->ec, state);
2181 VALUE val = rb_eval_cmd_call_kw(cmd, argc, argv, kw_splat);
2187rb_eval_cmd_call_kw(
VALUE cmd,
int argc,
const VALUE *argv,
int kw_splat)
2189 enum ruby_tag_type state;
2194 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
2199 val = eval_string_with_cref(rb_vm_top_self(), cmd, NULL, 0, 0);
2204 if (state) EC_JUMP_TAG(ec, state);
2211yield_under(
VALUE self,
int singleton,
int argc,
const VALUE *argv,
int kw_splat)
2215 VALUE block_handler = VM_CF_BLOCK_HANDLER(cfp);
2216 VALUE new_block_handler = 0;
2219 const VALUE *ep = NULL;
2221 int is_lambda = FALSE;
2224 if (block_handler != VM_BLOCK_HANDLER_NONE) {
2226 switch (vm_block_handler_type(block_handler)) {
2227 case block_handler_type_iseq:
2228 captured = VM_BH_TO_CAPT_BLOCK(block_handler);
2229 new_captured = *captured;
2230 new_block_handler = VM_BH_FROM_ISEQ_BLOCK(&new_captured);
2232 case block_handler_type_ifunc:
2233 captured = VM_BH_TO_CAPT_BLOCK(block_handler);
2234 new_captured = *captured;
2235 new_block_handler = VM_BH_FROM_IFUNC_BLOCK(&new_captured);
2237 case block_handler_type_proc:
2239 VALUE procval = VM_BH_TO_PROC(block_handler);
2241 GetProcPtr(procval, po);
2242 is_lambda = po->header.is_lambda;
2243 if (po->header.is_refined) proc_cref = rb_proc_refinements_cref_for_call(procval);
2244 block_handler = vm_block_to_block_handler(&po->block);
2247 case block_handler_type_symbol:
2248 return rb_sym_proc_call(
SYM2ID(VM_BH_TO_SYMBOL(block_handler)),
2249 argc, argv, kw_splat,
2250 VM_BLOCK_HANDLER_NONE);
2253 new_captured.self = self;
2256 VM_FORCE_WRITE_SPECIAL_CONST(&VM_CF_LEP(ec->cfp)[VM_ENV_DATA_INDEX_SPECVAL], new_block_handler);
2260 cref = vm_cref_push(ec, self, ep, TRUE, singleton);
2262 if (proc_cref && !
NIL_P(CREF_REFINEMENTS(proc_cref))) {
2263 CREF_REFINEMENTS_SET(cref, rb_hash_dup(CREF_REFINEMENTS(proc_cref)));
2264 CREF_REFINED_PROC_SET(cref);
2267 return vm_yield_with_cref(ec, argc, argv, kw_splat, cref, is_lambda);
2271rb_yield_refine_block(
VALUE refinement,
VALUE refinements)
2274 VALUE block_handler = VM_CF_BLOCK_HANDLER(ec->cfp);
2276 if (vm_block_handler_type(block_handler) != block_handler_type_iseq) {
2277 rb_bug(
"rb_yield_refine_block: an iseq block is required");
2282 const VALUE *
const argv = &new_captured.self;
2283 VALUE new_block_handler = VM_BH_FROM_ISEQ_BLOCK(&new_captured);
2284 const VALUE *ep = captured->ep;
2285 rb_cref_t *cref = vm_cref_push(ec, refinement, ep, TRUE, FALSE);
2286 CREF_REFINEMENTS_SET(cref, refinements);
2287 VM_FORCE_WRITE_SPECIAL_CONST(&VM_CF_LEP(ec->cfp)[VM_ENV_DATA_INDEX_SPECVAL], new_block_handler);
2288 new_captured.self = refinement;
2289 return vm_yield_with_cref(ec, 0, argv,
RB_NO_KEYWORDS, cref, FALSE);
2297 rb_cref_t *cref = vm_cref_push(GET_EC(), self, NULL, FALSE, singleton);
2300 return eval_string_with_cref(self, src, cref, file, line);
2304specific_eval(
int argc,
const VALUE *argv,
VALUE self,
int singleton,
int kw_splat)
2308 return yield_under(self, singleton, 1, &self, kw_splat);
2326 file = get_eval_default_path();
2329 return eval_under(self, singleton, code, file, line);
2367rb_obj_instance_eval_internal(
int argc,
const VALUE *argv,
VALUE self)
2397rb_obj_instance_exec_internal(
int argc,
const VALUE *argv,
VALUE self)
2473rb_mod_module_eval_internal(
int argc,
const VALUE *argv,
VALUE mod)
2507rb_mod_module_exec_internal(
int argc,
const VALUE *argv,
VALUE mod)
2532uncaught_throw_init(
int argc,
const VALUE *argv,
VALUE exc)
2549uncaught_throw_tag(
VALUE exc)
2562uncaught_throw_value(
VALUE exc)
2575uncaught_throw_to_s(
VALUE exc)
2577 VALUE mesg = rb_attr_get(exc, id_mesg);
2578 VALUE tag = uncaught_throw_tag(exc);
2611 if (tt->tag == tag) {
2625 ec->errinfo = (
VALUE)THROW_DATA_NEW(tag, NULL, TAG_THROW);
2626 EC_JUMP_TAG(ec, TAG_THROW);
2638 return rb_yield_0(1, &tag);
2710 enum ruby_tag_type state;
2713 enum ruby_tag_type *
volatile stateptr = stateptr_arg;
2719 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
2721 val = (*func)(tag, data, 1, (
const VALUE *)&tag,
Qnil);
2723 else if (state == TAG_THROW && THROW_DATA_VAL((
struct vm_throw_data *)ec->errinfo) == tag) {
2724 rb_vm_rewind_cfp(ec, saved_cfp);
2725 val = ec->tag->retval;
2739 return vm_catch_protect(t, func, data, stateptr, GET_EC());
2745 enum ruby_tag_type state;
2748 if (state) EC_JUMP_TAG(ec, state);
2755 vars->tbl = rb_ident_hash_new();
2756 RBASIC_CLEAR_CLASS(vars->tbl);
2763 VALUE ary = rb_hash_keys(vars->tbl);
2764 rb_hash_clear(vars->tbl);
2770local_var_list_update(st_data_t *key, st_data_t *value, st_data_t arg,
int existing)
2772 if (existing)
return ST_STOP;
2773 *value = (st_data_t)
Qtrue;
2777extern int rb_numparam_id_p(
ID id);
2787 if (rb_numparam_id_p(lid))
return;
2790 rb_hash_stlike_update(vars->tbl,
ID2SYM(lid), local_var_list_update, idx);
2801 if (rb_numparam_id_p(lid)) {
2803 rb_hash_stlike_update(vars->tbl,
ID2SYM(lid), local_var_list_update, idx);
2821rb_f_local_variables(
VALUE _)
2825 rb_control_frame_t *cfp = vm_get_ruby_level_caller_cfp(ec, RUBY_VM_PREVIOUS_CONTROL_FRAME(ec->cfp));
2828 local_var_list_init(&vars);
2830 if (CFP_ISEQ(cfp)) {
2831 for (i = 0; i < ISEQ_BODY(CFP_ISEQ(cfp))->local_table_size; i++) {
2832 local_var_list_add(&vars, ISEQ_BODY(CFP_ISEQ(cfp))->local_table[i]);
2835 if (!VM_ENV_LOCAL_P(cfp->ep)) {
2837 const VALUE *ep = VM_CF_PREV_EP(cfp);
2839 if (vm_collect_local_variables_in_heap(ep, &vars)) {
2843 while (cfp->ep != ep) {
2844 cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
2852 return local_var_list_finish(&vars);
2876rb_f_block_given_p(
VALUE _)
2880 cfp = vm_get_ruby_level_caller_cfp(ec, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
2882 return RBOOL(cfp != NULL && VM_CF_BLOCK_HANDLER(cfp) != VM_BLOCK_HANDLER_NONE);
2893rb_f_iterator_p(
VALUE self)
2895 rb_warn_deprecated(
"iterator?",
"block_given?");
2896 return rb_f_block_given_p(self);
2900rb_current_realfilepath(
void)
2904 cfp = vm_get_ruby_level_caller_cfp(ec, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
2907 VALUE path = rb_iseq_realpath(iseq);
2908 if (
RTEST(path))
return path;
2910 path = rb_iseq_path(iseq);
2911 if (path == eval_default_path) {
2916 const long len = RSTRING_LEN(path);
2917 if (
len > EVAL_LOCATION_MARK_LEN+1) {
2918 const char *
const ptr = RSTRING_PTR(path);
2919 if (ptr[
len - 1] ==
')' &&
2920 memcmp(ptr,
"("EVAL_LOCATION_MARK, EVAL_LOCATION_MARK_LEN+1) == 0) {
2933rb_current_ifunc(
void)
2936 VALUE ifunc = (
VALUE)CFP_ISEQ(GET_EC()->cfp);
2958 VM_METHOD_TYPE_OPTIMIZED, (
void *)OPTIMIZED_METHOD_TYPE_SEND, METHOD_VISI_PUBLIC);
2960 VM_METHOD_TYPE_OPTIMIZED, (
void *)OPTIMIZED_METHOD_TYPE_SEND, METHOD_VISI_PUBLIC);
2972 rb_eUncaughtThrow = rb_define_class(
"UncaughtThrowError", rb_eArgError);
2973 rb_define_method(rb_eUncaughtThrow,
"initialize", uncaught_throw_init, -1);
#define RUBY_ASSERT_ALWAYS(expr,...)
A variant of RUBY_ASSERT that does not interface with RUBY_DEBUG.
#define RUBY_ASSERT(...)
Asserts that the given expression is truthy if and only if RUBY_DEBUG is truthy.
uint32_t pm_constant_id_t
A constant id is a unique identifier for a constant in the constant pool.
#define rb_define_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_C_CALL
A method, written in C, is called.
#define RUBY_EVENT_C_RETURN
Return from a method, written in C.
void rb_extend_object(VALUE obj, VALUE module)
Extend the object with the module.
VALUE rb_module_new(void)
Creates a new, anonymous module.
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.
#define rb_str_new2
Old name of rb_str_new_cstr.
#define T_COMPLEX
Old name of RUBY_T_COMPLEX.
#define T_FILE
Old name of RUBY_T_FILE.
#define T_STRING
Old name of RUBY_T_STRING.
#define T_MASK
Old name of RUBY_T_MASK.
#define Qundef
Old name of RUBY_Qundef.
#define T_NIL
Old name of RUBY_T_NIL.
#define T_FLOAT
Old name of RUBY_T_FLOAT.
#define T_IMEMO
Old name of RUBY_T_IMEMO.
#define ID2SYM
Old name of RB_ID2SYM.
#define T_BIGNUM
Old name of RUBY_T_BIGNUM.
#define SPECIAL_CONST_P
Old name of RB_SPECIAL_CONST_P.
#define T_STRUCT
Old name of RUBY_T_STRUCT.
#define OBJ_FREEZE
Old name of RB_OBJ_FREEZE.
#define T_FIXNUM
Old name of RUBY_T_FIXNUM.
#define UNREACHABLE_RETURN
Old name of RBIMPL_UNREACHABLE_RETURN.
#define SYM2ID
Old name of RB_SYM2ID.
#define T_DATA
Old name of RUBY_T_DATA.
#define CLASS_OF
Old name of rb_class_of.
#define T_NONE
Old name of RUBY_T_NONE.
#define T_NODE
Old name of RUBY_T_NODE.
#define rb_ary_new4
Old name of rb_ary_new_from_values.
#define xmalloc
Old name of ruby_xmalloc.
#define T_MODULE
Old name of RUBY_T_MODULE.
#define T_TRUE
Old name of RUBY_T_TRUE.
#define T_RATIONAL
Old name of RUBY_T_RATIONAL.
#define T_ICLASS
Old name of RUBY_T_ICLASS.
#define T_HASH
Old name of RUBY_T_HASH.
#define T_FALSE
Old name of RUBY_T_FALSE.
#define T_UNDEF
Old name of RUBY_T_UNDEF.
#define Qtrue
Old name of RUBY_Qtrue.
#define NUM2INT
Old name of RB_NUM2INT.
#define T_ZOMBIE
Old name of RUBY_T_ZOMBIE.
#define Qnil
Old name of RUBY_Qnil.
#define Qfalse
Old name of RUBY_Qfalse.
#define ENC_CODERANGE_BROKEN
Old name of RUBY_ENC_CODERANGE_BROKEN.
#define T_ARRAY
Old name of RUBY_T_ARRAY.
#define T_OBJECT
Old name of RUBY_T_OBJECT.
#define NIL_P
Old name of RB_NIL_P.
#define ALLOCV_N
Old name of RB_ALLOCV_N.
#define T_SYMBOL
Old name of RUBY_T_SYMBOL.
#define T_MATCH
Old name of RUBY_T_MATCH.
#define T_CLASS
Old name of RUBY_T_CLASS.
#define BUILTIN_TYPE
Old name of RB_BUILTIN_TYPE.
#define T_MOVED
Old name of RUBY_T_MOVED.
#define Check_TypedStruct(v, t)
Old name of rb_check_typeddata.
#define ALLOCV_END
Old name of RB_ALLOCV_END.
#define SYMBOL_P
Old name of RB_SYMBOL_P.
#define T_REGEXP
Old name of RUBY_T_REGEXP.
VALUE rb_eNotImpError
NotImplementedError exception.
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
VALUE rb_eNameError
NameError exception.
VALUE rb_eNoMethodError
NoMethodError exception.
VALUE rb_eRuntimeError
RuntimeError exception.
VALUE rb_mKernel
Kernel module.
VALUE rb_cObject
Object class.
VALUE rb_obj_alloc(VALUE klass)
Allocates an instance of the given class.
VALUE rb_class_new_instance(int argc, const VALUE *argv, VALUE klass)
Allocates, then initialises an instance of the given class.
VALUE rb_obj_class(VALUE obj)
Queries the class of an object.
VALUE rb_cBasicObject
BasicObject class.
VALUE rb_cModule
Module class.
VALUE rb_obj_clone(VALUE obj)
Produces a shallow copy of the given object.
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.
VALUE rb_eval_string_wrap(const char *str, int *state)
Identical to rb_eval_string_protect(), except it evaluates the given string under a module binding in...
VALUE rb_funcall_passing_block(VALUE recv, ID mid, int argc, const VALUE *argv)
Identical to rb_funcallv_public(), except you can pass the passed block.
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_funcallv(VALUE recv, ID mid, int argc, const VALUE *argv)
Identical to rb_funcall(), except it takes the method arguments as a C array.
VALUE rb_funcall_with_block(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE procval)
Identical to rb_funcallv_public(), except you can pass a block.
VALUE rb_eval_string_protect(const char *str, int *state)
Identical to rb_eval_string(), except it avoids potential global escapes.
VALUE rb_call_super_kw(int argc, const VALUE *argv, int kw_splat)
Identical to rb_call_super(), except you can specify how to handle the last element of the given arra...
VALUE rb_funcallv_public(VALUE recv, ID mid, int argc, const VALUE *argv)
Identical to rb_funcallv(), except it only takes public methods into account.
VALUE rb_current_receiver(void)
This resembles ruby's self.
VALUE rb_funcall_passing_block_kw(VALUE recv, ID mid, int argc, const VALUE *argv, int kw_splat)
Identical to rb_funcallv_passing_block(), except you can specify how to handle the last element of th...
VALUE rb_funcall_with_block_kw(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE procval, int kw_splat)
Identical to rb_funcallv_with_block(), except you can specify how to handle the last element of the g...
VALUE rb_eval_string(const char *str)
Evaluates the given string.
VALUE rb_call_super(int argc, const VALUE *argv)
This resembles ruby's super.
VALUE rb_funcallv_public_kw(VALUE recv, ID mid, int argc, const VALUE *argv, int kw_splat)
Identical to rb_funcallv_public(), except you can specify how to handle the last element of the given...
VALUE rb_ary_cat(VALUE ary, const VALUE *train, long len)
Destructively appends multiple elements at the end of the array.
VALUE rb_check_array_type(VALUE obj)
Try converting an object to its array representation using its to_ary method, if any.
VALUE rb_ary_pop(VALUE ary)
Destructively deletes an element from the end of the passed array and returns what was deleted.
VALUE rb_ary_hidden_new(long capa)
Allocates a hidden (no class) empty array.
VALUE rb_ary_subseq(VALUE ary, long beg, long len)
Obtains a part of the passed array.
#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.
int rb_is_local_id(ID id)
Classifies the given ID, then sees if it is a local variable.
#define rb_str_new_cstr(str)
Identical to rb_str_new, except it assumes the passed pointer is a pointer to a C string.
VALUE rb_str_intern(VALUE str)
Identical to rb_to_symbol(), except it assumes the receiver being an instance of RString.
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_ivar_get(VALUE obj, ID name)
Identical to rb_iv_get(), except it accepts the name as an ID instead of a C string.
int rb_method_basic_definition_p(VALUE klass, ID mid)
Well... Let us hesitate from describing what a "basic definition" is.
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.
VALUE rb_check_funcall_kw(VALUE recv, ID mid, int argc, const VALUE *argv, int kw_splat)
Identical to rb_check_funcall(), except you can specify how to handle the last element of the given a...
VALUE rb_mod_module_eval(int argc, const VALUE *argv, VALUE mod)
Identical to rb_obj_instance_eval(), except it evaluates within the context of module.
VALUE rb_mod_module_exec(int argc, const VALUE *argv, VALUE mod)
Identical to rb_obj_instance_exec(), except it evaluates within the context of module.
VALUE rb_obj_instance_exec(int argc, const VALUE *argv, VALUE recv)
Executes the given block within the context of the receiver.
VALUE rb_eval_cmd_kw(VALUE cmd, VALUE arg, int kw_splat)
This API is practically a variant of rb_proc_call_kw() now.
VALUE rb_apply(VALUE recv, ID mid, VALUE args)
Identical to rb_funcallv(), except it takes Ruby's array instead of C's.
VALUE rb_obj_instance_eval(int argc, const VALUE *argv, VALUE recv)
Evaluates a string containing Ruby source code, or the given block, within the context of the receive...
static ID rb_intern_const(const char *str)
This is a "tiny optimisation" over rb_intern().
ID rb_check_id(volatile VALUE *namep)
Detects if the given name is already interned or not.
int len
Length of the buffer.
VALUE rb_str_format(int argc, const VALUE *argv, VALUE fmt)
Formats a string.
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)
Shim for block function parameters.
VALUE rb_each(VALUE obj)
This is a shorthand of calling obj.each.
VALUE rb_yield_values(int n,...)
Identical to rb_yield(), except it takes variadic number of parameters and pass them to the block.
VALUE rb_yield_splat(VALUE ary)
Identical to rb_yield_values(), except it splats an array to generate the list of parameters.
void rb_throw(const char *tag, VALUE val)
Transfers control to the end of the active catch block waiting for tag.
VALUE rb_yield_values2(int n, const VALUE *argv)
Identical to rb_yield_values(), except it takes the parameters as a C array instead of variadic argum...
VALUE rb_yield(VALUE val)
Yields the block.
VALUE rb_yield_values_kw(int n, const VALUE *argv, int kw_splat)
Identical to rb_yield_values2(), except you can specify how to handle the last element of the given a...
rb_block_call_func * rb_block_call_func_t
Shorthand type that represents an iterator-written-in-C function pointer.
VALUE rb_yield_block(RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg))
Pass a passed block.
void rb_throw_obj(VALUE tag, VALUE val)
Identical to rb_throw(), except it allows arbitrary Ruby object to become a tag.
VALUE rb_block_call_func(RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg))
This is the type of a function that the interpreter expect for C-backended blocks.
VALUE rb_block_call_kw(VALUE obj, ID mid, int argc, const VALUE *argv, rb_block_call_func_t proc, VALUE data2, int kw_splat)
Identical to rb_funcallv_kw(), except it additionally passes a function as a block.
VALUE rb_yield_splat_kw(VALUE ary, int kw_splat)
Identical to rb_yield_splat(), except you can specify how to handle the last element of the given arr...
#define MEMCPY(p1, p2, type, n)
Handy macro to call memcpy.
#define ALLOCA_N(type, n)
#define MEMZERO(p, type, n)
Handy macro to erase a region of memory.
#define RB_GC_GUARD(v)
Prevents premature destruction of local objects.
VALUE rb_catch_obj(VALUE q, type *w, VALUE e)
An equivalent of Kernel#catch.
VALUE rb_catch(const char *q, type *w, VALUE e)
An equivalent of Kernel#catch.
VALUE rb_block_call(VALUE q, ID w, int e, const VALUE *r, type *t, VALUE y)
Call a method with a block.
VALUE type(ANYARGS)
ANYARGS-ed function type.
VALUE rb_rescue2(type *q, VALUE w, type *e, VALUE r,...)
An equivalent of rescue clause.
static const uint8_t PM_OPTIONS_SCOPE_FORWARDING_NONE
The default value for parameters.
static const uint8_t PM_OPTIONS_SCOPE_FORWARDING_ALL
When the scope is forwarding with the ... parameter.
static const uint8_t PM_OPTIONS_SCOPE_FORWARDING_POSITIONALS
When the scope is forwarding with the * parameter.
static const uint8_t PM_OPTIONS_SCOPE_FORWARDING_KEYWORDS
When the scope is forwarding with the ** parameter.
static const uint8_t PM_OPTIONS_SCOPE_FORWARDING_BLOCK
When the scope is forwarding with the & parameter.
static int RARRAY_LENINT(VALUE ary)
Identical to rb_array_len(), except it differs for the return type.
#define RARRAY_CONST_PTR
Just another name of rb_array_const_ptr.
static VALUE RBASIC_CLASS(VALUE obj)
Queries the class of an object.
#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.
#define StringValue(v)
Ensures that the parameter object is a String.
#define StringValuePtr(v)
Identical to StringValue, except it returns a char*.
#define RB_PASS_CALLED_KEYWORDS
Pass keywords if current method is called with keywords, useful for argument delegation.
#define RB_NO_KEYWORDS
Do not pass keywords.
#define RTEST
This is an old name of RB_TEST.
#define _(args)
This was a transition path from K&R to ANSI.
pm_parser_t * parser
The parser that will do the actual parsing.
pm_scope_node_t node
The resulting scope node that will hold the generated AST.
pm_options_t * options
The options that will be passed to the parser.
pm_arena_t * arena
The arena allocator for AST-lifetime memory.
pm_index_lookup_table_t index_lookup_table
A flat lookup table mapping constant IDs (or special IDs) to local variable indices.
A generic string type that can have various ownership semantics.
Internal header for Ruby Box.
IFUNC (Internal FUNCtion)
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.
ruby_value_type
C-level type of an object.