12#include "eval_intern.h"
14#include "internal/class.h"
15#include "internal/error.h"
16#include "internal/eval.h"
17#include "internal/gc.h"
18#include "internal/hash.h"
19#include "internal/object.h"
20#include "internal/proc.h"
21#include "internal/symbol.h"
22#include "internal/vm.h"
26#include "ractor_core.h"
47static VALUE rb_cSourceRange;
50static int method_arity(
VALUE);
51static int method_min_max_arity(
VALUE,
int *max);
64source_range_memsize(
const void *ptr)
69RUBY_REFERENCES(source_range_refs) = {
78 RUBY_REFS_LIST_PTR(source_range_refs),
93 data->start_line = location->beg_pos.lineno;
94 data->start_column = location->beg_pos.column;
95 data->end_line = location->end_pos.lineno;
96 data->end_column = location->end_pos.column;
109 VALUE path = rb_iseq_path(iseq);
110 VALUE absolute_path = rb_iseq_realpath(iseq);
115 return rb_source_range_new(path, absolute_path, &ISEQ_BODY(iseq)->location.code_location);
119source_range_data_get(
VALUE self)
134source_range_path(
VALUE self)
136 return source_range_data_get(self)->path;
147source_range_absolute_path(
VALUE self)
149 return source_range_data_get(self)->absolute_path;
159source_range_start_line(
VALUE self)
161 return INT2NUM(source_range_data_get(self)->start_line);
176source_range_start_column(
VALUE self)
178 return INT2NUM(source_range_data_get(self)->start_column);
197source_range_end_line(
VALUE self)
199 return INT2NUM(source_range_data_get(self)->end_line);
218source_range_end_column(
VALUE self)
220 return INT2NUM(source_range_data_get(self)->end_column);
231source_range_inspect(
VALUE self)
235 VALUE path =
NIL_P(data->absolute_path) ? data->path : data->absolute_path;
237 VM_ASSERT(!
NIL_P(path));
240 rb_str_catf(str,
":(%d,%d)-(%d,%d)>",
241 data->start_line, data->start_column,
242 data->end_line, data->end_column);
249#define IS_METHOD_PROC_IFUNC(ifunc) ((ifunc)->func == bmcall)
252block_mark_and_move(
struct rb_block *block)
254 switch (block->type) {
255 case block_type_iseq:
256 case block_type_ifunc:
259 rb_gc_mark_and_move(&captured->self);
260 rb_gc_mark_and_move(&captured->code.val);
262 rb_gc_mark_and_move((
VALUE *)&captured->ep[VM_ENV_DATA_INDEX_ENV]);
266 case block_type_symbol:
267 rb_gc_mark_and_move(&block->as.symbol);
269 case block_type_proc:
270 rb_gc_mark_and_move(&block->as.proc);
275static ID id_refinements_recipe;
278proc_mark_and_move(
void *ptr)
281 block_mark_and_move((
struct rb_block *)&proc->block);
284enum refinement_recipe_index {
285 REFINEMENT_RECIPE_BASE_CREF,
286 REFINEMENT_RECIPE_CREF,
287 REFINEMENT_RECIPE_SRC_ISEQ,
288 REFINEMENT_RECIPE_MODS
294 if (r1 == r2)
return true;
297 if (
RARRAY_AREF(r1, REFINEMENT_RECIPE_BASE_CREF) !=
298 RARRAY_AREF(r2, REFINEMENT_RECIPE_BASE_CREF))
return false;
300 RARRAY_AREF(r2, REFINEMENT_RECIPE_SRC_ISEQ))
return false;
301 for (
long i = REFINEMENT_RECIPE_MODS; i <
len; i++) {
308rb_proc_refinements_recipe(
VALUE procval)
311 GetProcPtr(procval, proc);
312 if (!proc->header.is_refined)
return Qnil;
313 return rb_ivar_get(procval, id_refinements_recipe);
317rb_proc_set_refinements_recipe(
VALUE procval,
VALUE recipe)
320 GetProcPtr(procval, proc);
321 rb_ivar_set(procval, id_refinements_recipe, recipe);
322 proc->header.is_refined = 1;
327 VALUE env[VM_ENV_DATA_SIZE + 1];
331proc_memsize(
const void *ptr)
334 switch (proc->block.type) {
335 case block_type_iseq:
336 case block_type_ifunc:
337 if (proc->block.as.captured.ep == ((
const cfunc_proc_t *)ptr)->env+1)
340 case block_type_symbol:
342 case block_type_proc:
345 VM_UNREACHABLE(proc_memsize);
357 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED
360#define proc_data_type ruby_proc_data_type
363rb_proc_alloc(
VALUE klass,
enum rb_block_type block_type)
366 switch (block_type) {
367 case block_type_symbol:
370 case block_type_proc:
373 case block_type_iseq:
374 case block_type_ifunc:
378 VM_UNREACHABLE(rb_proc_alloc);
382 return rb_data_typed_object_zalloc(klass, size, &proc_data_type);
388 return RBOOL(rb_typeddata_is_kind_of(proc, &proc_data_type));
393proc_clone(
VALUE self)
395 VALUE procval = rb_proc_dup_0(self);
396 return rb_obj_clone_setup(self, procval,
Qnil);
403 VALUE procval = rb_proc_dup_0(self);
404 return rb_obj_dup_setup(self, procval);
425enum refinement_memo_index {
426 REFINEMENT_MEMO_RECIPE,
427 REFINEMENT_MEMO_COPIED_ISEQ
430static VALUE refinement_memo_map;
433refinement_memo_get(
const rb_iseq_t *src_iseq)
437 if (refinement_memo_map) {
438 memo = rb_hash_lookup(refinement_memo_map, (
VALUE)src_iseq);
447 VM_ASSERT(ISEQ_BODY(src_iseq)->
type == ISEQ_TYPE_BLOCK);
459 if (!refinement_memo_map) {
464 if (!refinement_memo_map) {
465 rb_vm_register_global_object(new_map);
466 refinement_memo_map = new_map;
468 rb_hash_aset(refinement_memo_map, (
VALUE)src_iseq, memo);
473refinement_recipe_modc(
VALUE recipe)
475 return NIL_P(recipe) ? 0 :
RARRAY_LEN(recipe) - REFINEMENT_RECIPE_MODS;
480 long argc,
const VALUE *mods)
482 long inherited = refinement_recipe_modc(src_recipe);
483 if (
RARRAY_AREF(recipe, REFINEMENT_RECIPE_BASE_CREF) != (
VALUE)base_cref)
return false;
484 if (refinement_recipe_modc(recipe) != inherited + argc)
return false;
485 for (
long i = 0; i < inherited; i++) {
486 if (
RARRAY_AREF(recipe, REFINEMENT_RECIPE_MODS + i) !=
487 RARRAY_AREF(src_recipe, REFINEMENT_RECIPE_MODS + i))
return false;
489 for (
long i = 0; i < argc; i++) {
490 if (
RARRAY_AREF(recipe, REFINEMENT_RECIPE_MODS + inherited + i) != mods[i])
return false;
498 long argc,
const VALUE *mods)
500 long inherited = refinement_recipe_modc(src_recipe);
505 for (
long i = 0; i < inherited; i++) {
508 for (
long i = 0; i < argc; i++) {
518 long argc,
const VALUE *mods)
520 VM_ASSERT(ISEQ_BODY(src_iseq)->
type == ISEQ_TYPE_BLOCK);
521 VALUE memo = refinement_memo_get(src_iseq);
524 if (!refinement_recipe_match(recipe, base_cref, src_recipe, argc, mods))
return Qnil;
529refinement_iseq_copy(
VALUE recipe)
533 VALUE memo = refinement_memo_get(src_iseq);
535 if (refinement_recipe_eq(
RARRAY_AREF(memo, REFINEMENT_MEMO_RECIPE), recipe)) {
538 if (ISEQ_BODY(copied_iseq)->param.flags.ruby2_keywords ==
539 ISEQ_BODY(src_iseq)->param.flags.ruby2_keywords) {
544 "Proc#refined re-copies the block because the ruby2_keywords flag changed after the copy was memoized"
550 "Proc#refined called with different modules for the same block disables memoization"
556 const rb_iseq_t *copied_iseq = rb_iseq_dup_with_independent_caches(src_iseq);
557 refinement_memo_set(src_iseq, recipe, copied_iseq);
561NOINLINE(
static void refinement_iseq_install(
VALUE procval,
rb_proc_t *proc));
566 const rb_iseq_t *copied_iseq = refinement_iseq_copy(recipe);
569 if (!
FL_TEST_RAW((
VALUE)proc->block.as.captured.code.iseq, ISEQ_REFINED_COPY)) {
578 if (UNLIKELY(!
FL_TEST_RAW((
VALUE)proc->block.as.captured.code.iseq, ISEQ_REFINED_COPY))) {
579 refinement_iseq_install(procval, proc);
584rb_proc_refinements_cref_for_call(
VALUE procval)
587 GetProcPtr(procval, proc);
588 if (!proc->header.is_refined)
return NULL;
590 refinement_iseq_ensure(procval, proc);
649proc_refined(
int argc,
VALUE *argv,
VALUE self)
652 GetProcPtr(self, src);
658 if (vm_block_type(&src->block) != block_type_iseq || src->header.is_from_method) {
659 rb_raise(rb_eArgError,
"can't apply refinements to a Proc without a Ruby block");
662 for (
int i = 0; i < argc; i++) {
666 const rb_iseq_t *src_iseq = src->block.as.captured.code.iseq;
667 VALUE src_recipe = rb_proc_refinements_recipe(self);
669 if (
NIL_P(src_recipe)) {
670 src_cref = base_cref = rb_vm_get_cref(src->block.as.captured.ep);
686 "Proc#refined on a Proc whose block was already copied by Proc#refined is not memoized"
691 refinement_memo_lookup(src_iseq, base_cref, src_recipe, argc, argv);
693 rb_cref_t *cref = rb_vm_cref_dup(src_cref);
696 for (
int i = 0; i < argc; i++) {
697 rb_using_module_recursive(cref, argv[i]);
702 VALUE refs = CREF_REFINEMENTS(cref);
707 CREF_OMOD_SHARED_SET(cref);
708 CREF_REFINED_PROC_SET(cref);
709 recipe = refinement_recipe_new(base_cref, cref, src_iseq, src_recipe, argc, argv);
713 rb_iseq_dup_with_independent_caches(src_iseq) : src_iseq;
715 return rb_proc_dup_with_iseq_and_recipe(self, new_iseq, recipe);
825 GetProcPtr(procval, proc);
827 return RBOOL(proc->header.is_lambda);
833binding_free(
void *ptr)
835 RUBY_FREE_ENTER(
"binding");
837 RUBY_FREE_LEAVE(
"binding");
841binding_mark_and_move(
void *ptr)
845 block_mark_and_move((
struct rb_block *)&bind->block);
846 rb_gc_mark_and_move((
VALUE *)&bind->pathobj);
850binding_memsize(
const void *ptr)
858 binding_mark_and_move,
861 binding_mark_and_move,
863 0, 0, RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_THREAD_SAFE_FREE
867rb_binding_alloc(
VALUE klass)
873 rb_yjit_collect_binding_alloc();
879binding_copy(
VALUE self)
883 GetBindingPtr(self, src);
884 GetBindingPtr(bindval, dst);
885 rb_vm_block_copy(bindval, &dst->block, &src->block);
887 dst->first_lineno = src->first_lineno;
893binding_dup(
VALUE self)
895 return rb_obj_dup_setup(self, binding_copy(self));
900binding_clone(
VALUE self)
902 return rb_obj_clone_setup(self, binding_copy(self),
Qnil);
909 return rb_vm_make_binding(ec, ec->cfp);
957rb_f_binding(
VALUE self)
991bind_eval(
int argc,
VALUE *argv,
VALUE bindval)
995 rb_scan_args(argc, argv,
"12", &args[0], &args[2], &args[3]);
997 return rb_f_eval(argc+1, args,
Qnil );
1001get_local_variable_ptr(
const rb_env_t **envp,
ID lid,
bool search_outer)
1005 if (!VM_ENV_FLAGS(env->ep, VM_FRAME_FLAG_CFRAME)) {
1006 if (VM_ENV_FLAGS(env->ep, VM_ENV_FLAG_ISOLATED)) {
1012 VM_ASSERT(rb_obj_is_iseq((
VALUE)iseq));
1014 const unsigned int local_table_size = ISEQ_BODY(iseq)->local_table_size;
1015 for (
unsigned int i=0; i<local_table_size; i++) {
1016 if (ISEQ_BODY(iseq)->local_table[i] == lid) {
1017 if (ISEQ_BODY(iseq)->local_iseq == iseq &&
1018 ISEQ_BODY(iseq)->param.flags.has_block &&
1019 (
unsigned int)ISEQ_BODY(iseq)->param.block_start == i) {
1020 const VALUE *ep = env->ep;
1021 if (!VM_ENV_FLAGS(ep, VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM)) {
1022 RB_OBJ_WRITE(env, &env->env[i], rb_vm_bh_to_procval(GET_EC(), VM_ENV_BLOCK_HANDLER(ep)));
1023 VM_ENV_FLAGS_SET(ep, VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM);
1028 unsigned int last_lvar = env->env_size+VM_ENV_INDEX_LAST_LVAR
1030 return &env->env[last_lvar - (local_table_size - i)];
1038 }
while (search_outer && (env = rb_vm_env_prev_env(env)) != NULL);
1050check_local_id(
VALUE bindval,
volatile VALUE *pname)
1053 VALUE name = *pname;
1057 rb_name_err_raise(
"wrong local variable name '%1$s' for %2$s",
1062 if (!rb_is_local_name(name)) {
1063 rb_name_err_raise(
"wrong local variable name '%1$s' for %2$s",
1090bind_local_variables(
VALUE bindval)
1095 GetBindingPtr(bindval, bind);
1096 env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
1097 return rb_vm_env_local_variables(env);
1101rb_numparam_id_p(
ID id)
1103 return (tNUMPARAM_1 << ID_SCOPE_SHIFT) <=
id &&
id < ((tNUMPARAM_1 + 9) << ID_SCOPE_SHIFT);
1107rb_implicit_param_p(
ID id)
1109 return id == idItImplicit || rb_numparam_id_p(
id);
1130bind_local_variable_get(
VALUE bindval,
VALUE sym)
1132 ID lid = check_local_id(bindval, &sym);
1137 if (!lid)
goto undefined;
1138 if (rb_numparam_id_p(lid)) {
1139 rb_name_err_raise(
"numbered parameter '%1$s' is not a local variable",
1143 GetBindingPtr(bindval, bind);
1145 env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
1146 if ((ptr = get_local_variable_ptr(&env, lid, TRUE)) != NULL) {
1152 rb_name_err_raise(
"local variable '%1$s' is not defined for %2$s",
1185 ID lid = check_local_id(bindval, &sym);
1190 if (!lid) lid = rb_intern_str(sym);
1191 if (rb_numparam_id_p(lid)) {
1192 rb_name_err_raise(
"numbered parameter '%1$s' is not a local variable",
1196 GetBindingPtr(bindval, bind);
1197 env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
1198 if ((ptr = get_local_variable_ptr(&env, lid, TRUE)) == NULL) {
1200 ptr = rb_binding_add_dynavars(bindval, bind, 1, &lid);
1201 env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
1205 rb_yjit_collect_binding_set();
1231bind_local_variable_defined_p(
VALUE bindval,
VALUE sym)
1233 ID lid = check_local_id(bindval, &sym);
1238 if (rb_numparam_id_p(lid)) {
1239 rb_name_err_raise(
"numbered parameter '%1$s' is not a local variable",
1243 GetBindingPtr(bindval, bind);
1244 env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
1245 return RBOOL(get_local_variable_ptr(&env, lid, TRUE));
1269bind_implicit_parameters(
VALUE bindval)
1274 GetBindingPtr(bindval, bind);
1275 env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
1277 if (get_local_variable_ptr(&env, idItImplicit, FALSE)) {
1278 return rb_ary_new_from_args(1,
ID2SYM(idIt));
1281 env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
1282 return rb_vm_env_numbered_parameters(env);
1306bind_implicit_parameter_get(
VALUE bindval,
VALUE sym)
1308 ID lid = check_local_id(bindval, &sym);
1313 if (lid == idIt) lid = idItImplicit;
1315 if (!lid || !rb_implicit_param_p(lid)) {
1316 rb_name_err_raise(
"'%1$s' is not an implicit parameter",
1320 GetBindingPtr(bindval, bind);
1322 env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
1323 if ((ptr = get_local_variable_ptr(&env, lid, FALSE)) != NULL) {
1327 if (lid == idItImplicit) lid = idIt;
1328 rb_name_err_raise(
"implicit parameter '%1$s' is not defined for %2$s", bindval,
ID2SYM(lid));
1356bind_implicit_parameter_defined_p(
VALUE bindval,
VALUE sym)
1358 ID lid = check_local_id(bindval, &sym);
1362 if (lid == idIt) lid = idItImplicit;
1364 if (!lid || !rb_implicit_param_p(lid)) {
1365 rb_name_err_raise(
"'%1$s' is not an implicit parameter",
1369 GetBindingPtr(bindval, bind);
1370 env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
1371 return RBOOL(get_local_variable_ptr(&env, lid, FALSE));
1381bind_receiver(
VALUE bindval)
1384 GetBindingPtr(bindval, bind);
1385 return vm_block_self(&bind->block);
1395bind_location(
VALUE bindval)
1399 GetBindingPtr(bindval, bind);
1400 loc[0] = pathobj_path(bind->pathobj);
1401 loc[1] =
INT2FIX(bind->first_lineno);
1414 proc = &sproc->basic;
1415 vm_block_type_set(&proc->block, block_type_ifunc);
1417 *(
VALUE **)&proc->block.as.captured.ep = ep = sproc->env + VM_ENV_DATA_SIZE-1;
1418 ep[VM_ENV_DATA_INDEX_FLAGS] = VM_FRAME_MAGIC_IFUNC | VM_FRAME_FLAG_CFRAME | VM_ENV_FLAG_LOCAL | VM_ENV_FLAG_ESCAPED;
1419 ep[VM_ENV_DATA_INDEX_ME_CREF] =
Qfalse;
1420 ep[VM_ENV_DATA_INDEX_SPECVAL] = VM_BLOCK_HANDLER_NONE;
1421 ep[VM_ENV_DATA_INDEX_ENV] =
Qundef;
1424 RB_OBJ_WRITE(procval, &proc->block.as.captured.code.ifunc, ifunc);
1425 proc->header.is_lambda = TRUE;
1430rb_func_proc_dup(
VALUE src_obj)
1432 RUBY_ASSERT(rb_typeddata_is_instance_of(src_obj, &proc_data_type));
1435 GetProcPtr(src_obj, src_proc);
1436 RUBY_ASSERT(vm_block_type(&src_proc->block) == block_type_ifunc);
1441 memcpy(&proc->basic, src_proc,
sizeof(
rb_proc_t));
1445 const VALUE *src_ep = src_proc->block.as.captured.ep;
1446 if (src_ep == ((
const cfunc_proc_t *)src_proc)->env + VM_ENV_DATA_SIZE - 1) {
1447 VALUE *ep = *(
VALUE **)&proc->basic.block.as.captured.ep = proc->env + VM_ENV_DATA_SIZE - 1;
1448 ep[VM_ENV_DATA_INDEX_FLAGS] = src_ep[VM_ENV_DATA_INDEX_FLAGS];
1449 ep[VM_ENV_DATA_INDEX_ME_CREF] = src_ep[VM_ENV_DATA_INDEX_ME_CREF];
1450 ep[VM_ENV_DATA_INDEX_SPECVAL] = src_ep[VM_ENV_DATA_INDEX_SPECVAL];
1451 RB_OBJ_WRITE(proc_obj, &ep[VM_ENV_DATA_INDEX_ENV], src_ep[VM_ENV_DATA_INDEX_ENV]);
1454 rb_vm_block_ep_update(proc_obj, &proc->basic.block, src_ep);
1463 VALUE procval = rb_proc_alloc(klass, block_type_symbol);
1465 GetProcPtr(procval, proc);
1467 vm_block_type_set(&proc->block, block_type_symbol);
1468 proc->header.is_lambda = TRUE;
1478 min_argc >= (
int)(1U << (
SIZEOF_VALUE * CHAR_BIT) / 2) ||
1481 rb_raise(
rb_eRangeError,
"minimum argument number out of range: %d",
1486 max_argc >= (
int)(1U << (
SIZEOF_VALUE * CHAR_BIT) / 2) ||
1489 rb_raise(
rb_eRangeError,
"maximum argument number out of range: %d",
1494 struct vm_ifunc *ifunc = IMEMO_NEW(
struct vm_ifunc, imemo_ifunc, (
VALUE)rb_vm_svar_lep(ec, ec->cfp));
1496 rb_gc_register_pinning_obj((
VALUE)ifunc);
1500 ifunc->argc.min = min_argc;
1501 ifunc->argc.max = max_argc;
1509 struct vm_ifunc *ifunc = rb_vm_ifunc_new(func, (
void *)val, min_argc, max_argc);
1513static const char proc_without_block[] =
"tried to create Proc object without a block";
1516proc_new(
VALUE klass, int8_t is_lambda)
1521 VALUE block_handler;
1523 if ((block_handler = rb_vm_frame_block_handler(cfp)) == VM_BLOCK_HANDLER_NONE) {
1524 rb_raise(rb_eArgError, proc_without_block);
1528 switch (vm_block_handler_type(block_handler)) {
1529 case block_handler_type_proc:
1530 procval = VM_BH_TO_PROC(block_handler);
1536 VALUE newprocval = rb_proc_dup(procval);
1537 RBASIC_SET_CLASS(newprocval, klass);
1542 case block_handler_type_symbol:
1544 sym_proc_new(klass, VM_BH_TO_SYMBOL(block_handler)) :
1545 rb_sym_to_proc(VM_BH_TO_SYMBOL(block_handler));
1548 case block_handler_type_ifunc:
1549 case block_handler_type_iseq:
1550 return rb_vm_make_proc_lambda(ec, VM_BH_TO_CAPT_BLOCK(block_handler), klass, is_lambda);
1552 VM_UNREACHABLE(proc_new);
1571rb_proc_s_new(
int argc,
VALUE *argv,
VALUE klass)
1573 VALUE block = proc_new(klass, FALSE);
1605f_lambda_filter_non_literal(
void)
1608 VALUE block_handler = rb_vm_frame_block_handler(cfp);
1610 if (block_handler == VM_BLOCK_HANDLER_NONE) {
1615 switch (vm_block_handler_type(block_handler)) {
1616 case block_handler_type_iseq:
1617 if (RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp)->ep == VM_BH_TO_ISEQ_BLOCK(block_handler)->ep) {
1621 case block_handler_type_symbol:
1623 case block_handler_type_proc:
1628 case block_handler_type_ifunc:
1632 rb_raise(rb_eArgError,
"the lambda method requires a literal block");
1646 f_lambda_filter_non_literal();
1701proc_call(
int argc,
VALUE *argv,
VALUE procval)
1707#if SIZEOF_LONG > SIZEOF_INT
1709check_argc(
long argc)
1711 if (argc > INT_MAX || argc < 0) {
1712 rb_raise(rb_eArgError,
"too many arguments (%lu)",
1713 (
unsigned long)argc);
1718#define check_argc(argc) (argc)
1733 GetProcPtr(self, proc);
1734 vret = rb_vm_invoke_proc(GET_EC(), proc, argc, argv,
1735 kw_splat, VM_BLOCK_HANDLER_NONE,
1736 rb_proc_refinements_cref_for_call(self));
1749proc_to_block_handler(
VALUE procval)
1751 return NIL_P(procval) ? VM_BLOCK_HANDLER_NONE : procval;
1760 GetProcPtr(self, proc);
1761 vret = rb_vm_invoke_proc(ec, proc, argc, argv, kw_splat, proc_to_block_handler(passed_procval),
1762 rb_proc_refinements_cref_for_call(self));
1816proc_arity(
VALUE self)
1823rb_iseq_min_max_arity(
const rb_iseq_t *iseq,
int *max)
1825 *max = ISEQ_BODY(iseq)->param.flags.has_rest == FALSE ?
1826 ISEQ_BODY(iseq)->param.lead_num + ISEQ_BODY(iseq)->param.opt_num + ISEQ_BODY(iseq)->param.post_num +
1827 (ISEQ_BODY(iseq)->param.flags.has_kw == TRUE || ISEQ_BODY(iseq)->param.flags.has_kwrest == TRUE || ISEQ_BODY(iseq)->param.flags.forwardable == TRUE)
1829 return ISEQ_BODY(iseq)->param.lead_num + ISEQ_BODY(iseq)->param.post_num + (ISEQ_BODY(iseq)->param.flags.has_kw && ISEQ_BODY(iseq)->param.keyword->required_num > 0);
1833rb_vm_block_min_max_arity(
const struct rb_block *block,
int *max)
1836 switch (vm_block_type(block)) {
1837 case block_type_iseq:
1838 return rb_iseq_min_max_arity(rb_iseq_check(block->as.captured.code.iseq), max);
1839 case block_type_proc:
1840 block = vm_proc_block(block->as.proc);
1842 case block_type_ifunc:
1844 const struct vm_ifunc *ifunc = block->as.captured.code.ifunc;
1845 if (IS_METHOD_PROC_IFUNC(ifunc)) {
1847 return method_min_max_arity((
VALUE)ifunc->data, max);
1849 *max = ifunc->argc.max;
1850 return ifunc->argc.min;
1852 case block_type_symbol:
1867rb_proc_min_max_arity(
VALUE self,
int *max)
1870 GetProcPtr(self, proc);
1871 return rb_vm_block_min_max_arity(&proc->block, max);
1879 GetProcPtr(self, proc);
1880 min = rb_vm_block_min_max_arity(&proc->block, &max);
1887 switch (vm_block_handler_type(block_handler)) {
1888 case block_handler_type_iseq:
1889 block->type = block_type_iseq;
1890 block->as.captured = *VM_BH_TO_ISEQ_BLOCK(block_handler);
1892 case block_handler_type_ifunc:
1893 block->type = block_type_ifunc;
1894 block->as.captured = *VM_BH_TO_IFUNC_BLOCK(block_handler);
1896 case block_handler_type_symbol:
1897 block->type = block_type_symbol;
1898 block->as.symbol = VM_BH_TO_SYMBOL(block_handler);
1900 case block_handler_type_proc:
1901 block->type = block_type_proc;
1902 block->as.proc = VM_BH_TO_PROC(block_handler);
1907rb_block_pair_yield_optimizable(
void)
1912 VALUE block_handler = rb_vm_frame_block_handler(cfp);
1915 if (block_handler == VM_BLOCK_HANDLER_NONE) {
1916 rb_raise(rb_eArgError,
"no block given");
1919 block_setup(&block, block_handler);
1920 min = rb_vm_block_min_max_arity(&block, &max);
1922 switch (vm_block_type(&block)) {
1923 case block_type_symbol:
1926 case block_type_proc:
1928 VALUE procval = block_handler;
1930 GetProcPtr(procval, proc);
1931 if (proc->header.is_lambda)
return 0;
1932 if (min != max)
return 0;
1936 case block_type_ifunc:
1938 const struct vm_ifunc *ifunc = block.as.captured.code.ifunc;
1939 if (ifunc->flags & IFUNC_YIELD_OPTIMIZABLE)
return 1;
1953 VALUE block_handler = rb_vm_frame_block_handler(cfp);
1956 if (block_handler == VM_BLOCK_HANDLER_NONE) {
1957 rb_raise(rb_eArgError,
"no block given");
1960 block_setup(&block, block_handler);
1962 switch (vm_block_type(&block)) {
1963 case block_type_symbol:
1966 case block_type_proc:
1970 min = rb_vm_block_min_max_arity(&block, &max);
1976rb_block_min_max_arity(
int *max)
1980 VALUE block_handler = rb_vm_frame_block_handler(cfp);
1983 if (block_handler == VM_BLOCK_HANDLER_NONE) {
1984 rb_raise(rb_eArgError,
"no block given");
1987 block_setup(&block, block_handler);
1988 return rb_vm_block_min_max_arity(&block, max);
1992rb_proc_get_iseq(
VALUE self,
int *is_proc)
1997 GetProcPtr(self, proc);
1998 block = &proc->block;
1999 if (is_proc) *is_proc = !proc->header.is_lambda;
2001 switch (vm_block_type(block)) {
2002 case block_type_iseq:
2003 return rb_iseq_check(block->as.captured.code.iseq);
2004 case block_type_proc:
2005 return rb_proc_get_iseq(block->as.proc, is_proc);
2006 case block_type_ifunc:
2008 const struct vm_ifunc *ifunc = block->as.captured.code.ifunc;
2009 if (IS_METHOD_PROC_IFUNC(ifunc)) {
2011 if (is_proc) *is_proc = 0;
2012 return rb_method_iseq((
VALUE)ifunc->data);
2018 case block_type_symbol:
2022 VM_UNREACHABLE(rb_proc_get_iseq);
2055 const rb_proc_t *self_proc, *other_proc;
2056 const struct rb_block *self_block, *other_block;
2062 GetProcPtr(self, self_proc);
2063 GetProcPtr(other, other_proc);
2065 if (self_proc->header.is_from_method != other_proc->header.is_from_method ||
2066 self_proc->header.is_lambda != other_proc->header.is_lambda ||
2067 self_proc->header.is_refined != other_proc->header.is_refined) {
2071 self_block = &self_proc->block;
2072 other_block = &other_proc->block;
2074 if (vm_block_type(self_block) != vm_block_type(other_block)) {
2078 switch (vm_block_type(self_block)) {
2079 case block_type_iseq:
2080 if (self_block->as.captured.ep != \
2081 other_block->as.captured.ep) {
2086 if (self_proc->header.is_refined) {
2087 if (!refinement_recipe_eq(rb_proc_refinements_recipe(self),
2088 rb_proc_refinements_recipe(other))) {
2092 else if (self_block->as.captured.code.iseq != \
2093 other_block->as.captured.code.iseq) {
2097 case block_type_ifunc:
2098 if (self_block->as.captured.code.ifunc != \
2099 other_block->as.captured.code.ifunc) {
2110 case block_type_proc:
2111 if (self_block->as.proc != other_block->as.proc) {
2115 case block_type_symbol:
2116 if (self_block->as.symbol != other_block->as.symbol) {
2130 if (!iseq)
return Qnil;
2131 rb_iseq_check(iseq);
2132 loc[0] = rb_iseq_path(iseq);
2133 loc[1] =
RB_INT2NUM(ISEQ_BODY(iseq)->location.first_lineno);
2141 return iseq_location(iseq);
2153rb_proc_location(
VALUE self)
2155 return iseq_location(rb_proc_get_iseq(self, 0));
2172rb_proc_source_range(
VALUE self)
2174 return source_range_new(rb_proc_get_iseq(self, 0));
2178rb_unnamed_parameters(
int arity)
2181 int n = (arity < 0) ? ~arity : arity;
2215rb_proc_parameters(
int argc,
VALUE *argv,
VALUE self)
2217 static ID keyword_ids[1];
2223 iseq = rb_proc_get_iseq(self, &is_proc);
2225 if (!keyword_ids[0]) {
2226 CONST_ID(keyword_ids[0],
"lambda");
2233 if (!
NIL_P(lambda)) {
2234 is_proc = !
RTEST(lambda);
2241 return rb_iseq_parameters(iseq, is_proc);
2245iseq_location_hash(st_index_t hash,
const rb_iseq_t *iseq)
2250 hash = rb_st_hash_uint(hash, (st_index_t)loc->code_location.beg_pos.lineno);
2251 hash = rb_st_hash_uint(hash, (st_index_t)loc->code_location.beg_pos.column);
2252 hash = rb_st_hash_uint(hash, (st_index_t)loc->code_location.end_pos.lineno);
2253 hash = rb_st_hash_uint(hash, (st_index_t)loc->code_location.end_pos.column);
2259rb_hash_proc(st_index_t hash,
VALUE prc)
2262 GetProcPtr(prc, proc);
2264 switch (vm_block_type(&proc->block)) {
2265 case block_type_iseq:
2266 if (proc->header.is_refined) {
2269 VALUE recipe = rb_proc_refinements_recipe(prc);
2271 hash = rb_st_hash_uint(hash, (st_index_t)
RARRAY_AREF(recipe, REFINEMENT_RECIPE_BASE_CREF));
2272 hash = iseq_location_hash(hash, (
const rb_iseq_t *)
RARRAY_AREF(recipe, REFINEMENT_RECIPE_SRC_ISEQ));
2273 for (
long i = REFINEMENT_RECIPE_MODS; i <
len; i++) {
2274 hash = rb_st_hash_uint(hash, (st_index_t)
RARRAY_AREF(recipe, i));
2278 hash = iseq_location_hash(hash, proc->block.as.captured.code.iseq);
2281 case block_type_ifunc:
2282 hash = rb_st_hash_uint(hash, (st_index_t)proc->block.as.captured.code.ifunc->func);
2283 hash = rb_st_hash_uint(hash, (st_index_t)proc->block.as.captured.code.ifunc->data);
2285 case block_type_symbol:
2286 hash = rb_st_hash_uint(hash, rb_any_hash(proc->block.as.symbol));
2288 case block_type_proc:
2289 hash = rb_st_hash_uint(hash, rb_any_hash(proc->block.as.proc));
2292 rb_bug(
"rb_hash_proc: unknown block type %d", vm_block_type(&proc->block));
2299 if (vm_block_type(&proc->block) == block_type_iseq) {
2300 hash =
rb_hash_uint(hash, (st_index_t)proc->block.as.captured.ep);
2323rb_sym_to_proc(
VALUE sym)
2325 enum {SYM_PROC_CACHE_SIZE = 67};
2327 if (rb_ractor_main_p()) {
2328 if (!sym_proc_cache) {
2334 long index = (
id % SYM_PROC_CACHE_SIZE);
2336 if (
RTEST(procval)) {
2338 GetProcPtr(procval, proc);
2340 if (proc->block.as.symbol == sym) {
2345 procval = sym_proc_new(
rb_cProc, sym);
2351 return sym_proc_new(
rb_cProc, sym);
2365proc_hash(
VALUE self)
2369 hash = rb_hash_proc(hash, self);
2375rb_block_to_s(
VALUE self,
const struct rb_block *block,
const char *additional_info)
2378 VALUE str = rb_sprintf(
"#<%"PRIsVALUE
":", cname);
2381 switch (vm_block_type(block)) {
2382 case block_type_proc:
2383 block = vm_proc_block(block->as.proc);
2385 case block_type_iseq:
2387 const rb_iseq_t *iseq = rb_iseq_check(block->as.captured.code.iseq);
2388 rb_str_catf(str,
"%p %"PRIsVALUE
":%d", (
void *)self,
2390 ISEQ_BODY(iseq)->location.first_lineno);
2393 case block_type_symbol:
2394 rb_str_catf(str,
"%p(&%+"PRIsVALUE
")", (
void *)self, block->as.symbol);
2396 case block_type_ifunc:
2397 rb_str_catf(str,
"%p", (
void *)block->as.captured.code.ifunc);
2415proc_to_s(
VALUE self)
2418 GetProcPtr(self, proc);
2419 return rb_block_to_s(self, &proc->block, proc->header.is_lambda ?
" (lambda)" : NULL);
2431proc_to_proc(
VALUE self)
2437bm_mark_and_move(
void *ptr)
2439 struct METHOD *data = ptr;
2440 rb_gc_mark_and_move((
VALUE *)&data->recv);
2441 rb_gc_mark_and_move((
VALUE *)&data->klass);
2442 rb_gc_mark_and_move((
VALUE *)&data->iclass);
2443 rb_gc_mark_and_move((
VALUE *)&data->owner);
2455 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE | RUBY_TYPED_FROZEN_SHAREABLE_NO_REC
2461 return RBOOL(rb_typeddata_is_kind_of(m, &method_data_type));
2468 ID rmiss = idRespond_to_missing;
2470 if (UNDEF_P(obj))
return 0;
2489 def->type = VM_METHOD_TYPE_MISSING;
2490 def->original_id = id;
2492 me = rb_method_entry_create(
id, klass, METHOD_VISI_UNDEF, def);
2504 if (!respond_to_missing_p(klass, obj, vid, scope))
return Qfalse;
2505 return mnew_missing(klass, obj,
SYM2ID(vid), mclass);
2517 rb_method_visibility_t visi = METHOD_VISI_UNDEF;
2520 if (UNDEFINED_METHOD_ENTRY_P(me)) {
2521 if (respond_to_missing_p(klass, obj,
ID2SYM(
id), scope)) {
2522 return mnew_missing(klass, obj,
id, mclass);
2524 if (!error)
return Qnil;
2525 rb_print_undef(klass,
id, METHOD_VISI_UNDEF);
2527 if (visi == METHOD_VISI_UNDEF) {
2528 visi = METHOD_ENTRY_VISI(me);
2530 if (scope && (visi != METHOD_VISI_PUBLIC)) {
2531 if (!error)
return Qnil;
2532 rb_print_inaccessible(klass,
id, visi);
2535 if (me->def->type == VM_METHOD_TYPE_ZSUPER ||
2536 (me->def->type == VM_METHOD_TYPE_CFUNC && me->def->body.cfunc.func == (rb_cfunc_t)rb_zsuper_to_super)) {
2537 if (me->def->type == VM_METHOD_TYPE_ZSUPER && me->defined_class) {
2539 id = me->def->original_id;
2540 me = (
rb_method_entry_t *)rb_callable_method_entry_with_refinements(klass,
id, &iclass);
2544 id = me->def->original_id;
2545 me = rb_method_entry_without_refinements(klass,
id, &iclass);
2561 RB_OBJ_WRITE(method, &data->owner, original_me->owner);
2571 return mnew_internal(me, klass, iclass, obj,
id, mclass, scope, TRUE);
2581 me = (
rb_method_entry_t *)rb_callable_method_entry_with_refinements(klass,
id, &iclass);
2582 return mnew_from_me(me, klass, iclass, obj,
id, mclass, scope);
2586mnew_unbound(
VALUE klass,
ID id,
VALUE mclass,
int scope)
2591 me = rb_method_entry_with_refinements(klass,
id, &iclass);
2592 return mnew_from_me(me, klass, iclass,
Qundef,
id, mclass, scope);
2598 VALUE defined_class = me->defined_class;
2599 return defined_class ? defined_class : me->owner;
2643 VALUE klass1, klass2;
2651 m1 = (
struct METHOD *)RTYPEDDATA_GET_DATA(method);
2652 m2 = (
struct METHOD *)RTYPEDDATA_GET_DATA(other);
2654 klass1 = method_entry_defined_class(m1->me);
2655 klass2 = method_entry_defined_class(m2->me);
2659 if (!rb_method_entry_eq(m1->me, m2->me) ||
2661 m1->klass != m2->klass ||
2662 m1->recv != m2->recv) {
2683#define unbound_method_eq method_eq
2695method_hash(
VALUE method)
2702 hash = rb_hash_method_entry(hash, m->me);
2718method_unbind(
VALUE obj)
2721 struct METHOD *orig, *data;
2725 &method_data_type, data);
2730 RB_OBJ_WRITE(method, &data->me, rb_method_entry_clone(orig->me));
2745method_receiver(
VALUE obj)
2761method_name(
VALUE obj)
2766 return ID2SYM(data->me->called_id);
2783method_original_name(
VALUE obj)
2788 return ID2SYM(data->me->def->original_id);
2810method_owner(
VALUE obj)
2824method_box(
VALUE obj)
2830 box = data->me->def->box;
2831 if (!box)
return Qnil;
2832 if (box->box_object)
return box->box_object;
2833 rb_bug(
"Unexpected box on the method definition: %p", (
void*) box);
2840#define MSG(s) rb_fstring_lit("undefined method '%1$s' for"s" '%2$s'")
2844 if (RCLASS_SINGLETON_P(c)) {
2845 VALUE obj = RCLASS_ATTACHED_OBJECT(klass);
2862 rb_name_err_raise_str(s, c, str);
2874 VALUE m = mnew_missing_by_name(klass, obj, &vid, scope, mclass);
2876 rb_method_name_error(klass, vid);
2878 return mnew_callable(klass, obj,
id, mclass, scope);
2923 return obj_method(obj, vid, FALSE);
2936 return obj_method(obj, vid, TRUE);
2940rb_obj_singleton_method_lookup(
VALUE arg)
2947rb_obj_singleton_method_lookup_fail(
VALUE arg1,
VALUE arg2)
2984 NIL_P(klass = RCLASS_ORIGIN(sc)) ||
2985 !
NIL_P(rb_special_singleton_class(obj))) {
2994 VALUE args[2] = {obj, vid};
2995 VALUE ruby_method =
rb_rescue(rb_obj_singleton_method_lookup, (
VALUE)args, rb_obj_singleton_method_lookup_fail,
Qfalse);
2997 struct METHOD *method = (
struct METHOD *)RTYPEDDATA_GET_DATA(ruby_method);
3000 VALUE method_class = method->iclass;
3004 if (lookup_class == method_class) {
3008 }
while (lookup_class && lookup_class != stop_class);
3014 rb_name_err_raise(
"undefined singleton method '%1$s' for '%2$s'",
3055 rb_method_name_error(mod, vid);
3068rb_mod_public_instance_method(
VALUE mod,
VALUE vid)
3072 rb_method_name_error(mod, vid);
3083 int is_method = FALSE;
3102 "wrong argument type %s (expected Proc/Method/UnboundMethod)",
3109 struct METHOD *method = (
struct METHOD *)RTYPEDDATA_GET_DATA(body);
3112 if (RCLASS_SINGLETON_P(method->me->owner)) {
3114 "can't bind singleton method to a different class");
3118 "bind argument must be a subclass of % "PRIsVALUE,
3122 rb_method_entry_set(mod,
id, method->me, scope_visi->method_visi);
3123 if (scope_visi->module_func) {
3130 GetProcPtr(body, body_proc);
3133 if (body_proc->header.is_refined) {
3134 rb_raise(rb_eArgError,
3135 "can't define a method from a Proc with refinements");
3137 VALUE procval = rb_proc_dup(body);
3138 if (vm_proc_iseq(procval) != NULL) {
3140 GetProcPtr(procval, proc);
3141 proc->header.is_lambda = TRUE;
3142 proc->header.is_from_method = TRUE;
3144 rb_add_method(mod,
id, VM_METHOD_TYPE_BMETHOD, (
void *)procval, scope_visi->method_visi);
3145 if (scope_visi->module_func) {
3146 rb_add_method(
rb_singleton_class(mod),
id, VM_METHOD_TYPE_BMETHOD, (
void *)body, METHOD_VISI_PUBLIC);
3194rb_mod_define_method(
int argc,
VALUE *argv,
VALUE mod)
3196 const rb_cref_t *cref = rb_vm_cref_in_context(mod, mod);
3201 scope_visi = CREF_SCOPE_VISI(cref);
3204 return rb_mod_define_method_with_visibility(argc, argv, mod, scope_visi);
3239rb_obj_define_method(
int argc,
VALUE *argv,
VALUE obj)
3244 return rb_mod_define_method_with_visibility(argc, argv, klass, &scope_visi);
3255top_define_method(
int argc,
VALUE *argv,
VALUE obj)
3257 return rb_mod_define_method(argc, argv, rb_top_main_class(
"define_method"));
3278method_clone(
VALUE self)
3281 struct METHOD *orig, *data;
3285 rb_obj_clone_setup(self, clone,
Qnil);
3290 RB_OBJ_WRITE(clone, &data->me, rb_method_entry_clone(orig->me));
3296method_dup(
VALUE self)
3299 struct METHOD *orig, *data;
3303 rb_obj_dup_setup(self, clone);
3308 RB_OBJ_WRITE(clone, &data->me, rb_method_entry_clone(orig->me));
3337rb_method_call_pass_called_kw(
int argc,
const VALUE *argv,
VALUE method)
3357method_callable_method_entry(
const struct METHOD *data)
3359 if (data->me->defined_class == 0) rb_bug(
"method_callable_method_entry: not callable.");
3365 int argc,
const VALUE *argv,
VALUE passed_procval,
int kw_splat)
3367 vm_passed_block_handler_set(ec, proc_to_block_handler(passed_procval));
3368 return rb_vm_call_kw(ec, data->recv, data->me->called_id, argc, argv,
3369 method_callable_method_entry(data), kw_splat);
3375 const struct METHOD *data;
3379 if (UNDEF_P(data->recv)) {
3380 rb_raise(
rb_eTypeError,
"can't call unbound method; bind first");
3382 return call_method_data(ec, data, argc, argv, passed_procval, kw_splat);
3449 VALUE methclass = data->owner;
3450 VALUE iclass = data->me->defined_class;
3454 VALUE refined_class = rb_refinement_module_get_refined_class(methclass);
3455 if (!
NIL_P(refined_class)) methclass = refined_class;
3458 if (RCLASS_SINGLETON_P(methclass)) {
3460 "singleton method called for a different object");
3463 rb_raise(
rb_eTypeError,
"bind argument must be an instance of % "PRIsVALUE,
3470 me = rb_method_entry_clone(data->me);
3480 me = rb_method_entry_clone(me);
3482 VALUE ic = rb_class_search_ancestor(klass, me->owner);
3488 klass = rb_include_class_new(methclass, klass);
3490 me = (
const rb_method_entry_t *) rb_method_entry_complement_defined_class(me, me->called_id, klass);
3493 *methclass_out = methclass;
3495 *iclass_out = iclass;
3537 VALUE methclass, klass, iclass;
3539 const struct METHOD *data;
3541 convert_umethod_to_method_components(data, recv, &methclass, &klass, &iclass, &me,
true);
3563umethod_bind_call(
int argc,
VALUE *argv,
VALUE method)
3566 VALUE recv = argv[0];
3573 const struct METHOD *data;
3578 vm_passed_block_handler_set(ec, proc_to_block_handler(passed_procval));
3582 VALUE methclass, klass, iclass;
3584 convert_umethod_to_method_components(data, recv, &methclass, &klass, &iclass, &me,
false);
3585 struct METHOD bound = { recv, klass, 0, methclass, me };
3600 if (!def)
return *max = 0;
3601 switch (def->type) {
3602 case VM_METHOD_TYPE_CFUNC:
3603 if (def->body.cfunc.argc < 0) {
3607 return *max = check_argc(def->body.cfunc.argc);
3608 case VM_METHOD_TYPE_ZSUPER:
3611 case VM_METHOD_TYPE_ATTRSET:
3613 case VM_METHOD_TYPE_IVAR:
3615 case VM_METHOD_TYPE_ALIAS:
3616 def = def->body.alias.original_me->def;
3618 case VM_METHOD_TYPE_BMETHOD:
3619 return rb_proc_min_max_arity(def->body.bmethod.proc, max);
3620 case VM_METHOD_TYPE_ISEQ:
3621 return rb_iseq_min_max_arity(rb_iseq_check(def->body.iseq.
iseqptr), max);
3622 case VM_METHOD_TYPE_UNDEF:
3623 case VM_METHOD_TYPE_NOTIMPLEMENTED:
3625 case VM_METHOD_TYPE_MISSING:
3628 case VM_METHOD_TYPE_OPTIMIZED: {
3629 switch (def->body.optimized.type) {
3630 case OPTIMIZED_METHOD_TYPE_SEND:
3633 case OPTIMIZED_METHOD_TYPE_CALL:
3636 case OPTIMIZED_METHOD_TYPE_BLOCK_CALL:
3639 case OPTIMIZED_METHOD_TYPE_STRUCT_AREF:
3642 case OPTIMIZED_METHOD_TYPE_STRUCT_ASET:
3650 case VM_METHOD_TYPE_REFINED:
3654 rb_bug(
"method_def_min_max_arity: invalid method entry type (%d)", def->type);
3661 int max, min = method_def_min_max_arity(def, &max);
3662 return min == max ? min : -min-1;
3668 return method_def_arity(me->def);
3715method_arity_m(
VALUE method)
3717 int n = method_arity(method);
3722method_arity(
VALUE method)
3727 return rb_method_entry_arity(data->me);
3731original_method_entry(
VALUE mod,
ID id)
3735 while ((me = rb_method_entry(mod,
id)) != 0) {
3738 if (def->type != VM_METHOD_TYPE_ZSUPER &&
3739 (def->type != VM_METHOD_TYPE_CFUNC ||
3740 def->body.cfunc.func != (rb_cfunc_t)rb_zsuper_to_super))
break;
3743 id = def->original_id;
3749method_min_max_arity(
VALUE method,
int *max)
3751 const struct METHOD *data;
3754 return method_def_min_max_arity(data->me->def, max);
3762 return rb_method_entry_arity(me);
3772rb_callable_receiver(
VALUE callable)
3775 VALUE binding = proc_binding(callable);
3776 return rb_funcall(binding, rb_intern(
"receiver"), 0);
3779 return method_receiver(callable);
3787rb_method_def(
VALUE method)
3789 const struct METHOD *data;
3792 return data->me->def;
3798 switch (def->type) {
3799 case VM_METHOD_TYPE_ISEQ:
3800 return rb_iseq_check(def->body.iseq.
iseqptr);
3801 case VM_METHOD_TYPE_BMETHOD:
3802 return rb_proc_get_iseq(def->body.bmethod.proc, 0);
3803 case VM_METHOD_TYPE_ALIAS:
3804 return method_def_iseq(def->body.alias.original_me->def);
3805 case VM_METHOD_TYPE_CFUNC:
3806 case VM_METHOD_TYPE_ATTRSET:
3807 case VM_METHOD_TYPE_IVAR:
3808 case VM_METHOD_TYPE_ZSUPER:
3809 case VM_METHOD_TYPE_UNDEF:
3810 case VM_METHOD_TYPE_NOTIMPLEMENTED:
3811 case VM_METHOD_TYPE_OPTIMIZED:
3812 case VM_METHOD_TYPE_MISSING:
3813 case VM_METHOD_TYPE_REFINED:
3820rb_method_iseq(
VALUE method)
3822 return method_def_iseq(rb_method_def(method));
3826method_cref(
VALUE method)
3831 switch (def->type) {
3832 case VM_METHOD_TYPE_ISEQ:
3833 return def->body.iseq.
cref;
3834 case VM_METHOD_TYPE_ALIAS:
3835 def = def->body.alias.original_me->def;
3845 if (def->type == VM_METHOD_TYPE_ATTRSET || def->type == VM_METHOD_TYPE_IVAR) {
3846 if (!def->body.attr.location)
3850 return iseq_location(method_def_iseq(def));
3856 if (!me)
return Qnil;
3857 return method_def_location(me->def);
3877rb_method_location(
VALUE method)
3879 return method_def_location(rb_method_def(method));
3885 return source_range_new(method_def_iseq(def));
3902rb_method_source_range(
VALUE method)
3904 return method_def_source_range(rb_method_def(method));
3908vm_proc_method_def(
VALUE procval)
3914 GetProcPtr(procval, proc);
3915 block = &proc->block;
3917 if (vm_block_type(block) == block_type_ifunc &&
3918 IS_METHOD_PROC_IFUNC(ifunc = block->as.captured.code.ifunc)) {
3919 return rb_method_def((
VALUE)ifunc->data);
3932 switch (def->type) {
3933 case VM_METHOD_TYPE_ISEQ:
3934 iseq = method_def_iseq(def);
3935 return rb_iseq_parameters(iseq, 0);
3936 case VM_METHOD_TYPE_BMETHOD:
3937 if ((iseq = method_def_iseq(def)) != NULL) {
3938 return rb_iseq_parameters(iseq, 0);
3940 else if ((bmethod_def = vm_proc_method_def(def->body.bmethod.proc)) != NULL) {
3941 return method_def_parameters(bmethod_def);
3945 case VM_METHOD_TYPE_ALIAS:
3946 return method_def_parameters(def->body.alias.original_me->def);
3948 case VM_METHOD_TYPE_OPTIMIZED:
3949 if (def->body.optimized.type == OPTIMIZED_METHOD_TYPE_STRUCT_ASET) {
3950 VALUE param = rb_ary_new_from_args(2,
ID2SYM(rb_intern(
"req")),
ID2SYM(rb_intern(
"_")));
3951 return rb_ary_new_from_args(1, param);
3955 case VM_METHOD_TYPE_CFUNC:
3956 case VM_METHOD_TYPE_ATTRSET:
3957 case VM_METHOD_TYPE_IVAR:
3958 case VM_METHOD_TYPE_ZSUPER:
3959 case VM_METHOD_TYPE_UNDEF:
3960 case VM_METHOD_TYPE_NOTIMPLEMENTED:
3961 case VM_METHOD_TYPE_MISSING:
3962 case VM_METHOD_TYPE_REFINED:
3966 return rb_unnamed_parameters(method_def_arity(def));
3990rb_method_parameters(
VALUE method)
3992 return method_def_parameters(rb_method_def(method));
3996append_param_name(
VALUE str,
VALUE name,
const char *unnamed)
4041method_inspect(
VALUE method)
4045 const char *sharp =
"#";
4047 VALUE defined_class;
4050 str = rb_sprintf(
"#<% "PRIsVALUE
": ",
rb_obj_class(method));
4052 mklass = data->iclass;
4053 if (!mklass) mklass = data->klass;
4063 if (data->me->def->type == VM_METHOD_TYPE_ALIAS) {
4064 defined_class = data->me->def->body.alias.original_me->owner;
4067 defined_class = method_entry_defined_class(data->me);
4074 if (UNDEF_P(data->recv)) {
4078 else if (RCLASS_SINGLETON_P(mklass)) {
4079 VALUE v = RCLASS_ATTACHED_OBJECT(mklass);
4081 if (UNDEF_P(data->recv)) {
4084 else if (data->recv == v) {
4097 mklass = data->klass;
4101 if (RCLASS_SINGLETON_P(mklass)) {
4102 VALUE v = RCLASS_ATTACHED_OBJECT(mklass);
4110 if (defined_class != mklass) {
4111 rb_str_catf(str,
"(% "PRIsVALUE
")", defined_class);
4116 if (data->me->called_id != data->me->def->original_id) {
4117 rb_str_catf(str,
"(%"PRIsVALUE
")",
4118 rb_id2str(data->me->def->original_id));
4120 if (data->me->def->type == VM_METHOD_TYPE_NOTIMPLEMENTED) {
4126 VALUE params = rb_method_parameters(method);
4127 VALUE pair, name, kind;
4133 const VALUE keyrest =
ID2SYM(rb_intern(
"keyrest"));
4136 const VALUE noblock =
ID2SYM(rb_intern(
"noblock"));
4151 for (
int i = 0; i <
RARRAY_LEN(params); i++) {
4162 append_param_name(str, name,
"_");
4164 else if (kind == opt) {
4167 else if (kind == keyreq) {
4170 else if (kind == key) {
4173 else if (kind == rest) {
4175 if (name !=
ID2SYM(
'*')) {
4176 append_param_name(str, name, NULL);
4179 else if (kind == keyrest) {
4180 if (name !=
ID2SYM(idPow)) {
4190 else if (kind == block) {
4191 if (name ==
ID2SYM(
'&')) {
4203 else if (kind == nokey) {
4206 else if (kind == noblock) {
4218 VALUE loc = rb_method_location(method);
4220 rb_str_catf(str,
" %"PRIsVALUE
":%"PRIsVALUE,
4253method_to_proc(
VALUE method)
4267 procval =
rb_block_call(rb_mRubyVMFrozenCore, idLambda, 0, 0, bmcall, method);
4268 GetProcPtr(procval, proc);
4269 proc->header.is_from_method = 1;
4273extern VALUE rb_find_defined_class_by_owner(
VALUE current_class,
VALUE target_owner);
4286method_super_method(
VALUE method)
4288 const struct METHOD *data;
4289 VALUE super_class, iclass;
4294 iclass = data->iclass;
4295 if (!iclass)
return Qnil;
4296 if (data->me->def->type == VM_METHOD_TYPE_ALIAS && data->me->defined_class) {
4297 super_class =
RCLASS_SUPER(rb_find_defined_class_by_owner(data->me->defined_class,
4298 data->me->def->body.alias.original_me->owner));
4299 mid = data->me->def->body.alias.original_me->def->original_id;
4302 VALUE klass = iclass;
4303 if (RICLASS_FOR_REFINEMENT_P(klass)) {
4305 klass =
RBASIC(klass)->klass;
4308 mid = data->me->def->original_id;
4310 if (!super_class)
return Qnil;
4320 switch (data->me->def->type) {
4321 case VM_METHOD_TYPE_ISEQ:
4322 cref = data->me->def->body.iseq.
cref;
4324 case VM_METHOD_TYPE_BMETHOD: {
4326 GetProcPtr(data->me->def->body.bmethod.proc, proc);
4327 const struct rb_block *block = &proc->block;
4328 if (vm_block_type(block) == block_type_iseq)
4329 cref = rb_vm_get_cref(block->as.captured.ep);
4335 VALUE klass = super_class;
4340 if (cme->def->type != VM_METHOD_TYPE_REFINED) {
4342 iclass = cme->defined_class;
4348 for (c = cref; c; c = CREF_NEXT(c)) {
4349 VALUE refs = CREF_REFINEMENTS(c);
4350 if (
NIL_P(refs))
continue;
4351 VALUE r = rb_hash_lookup(refs, cme->owner);
4352 if (
NIL_P(r))
continue;
4354 if (!ref_cme)
break;
4355 if (ref_cme->def->type == VM_METHOD_TYPE_REFINED)
continue;
4356 if (skip_def && rb_method_definition_eq(ref_cme->def, skip_def))
continue;
4358 iclass = ref_cme->defined_class;
4367 iclass = orig_me->defined_class ? orig_me->defined_class : cme->defined_class;
4372 if (!me)
return Qnil;
4373 return mnew_internal(me, me->owner, iclass, data->recv, mid,
rb_obj_class(method), FALSE, FALSE);
4383localjump_xvalue(
VALUE exc)
4397localjump_reason(
VALUE exc)
4402rb_cref_t *rb_vm_cref_new_toplevel(
void);
4411 VM_ASSERT(env->ep > env->env);
4412 VM_ASSERT(VM_ENV_ESCAPED_P(env->ep));
4415 cref = rb_vm_cref_new_toplevel();
4419 new_ep = &new_body[env->ep - env->env];
4420 new_env = vm_env_new(new_ep, new_body, env->env_size, env->iseq);
4427 new_ep[VM_ENV_DATA_INDEX_ENV] = (
VALUE)new_env;
4429 VM_ASSERT(VM_ENV_ESCAPED_P(new_ep));
4447proc_binding(
VALUE self)
4456 GetProcPtr(self, proc);
4457 block = &proc->block;
4459 if (proc->header.is_isolated) rb_raise(rb_eArgError,
"Can't create Binding from isolated Proc");
4462 switch (vm_block_type(block)) {
4463 case block_type_iseq:
4464 iseq = block->as.captured.code.iseq;
4465 binding_self = block->as.captured.self;
4466 env = VM_ENV_ENVVAL_PTR(block->as.captured.ep);
4468 case block_type_proc:
4469 GetProcPtr(block->as.proc, proc);
4470 block = &proc->block;
4472 case block_type_ifunc:
4474 const struct vm_ifunc *ifunc = block->as.captured.code.ifunc;
4475 if (IS_METHOD_PROC_IFUNC(ifunc)) {
4477 VALUE name = rb_fstring_lit(
"<empty_iseq>");
4479 binding_self = method_receiver(method);
4480 iseq = rb_method_iseq(method);
4481 env = VM_ENV_ENVVAL_PTR(block->as.captured.ep);
4482 env = env_clone(env, method_cref(method));
4484 empty = rb_iseq_new(
Qnil, name, name,
Qnil, 0, ISEQ_TYPE_TOP);
4490 case block_type_symbol:
4491 rb_raise(rb_eArgError,
"Can't create Binding from C level Proc");
4496 GetBindingPtr(bindval, bind);
4497 RB_OBJ_WRITE(bindval, &bind->block.as.captured.self, binding_self);
4498 RB_OBJ_WRITE(bindval, &bind->block.as.captured.code.iseq, env->iseq);
4499 rb_vm_block_ep_update(bindval, &bind->block, env->ep);
4503 rb_iseq_check(iseq);
4504 RB_OBJ_WRITE(bindval, &bind->pathobj, ISEQ_BODY(iseq)->location.pathobj);
4505 bind->first_lineno = ISEQ_BODY(iseq)->location.first_lineno;
4509 rb_iseq_pathobj_new(rb_fstring_lit(
"(binding)"),
Qnil));
4510 bind->first_lineno = 1;
4525 GetProcPtr(proc, procp);
4526 is_lambda = procp->header.is_lambda;
4530 GetProcPtr(proc, procp);
4531 procp->header.is_lambda = is_lambda;
4538 VALUE proc, passed, arity;
4547 if (!
NIL_P(blockarg)) {
4548 rb_warn(
"given block not used");
4550 arity = make_curry_proc(proc, passed, arity);
4613proc_curry(
int argc,
const VALUE *argv,
VALUE self)
4615 int sarity, max_arity, min_arity = rb_proc_min_max_arity(self, &max_arity);
4629 return make_curry_proc(self,
rb_ary_new(), arity);
4665rb_method_curry(
int argc,
const VALUE *argv,
VALUE self)
4667 VALUE proc = method_to_proc(self);
4668 return proc_curry(argc, argv, proc);
4697 mesg = rb_fstring_lit(
"callable object is expected");
4721 return rb_proc_compose_to_left(self, to_callable(g));
4727 VALUE proc, args, procs[2];
4733 args = rb_ary_tmp_new_from_values(0, 2, procs);
4736 GetProcPtr(g, procp);
4737 is_lambda = procp->header.is_lambda;
4745 GetProcPtr(proc, procp);
4746 procp->header.is_lambda = is_lambda;
4780 return rb_proc_compose_to_right(self, to_callable(g));
4786 VALUE proc, args, procs[2];
4792 args = rb_ary_tmp_new_from_values(0, 2, procs);
4794 GetProcPtr(self, procp);
4795 is_lambda = procp->header.is_lambda;
4798 GetProcPtr(proc, procp);
4799 procp->header.is_lambda = is_lambda;
4820rb_method_compose_to_left(
VALUE self,
VALUE g)
4823 self = method_to_proc(self);
4824 return proc_compose_to_left(self, g);
4843rb_method_compose_to_right(
VALUE self,
VALUE g)
4846 self = method_to_proc(self);
4847 return proc_compose_to_right(self, g);
4875proc_ruby2_keywords(
VALUE procval)
4878 GetProcPtr(procval, proc);
4880 rb_check_frozen(procval);
4882 if (proc->header.is_from_method) {
4883 rb_warn(
"Skipping set of ruby2_keywords flag for proc (proc created from method)");
4887 switch (proc->block.type) {
4888 case block_type_iseq:
4889 if (ISEQ_BODY(proc->block.as.captured.code.iseq)->param.flags.has_rest &&
4890 !ISEQ_BODY(proc->block.as.captured.code.iseq)->param.flags.has_post &&
4891 !ISEQ_BODY(proc->block.as.captured.code.iseq)->param.flags.has_kw &&
4892 !ISEQ_BODY(proc->block.as.captured.code.iseq)->param.flags.has_kwrest) {
4893 if (proc->header.is_refined) {
4898 rb_iseq_dup_with_independent_caches(proc->block.as.captured.code.iseq);
4899 ISEQ_BODY(copy)->param.flags.ruby2_keywords = 1;
4905 ISEQ_BODY(proc->block.as.captured.code.iseq)->param.flags.ruby2_keywords = 1;
4909 rb_warn(
"Skipping set of ruby2_keywords flag for proc (proc accepts keywords or post arguments or proc does not accept argument splat)");
4913 rb_warn(
"Skipping set of ruby2_keywords flag for proc (proc not defined in Ruby)");
5353 id_refinements_recipe = rb_make_internal_id();
5355 VALUE mRuby = rb_define_module(
"Ruby");
5358 rb_cSourceRange = rb_define_class_under(mRuby,
"SourceRange",
rb_cObject);
5362 rb_define_method(rb_cSourceRange,
"absolute_path", source_range_absolute_path, 0);
5363 rb_define_method(rb_cSourceRange,
"start_line", source_range_start_line, 0);
5364 rb_define_method(rb_cSourceRange,
"start_column", source_range_start_column, 0);
5366 rb_define_method(rb_cSourceRange,
"end_column", source_range_end_column, 0);
5374 rb_add_method_optimized(
rb_cProc, idCall, OPTIMIZED_METHOD_TYPE_CALL, 0, METHOD_VISI_PUBLIC);
5375 rb_add_method_optimized(
rb_cProc, rb_intern(
"[]"), OPTIMIZED_METHOD_TYPE_CALL, 0, METHOD_VISI_PUBLIC);
5376 rb_add_method_optimized(
rb_cProc, rb_intern(
"==="), OPTIMIZED_METHOD_TYPE_CALL, 0, METHOD_VISI_PUBLIC);
5377 rb_add_method_optimized(
rb_cProc, rb_intern(
"yield"), OPTIMIZED_METHOD_TYPE_CALL, 0, METHOD_VISI_PUBLIC);
5413 rb_vm_register_special_exception(ruby_error_sysstack,
rb_eSysStackError,
"stack level too deep");
5484 "define_method", top_define_method, -1);
5525 rb_gc_register_address(&sym_proc_cache);
#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.
VALUE rb_singleton_class(VALUE obj)
Finds or creates the singleton class of the passed object.
VALUE rb_singleton_class_get(VALUE obj)
Returns the singleton class of obj, or nil if obj is not a singleton object.
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
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_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 rb_str_buf_cat2
Old name of rb_usascii_str_new_cstr.
#define Qundef
Old name of RUBY_Qundef.
#define INT2FIX
Old name of RB_INT2FIX.
#define ID2SYM
Old name of RB_ID2SYM.
#define OBJ_FREEZE
Old name of RB_OBJ_FREEZE.
#define UNREACHABLE_RETURN
Old name of RBIMPL_UNREACHABLE_RETURN.
#define SYM2ID
Old name of RB_SYM2ID.
#define ZALLOC
Old name of RB_ZALLOC.
#define CLASS_OF
Old name of rb_class_of.
#define rb_ary_new4
Old name of rb_ary_new_from_values.
#define FIX2INT
Old name of RB_FIX2INT.
#define T_MODULE
Old name of RUBY_T_MODULE.
#define ASSUME
Old name of RBIMPL_ASSUME.
#define T_ICLASS
Old name of RUBY_T_ICLASS.
#define ALLOC_N
Old name of RB_ALLOC_N.
#define FL_TEST_RAW
Old name of RB_FL_TEST_RAW.
#define rb_ary_new3
Old name of rb_ary_new_from_args.
#define Qtrue
Old name of RUBY_Qtrue.
#define ST2FIX
Old name of RB_ST2FIX.
#define NUM2INT
Old name of RB_NUM2INT.
#define INT2NUM
Old name of RB_INT2NUM.
#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 BUILTIN_TYPE
Old name of RB_BUILTIN_TYPE.
#define Check_TypedStruct(v, t)
Old name of rb_check_typeddata.
#define CONST_ID
Old name of RUBY_CONST_ID.
#define rb_ary_new2
Old name of rb_ary_new_capa.
VALUE rb_eLocalJumpError
LocalJumpError exception.
void rb_category_warn(rb_warning_category_t category, const char *fmt,...)
Identical to rb_category_warning(), except it reports unless $VERBOSE is nil.
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
VALUE rb_eStandardError
StandardError exception.
VALUE rb_eRangeError
RangeError exception.
VALUE rb_eTypeError
TypeError exception.
void rb_warn(const char *fmt,...)
Identical to rb_warning(), except it reports unless $VERBOSE is nil.
VALUE rb_exc_new_str(VALUE etype, VALUE str)
Identical to rb_exc_new_cstr(), except it takes a Ruby's string instead of C's.
VALUE rb_eException
Mother of all exceptions.
VALUE rb_eSysStackError
SystemStackError exception.
@ RB_WARN_CATEGORY_PERFORMANCE
Warning is for performance issues (not enabled by -w).
VALUE rb_class_superclass(VALUE klass)
Queries the parent of the given class.
VALUE rb_cUnboundMethod
UnboundMethod class.
VALUE rb_mKernel
Kernel module.
VALUE rb_cObject
Object class.
VALUE rb_obj_hide(VALUE obj)
Make the object invisible from Ruby code.
VALUE rb_cBinding
Binding class.
VALUE rb_obj_class(VALUE obj)
Queries the class of an object.
VALUE rb_inspect(VALUE obj)
Generates a human-readable textual representation of the given object.
VALUE rb_cModule
Module class.
VALUE rb_class_inherited_p(VALUE scion, VALUE ascendant)
Determines if the given two modules are relatives.
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_cProc
Proc class.
VALUE rb_cMethod
Method class.
#define RB_OBJ_WRITTEN(old, oldv, young)
Identical to RB_OBJ_WRITE(), except it doesn't write any values, but only a WB declaration.
#define RB_OBJ_WRITE(old, slot, young)
Declaration of a "back" pointer.
VALUE rb_funcall(VALUE recv, ID mid, int n,...)
Calls a method.
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_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_ary_dup(VALUE ary)
Duplicates an array.
VALUE rb_ary_plus(VALUE lhs, VALUE rhs)
Creates a new array, concatenating the former to the latter.
VALUE rb_ary_new(void)
Allocates a new, empty array.
VALUE rb_ary_hidden_new(long capa)
Allocates a hidden (no class) 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_freeze(VALUE obj)
Freeze an array, preventing further modifications.
void rb_ary_store(VALUE ary, long key, VALUE val)
Destructively stores the passed value to the passed array's passed index.
#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.
VALUE rb_method_call_with_block(int argc, const VALUE *argv, VALUE recv, VALUE proc)
Identical to rb_proc_call(), except you can additionally pass a proc as a block.
int rb_obj_method_arity(VALUE obj, ID mid)
Identical to rb_mod_method_arity(), except it searches for singleton methods rather than instance met...
VALUE rb_proc_call(VALUE recv, VALUE args)
Evaluates the passed proc with the passed arguments.
VALUE rb_proc_call_with_block_kw(VALUE recv, int argc, const VALUE *argv, VALUE proc, int kw_splat)
Identical to rb_proc_call_with_block(), except you can specify how to handle the last element of the ...
VALUE rb_method_call_kw(int argc, const VALUE *argv, VALUE recv, int kw_splat)
Identical to rb_method_call(), except you can specify how to handle the last element of the given arr...
VALUE rb_obj_method(VALUE recv, VALUE mid)
Creates a method object.
VALUE rb_proc_lambda_p(VALUE recv)
Queries if the given object is a lambda.
VALUE rb_block_proc(void)
Constructs a Proc object from implicitly passed components.
VALUE rb_proc_call_with_block(VALUE recv, int argc, const VALUE *argv, VALUE proc)
Identical to rb_proc_call(), except you can additionally pass another proc object,...
int rb_mod_method_arity(VALUE mod, ID mid)
Queries the number of mandatory arguments of the method defined in the given module.
VALUE rb_method_call_with_block_kw(int argc, const VALUE *argv, VALUE recv, VALUE proc, int kw_splat)
Identical to rb_method_call_with_block(), except you can specify how to handle the last element of th...
VALUE rb_obj_is_method(VALUE recv)
Queries if the given object is a method.
VALUE rb_block_lambda(void)
Identical to rb_proc_new(), except it returns a lambda.
VALUE rb_proc_call_kw(VALUE recv, VALUE args, int kw_splat)
Identical to rb_proc_call(), except you can specify how to handle the last element of the given array...
VALUE rb_binding_new(void)
Snapshots the current execution context and turn it into an instance of rb_cBinding.
int rb_proc_arity(VALUE recv)
Queries the number of mandatory arguments of the given Proc.
VALUE rb_method_call(int argc, const VALUE *argv, VALUE recv)
Evaluates the passed method with the passed arguments.
VALUE rb_obj_is_proc(VALUE recv)
Queries if the given object is a proc.
#define rb_hash_uint(h, i)
Just another name of st_hash_uint.
#define rb_hash_end(h)
Just another name of st_hash_end.
VALUE rb_str_append(VALUE dst, VALUE src)
Identical to rb_str_buf_append(), except it converts the right hand side before concatenating.
VALUE rb_str_buf_append(VALUE dst, VALUE src)
Identical to rb_str_cat_cstr(), except it takes Ruby's string instead of C's.
void rb_str_set_len(VALUE str, long len)
Overwrites the length of the string.
st_index_t rb_hash_start(st_index_t i)
Starts a series of hashing.
#define rb_str_cat_cstr(buf, str)
Identical to rb_str_cat(), except it assumes the passed pointer is a pointer to a C string.
#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.
void rb_undef_alloc_func(VALUE klass)
Deletes the allocator function of a class.
int rb_method_basic_definition_p(VALUE klass, ID mid)
Well... Let us hesitate from describing what a "basic definition" is.
int rb_obj_respond_to(VALUE obj, ID mid, int private_p)
Identical to rb_respond_to(), except it additionally takes the visibility parameter.
ID rb_check_id(volatile VALUE *namep)
Detects if the given name is already interned or not.
VALUE rb_sym2str(VALUE symbol)
Obtain a frozen string representation of a symbol (not including the leading colon).
ID rb_to_id(VALUE str)
Identical to rb_intern_str(), except it tries to convert the parameter object to an instance of rb_cS...
VALUE rb_iv_get(VALUE obj, const char *name)
Obtains an instance variable.
int len
Length of the buffer.
#define RB_OBJ_SET_SHAREABLE(obj)
Wrapper of rb_obj_set_shareable().
#define RB_INT2NUM
Just another name of rb_int2num_inline.
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)
Shim for block function parameters.
rb_block_call_func * rb_block_call_func_t
Shorthand type that represents an iterator-written-in-C function pointer.
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.
#define MEMCPY(p1, p2, type, n)
Handy macro to call memcpy.
#define RB_GC_GUARD(v)
Prevents premature destruction of local objects.
VALUE rb_block_call(VALUE q, ID w, int e, const VALUE *r, type *t, VALUE y)
Call a method with a block.
VALUE rb_proc_new(type *q, VALUE w)
Creates a rb_cProc instance.
VALUE type(ANYARGS)
ANYARGS-ed function type.
VALUE rb_rescue(type *q, VALUE w, type *e, VALUE r)
An equivalent of rescue clause.
#define RARRAY_LEN
Just another name of rb_array_len.
static void RARRAY_ASET(VALUE ary, long i, VALUE v)
Assigns an object in an array.
static VALUE * RARRAY_PTR(VALUE ary)
Wild use of a C pointer.
#define RARRAY_AREF(a, i)
#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 RUBY_TYPED_DEFAULT_FREE
This is a value you can set to rb_data_type_struct::dfree.
#define RUBY_TYPED_FREE_IMMEDIATELY
Macros to see if each corresponding flag is defined.
#define TypedData_Get_Struct(obj, type, data_type, sval)
Obtains a C struct from inside of a wrapper Ruby object.
#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_obj_classname(VALUE obj)
Queries the name of the class of the passed object.
#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.
Internal header for Ruby Box.
This is the struct that holds necessary info for a struct.
rb_cref_t * cref
class reference, should be marked
const rb_iseq_t * iseqptr
iseq pointer, should be separated from iseqval
IFUNC (Internal FUNCtion)
uintptr_t ID
Type that represents a Ruby identifier such as a variable name.
#define SIZEOF_VALUE
Identical to sizeof(VALUE), except it is a macro that can also be used inside of preprocessor directi...
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.