Ruby 4.1.0dev (2026-10-09 revision 28c73472f8f4a19bcb64482c1303ac20d8cb383e)
proc.c (28c73472f8f4a19bcb64482c1303ac20d8cb383e)
1/**********************************************************************
2
3 proc.c - Proc, Binding, Env
4
5 $Author$
6 created at: Wed Jan 17 12:13:14 2007
7
8 Copyright (C) 2004-2007 Koichi Sasada
9
10**********************************************************************/
11
12#include "eval_intern.h"
13#include "internal.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"
23#include "method.h"
24#include "iseq.h"
25#include "vm_core.h"
26#include "ractor_core.h"
27#include "yjit.h"
28
29const rb_cref_t *rb_vm_cref_in_context(VALUE self, VALUE cbase);
30
31struct METHOD {
32 const VALUE recv;
33 const VALUE klass;
34 /* needed for #super_method */
35 const VALUE iclass;
36 /* Different than me->owner only for ZSUPER methods.
37 This is error-prone but unavoidable unless ZSUPER methods are removed. */
38 const VALUE owner;
39 const rb_method_entry_t * const me;
40 /* for bound methods, `me' should be rb_callable_method_entry_t * */
41};
42
47static VALUE rb_cSourceRange;
48
49static rb_block_call_func bmcall;
50static int method_arity(VALUE);
51static int method_min_max_arity(VALUE, int *max);
52static VALUE proc_binding(VALUE self);
53
55 VALUE path;
56 VALUE absolute_path;
57 int start_line;
58 int start_column;
59 int end_line;
60 int end_column;
61};
62
63static size_t
64source_range_memsize(const void *ptr)
65{
66 return sizeof(struct source_range_data);
67}
68
69RUBY_REFERENCES(source_range_refs) = {
70 RUBY_REF_EDGE(struct source_range_data, path),
71 RUBY_REF_EDGE(struct source_range_data, absolute_path),
72 RUBY_REF_END
73};
74
75static const rb_data_type_t source_range_data_type = {
76 "source_range",
77 {
78 RUBY_REFS_LIST_PTR(source_range_refs),
80 source_range_memsize,
81 },
82 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_DECL_MARKING
83};
84
86rb_source_range_new(VALUE path, VALUE absolute_path, const rb_code_location_t *location)
87{
88 struct source_range_data *data;
90 rb_cSourceRange, struct source_range_data, &source_range_data_type, data);
91 RB_OBJ_WRITE(obj, &data->path, path);
92 RB_OBJ_WRITE(obj, &data->absolute_path, absolute_path);
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;
97
98 return obj;
99}
100
101static VALUE
102source_range_new(const rb_iseq_t *iseq)
103{
104 if (!iseq) {
105 return Qnil;
106 }
107 rb_iseq_check(iseq);
108
109 VALUE path = rb_iseq_path(iseq);
110 VALUE absolute_path = rb_iseq_realpath(iseq);
111 if (NIL_P(path) && NIL_P(absolute_path)) {
112 return Qnil;
113 }
114
115 return rb_source_range_new(path, absolute_path, &ISEQ_BODY(iseq)->location.code_location);
116}
117
118static struct source_range_data *
119source_range_data_get(VALUE self)
120{
121 struct source_range_data *data;
122 TypedData_Get_Struct(self, struct source_range_data, &source_range_data_type, data);
123 return data;
124}
125
126/*
127 * call-seq:
128 * source_range.path -> String
129 *
130 * Returns the source path for the callable associated with this source range.
131 * This is the same path returned as the first element of #source_location.
132 */
133static VALUE
134source_range_path(VALUE self)
135{
136 return source_range_data_get(self)->path;
137}
138
139/*
140 * call-seq:
141 * source_range.absolute_path -> String or nil
142 *
143 * Returns the absolute source path for the callable associated with this source
144 * range, or +nil+ if the source has no absolute path, such as eval'd code.
145 */
146static VALUE
147source_range_absolute_path(VALUE self)
148{
149 return source_range_data_get(self)->absolute_path;
150}
151
152/*
153 * call-seq:
154 * source_range.start_line -> Integer
155 *
156 * Returns the 1-indexed line number where this source range starts.
157 */
158static VALUE
159source_range_start_line(VALUE self)
160{
161 return INT2NUM(source_range_data_get(self)->start_line);
162}
163
164/*
165 * call-seq:
166 * source_range.start_column -> Integer
167 *
168 * Returns the 0-indexed byte column where this source range starts.
169 *
170 * -> {}.source_range.start_column # => 0 # the '->'
171 * l = -> {}.source_range.start_column # => 4 # the '->'
172 * proc {}.source_range.start_column # => 5 # the '{'
173 * method(def m = 42).source_range.start_column # => 7 # the 'def'
174 */
175static VALUE
176source_range_start_column(VALUE self)
177{
178 return INT2NUM(source_range_data_get(self)->start_column);
179}
180
181/*
182 * call-seq:
183 * source_range.end_line -> Integer
184 *
185 * Returns the 1-indexed line number where this source range ends.
186 *
187 * Note that this does not include a potential heredoc that spans beyond the callable's end, for example:
188 *
189 * proc { <<~HEREDOC }.source_range.end_line # => 1
190 * heredoc
191 * contents
192 * HEREDOC
193 *
194 * To get the location of the final HEREDOC you can use +Prism.find(Proc|Method|UnboundMethod)+ and then compute the maximum end_line and end_column.
195 */
196static VALUE
197source_range_end_line(VALUE self)
198{
199 return INT2NUM(source_range_data_get(self)->end_line);
200}
201
202/*
203 * call-seq:
204 * source_range.end_column -> Integer
205 *
206 * Returns the 0-indexed byte column where this source range ends.
207 *
208 * Note that this does not include a potential heredoc that spans beyond the callable's end, for example:
209 *
210 * proc { <<~HEREDOC }.source_range.end_column # => 19
211 * heredoc
212 * contents
213 * HEREDOC
214 *
215 * To get the location of the final HEREDOC you can use +Prism.find(Proc|Method|UnboundMethod)+ and then compute the maximum end_line and end_column.
216 */
217static VALUE
218source_range_end_column(VALUE self)
219{
220 return INT2NUM(source_range_data_get(self)->end_column);
221}
222
223/*
224 * call-seq:
225 * source_range.inspect -> String
226 *
227 * Returns a human-readable string with the #absolute_path if available,
228 * otherwise the #path, and the start and end coordinates.
229 */
230static VALUE
231source_range_inspect(VALUE self)
232{
233 struct source_range_data *data = source_range_data_get(self);
234 VALUE str = rb_str_new_cstr("#<Ruby::SourceRange ");
235 VALUE path = NIL_P(data->absolute_path) ? data->path : data->absolute_path;
236
237 VM_ASSERT(!NIL_P(path));
238 rb_str_append(str, path);
239
240 rb_str_catf(str, ":(%d,%d)-(%d,%d)>",
241 data->start_line, data->start_column,
242 data->end_line, data->end_column);
243
244 return str;
245}
246
247/* Proc */
248
249#define IS_METHOD_PROC_IFUNC(ifunc) ((ifunc)->func == bmcall)
250
251static void
252block_mark_and_move(struct rb_block *block)
253{
254 switch (block->type) {
255 case block_type_iseq:
256 case block_type_ifunc:
257 {
258 struct rb_captured_block *captured = &block->as.captured;
259 rb_gc_mark_and_move(&captured->self);
260 rb_gc_mark_and_move(&captured->code.val);
261 if (captured->ep) {
262 rb_gc_mark_and_move((VALUE *)&captured->ep[VM_ENV_DATA_INDEX_ENV]);
263 }
264 }
265 break;
266 case block_type_symbol:
267 rb_gc_mark_and_move(&block->as.symbol);
268 break;
269 case block_type_proc:
270 rb_gc_mark_and_move(&block->as.proc);
271 break;
272 }
273}
274
275static ID id_refinements_recipe;
276
277static void
278proc_mark_and_move(void *ptr)
279{
280 rb_proc_t *proc = ptr;
281 block_mark_and_move((struct rb_block *)&proc->block);
282}
283
284enum refinement_recipe_index {
285 REFINEMENT_RECIPE_BASE_CREF, /* key: cref the modules are activated on */
286 REFINEMENT_RECIPE_CREF, /* value: cref with the refinements activated */
287 REFINEMENT_RECIPE_SRC_ISEQ, /* key: iseq of the block the Proc came from */
288 REFINEMENT_RECIPE_MODS /* key: modules, in the order given */
289};
290
291static bool
292refinement_recipe_eq(VALUE r1, VALUE r2)
293{
294 if (r1 == r2) return true;
295 long len = RARRAY_LEN(r1);
296 if (RARRAY_LEN(r2) != len) return false;
297 if (RARRAY_AREF(r1, REFINEMENT_RECIPE_BASE_CREF) !=
298 RARRAY_AREF(r2, REFINEMENT_RECIPE_BASE_CREF)) return false;
299 if (RARRAY_AREF(r1, REFINEMENT_RECIPE_SRC_ISEQ) !=
300 RARRAY_AREF(r2, REFINEMENT_RECIPE_SRC_ISEQ)) return false;
301 for (long i = REFINEMENT_RECIPE_MODS; i < len; i++) {
302 if (RARRAY_AREF(r1, i) != RARRAY_AREF(r2, i)) return false;
303 }
304 return true;
305}
306
307VALUE
308rb_proc_refinements_recipe(VALUE procval)
309{
310 rb_proc_t *proc;
311 GetProcPtr(procval, proc);
312 if (!proc->header.is_refined) return Qnil;
313 return rb_ivar_get(procval, id_refinements_recipe);
314}
315
316void
317rb_proc_set_refinements_recipe(VALUE procval, VALUE recipe)
318{
319 rb_proc_t *proc;
320 GetProcPtr(procval, proc);
321 rb_ivar_set(procval, id_refinements_recipe, recipe);
322 proc->header.is_refined = 1;
323}
324
325typedef struct {
326 rb_proc_t basic;
327 VALUE env[VM_ENV_DATA_SIZE + 1]; /* ..., envval */
329
330static size_t
331proc_memsize(const void *ptr)
332{
333 const rb_proc_t *proc = 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)
338 return sizeof(cfunc_proc_t);
339 return sizeof(rb_proc_captured_t);
340 case block_type_symbol:
341 return sizeof(rb_proc_symbol_t);
342 case block_type_proc:
343 return sizeof(rb_proc_proc_t);
344 }
345 VM_UNREACHABLE(proc_memsize);
346 return 0;
347}
348
349const rb_data_type_t ruby_proc_data_type = {
350 "proc",
351 {
352 proc_mark_and_move,
354 proc_memsize,
355 proc_mark_and_move,
356 },
357 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED
358};
359
360#define proc_data_type ruby_proc_data_type
361
362VALUE
363rb_proc_alloc(VALUE klass, enum rb_block_type block_type)
364{
365 size_t size;
366 switch (block_type) {
367 case block_type_symbol:
368 size = sizeof(rb_proc_symbol_t);
369 break;
370 case block_type_proc:
371 size = sizeof(rb_proc_proc_t);
372 break;
373 case block_type_iseq:
374 case block_type_ifunc:
375 size = sizeof(rb_proc_captured_t);
376 break;
377 default:
378 VM_UNREACHABLE(rb_proc_alloc);
379 return Qundef;
380 }
381
382 return rb_data_typed_object_zalloc(klass, size, &proc_data_type);
383}
384
385VALUE
387{
388 return RBOOL(rb_typeddata_is_kind_of(proc, &proc_data_type));
389}
390
391/* :nodoc: */
392static VALUE
393proc_clone(VALUE self)
394{
395 VALUE procval = rb_proc_dup_0(self);
396 return rb_obj_clone_setup(self, procval, Qnil);
397}
398
399/* :nodoc: */
400static VALUE
401proc_dup(VALUE self)
402{
403 VALUE procval = rb_proc_dup_0(self);
404 return rb_obj_dup_setup(self, procval);
405}
406
407rb_cref_t *rb_vm_get_cref(const VALUE *ep);
408VALUE rb_proc_dup_with_iseq_and_recipe(VALUE self, const rb_iseq_t *iseq, VALUE recipe);
409
410/* Proc#refined memoizes the most recent recipe copied for a source iseq, with
411 * its copy. The memo lives in a hidden identity Hash:
412 *
413 * source iseq -> [recipe, copied_iseq]
414 *
415 * An entry is written when the copy is made, that is on the first call of a
416 * Proc built from the recipe, not when Proc#refined is called: a chain of
417 * calls then memoizes the chain as a whole, since the recipe of the last link
418 * carries all of the modules. It also means one entry per source iseq is
419 * enough for prc.refined(a).refined(b), which shares its entry with
420 * prc.refined(a, b).
421 *
422 * An entry is retained for the VM's lifetime, so a block that is itself a copy
423 * is never used as a key; such a Proc is copied by Proc#refined instead. */
424
425enum refinement_memo_index {
426 REFINEMENT_MEMO_RECIPE,
427 REFINEMENT_MEMO_COPIED_ISEQ
428};
429
430static VALUE refinement_memo_map; /* set once under the VM lock */
431
432static VALUE
433refinement_memo_get(const rb_iseq_t *src_iseq)
434{
435 VALUE memo = Qnil;
436 RB_VM_LOCKING() {
437 if (refinement_memo_map) {
438 memo = rb_hash_lookup(refinement_memo_map, (VALUE)src_iseq);
439 }
440 }
441 return memo;
442}
443
444static void
445refinement_memo_set(const rb_iseq_t *src_iseq, VALUE recipe, const rb_iseq_t *copied_iseq)
446{
447 VM_ASSERT(ISEQ_BODY(src_iseq)->type == ISEQ_TYPE_BLOCK);
448
449 VALUE memo = rb_ary_hidden_new(2);
450 rb_ary_push(memo, recipe);
451 rb_ary_push(memo, (VALUE)copied_iseq);
452 OBJ_FREEZE(memo);
453 /* Every element is shareable, so mark the memo array shareable too for
454 * reuse from any Ractor. */
456
457 /* create the map outside the lock; losing the race just discards it */
458 VALUE new_map = 0;
459 if (!refinement_memo_map) {
460 new_map = rb_obj_hide(rb_ident_hash_new());
461 }
462
463 RB_VM_LOCKING() {
464 if (!refinement_memo_map) {
465 rb_vm_register_global_object(new_map);
466 refinement_memo_map = new_map;
467 }
468 rb_hash_aset(refinement_memo_map, (VALUE)src_iseq, memo);
469 }
470}
471
472static long
473refinement_recipe_modc(VALUE recipe)
474{
475 return NIL_P(recipe) ? 0 : RARRAY_LEN(recipe) - REFINEMENT_RECIPE_MODS;
476}
477
478static bool
479refinement_recipe_match(VALUE recipe, const rb_cref_t *base_cref, VALUE src_recipe,
480 long argc, const VALUE *mods)
481{
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;
488 }
489 for (long i = 0; i < argc; i++) {
490 if (RARRAY_AREF(recipe, REFINEMENT_RECIPE_MODS + inherited + i) != mods[i]) return false;
491 }
492 return true;
493}
494
495static VALUE
496refinement_recipe_new(const rb_cref_t *base_cref, const rb_cref_t *cref,
497 const rb_iseq_t *src_iseq, VALUE src_recipe,
498 long argc, const VALUE *mods)
499{
500 long inherited = refinement_recipe_modc(src_recipe);
501 VALUE recipe = rb_ary_hidden_new(REFINEMENT_RECIPE_MODS + inherited + argc);
502 rb_ary_push(recipe, (VALUE)base_cref);
503 rb_ary_push(recipe, (VALUE)cref);
504 rb_ary_push(recipe, (VALUE)src_iseq);
505 for (long i = 0; i < inherited; i++) {
506 rb_ary_push(recipe, RARRAY_AREF(src_recipe, REFINEMENT_RECIPE_MODS + i));
507 }
508 for (long i = 0; i < argc; i++) {
509 rb_ary_push(recipe, mods[i]);
510 }
511 OBJ_FREEZE(recipe);
512 RB_OBJ_SET_SHAREABLE(recipe);
513 return recipe;
514}
515
516static VALUE
517refinement_memo_lookup(const rb_iseq_t *src_iseq, const rb_cref_t *base_cref, VALUE src_recipe,
518 long argc, const VALUE *mods)
519{
520 VM_ASSERT(ISEQ_BODY(src_iseq)->type == ISEQ_TYPE_BLOCK);
521 VALUE memo = refinement_memo_get(src_iseq);
522 if (NIL_P(memo)) return Qnil;
523 VALUE recipe = RARRAY_AREF(memo, REFINEMENT_MEMO_RECIPE);
524 if (!refinement_recipe_match(recipe, base_cref, src_recipe, argc, mods)) return Qnil;
525 return recipe;
526}
527
528static const rb_iseq_t *
529refinement_iseq_copy(VALUE recipe)
530{
531 const rb_iseq_t *src_iseq =
532 (const rb_iseq_t *)RARRAY_AREF(recipe, REFINEMENT_RECIPE_SRC_ISEQ);
533 VALUE memo = refinement_memo_get(src_iseq);
534 if (!NIL_P(memo)) {
535 if (refinement_recipe_eq(RARRAY_AREF(memo, REFINEMENT_MEMO_RECIPE), recipe)) {
536 const rb_iseq_t *copied_iseq =
537 (const rb_iseq_t *)RARRAY_AREF(memo, REFINEMENT_MEMO_COPIED_ISEQ);
538 if (ISEQ_BODY(copied_iseq)->param.flags.ruby2_keywords ==
539 ISEQ_BODY(src_iseq)->param.flags.ruby2_keywords) {
540 return copied_iseq;
541 }
544 "Proc#refined re-copies the block because the ruby2_keywords flag changed after the copy was memoized"
545 );
546 }
547 else {
550 "Proc#refined called with different modules for the same block disables memoization"
551 );
552 }
553 }
554
555 /* copy outside the lock; losing a race just discards the extra copy */
556 const rb_iseq_t *copied_iseq = rb_iseq_dup_with_independent_caches(src_iseq);
557 refinement_memo_set(src_iseq, recipe, copied_iseq);
558 return copied_iseq;
559}
560
561NOINLINE(static void refinement_iseq_install(VALUE procval, rb_proc_t *proc));
562static void
563refinement_iseq_install(VALUE procval, rb_proc_t *proc)
564{
565 VALUE recipe = rb_ivar_get(procval, id_refinements_recipe);
566 const rb_iseq_t *copied_iseq = refinement_iseq_copy(recipe);
567
568 RB_VM_LOCKING() {
569 if (!FL_TEST_RAW((VALUE)proc->block.as.captured.code.iseq, ISEQ_REFINED_COPY)) {
570 RB_OBJ_WRITE(procval, &proc->block.as.captured.code.val, (VALUE)copied_iseq);
571 }
572 }
573}
574
575static inline void
576refinement_iseq_ensure(VALUE procval, rb_proc_t *proc)
577{
578 if (UNLIKELY(!FL_TEST_RAW((VALUE)proc->block.as.captured.code.iseq, ISEQ_REFINED_COPY))) {
579 refinement_iseq_install(procval, proc);
580 }
581}
582
583const rb_cref_t *
584rb_proc_refinements_cref_for_call(VALUE procval)
585{
586 rb_proc_t *proc;
587 GetProcPtr(procval, proc);
588 if (!proc->header.is_refined) return NULL;
589
590 refinement_iseq_ensure(procval, proc);
591 VALUE recipe = rb_ivar_get(procval, id_refinements_recipe);
592 return (const rb_cref_t *)RARRAY_AREF(recipe, REFINEMENT_RECIPE_CREF);
593}
594
595/*
596 * call-seq:
597 * prc.refined(*modules) -> a_proc
598 *
599 * Returns a new Proc that behaves like the receiver but with the refinements
600 * activated by the given modules in effect inside its body. The receiver is
601 * left unchanged.
602 *
603 * module StringRefinement
604 * refine String do
605 * def shout = upcase + "!"
606 * end
607 * end
608 *
609 * original = ->(s) { s.shout }
610 * refined_proc = original.refined(StringRefinement)
611 * refined_proc.call("hi") #=> "HI!"
612 * original.call("hi") #=> NoMethodError
613 *
614 * If no modules are given, returns the receiver.
615 * Otherwise, only Procs created from a Ruby block are supported; calling this
616 * on a Proc backed by a C function, a Symbol, or a method raises ArgumentError.
617 *
618 * When calls of this method are chained, all the given modules are activated
619 * in the order they are given, so refinements activated by a later call take
620 * precedence.
621 *
622 * The refinement set of the returned Proc is fixed when it is created:
623 * calling +using+ inside its body raises RuntimeError.
624 *
625 * The refinements are in effect throughout the body, including nested blocks
626 * and methods defined with +def+ inside it. As with a +def+ inside a +using+
627 * scope, such a method keeps the refinements even when it is called later:
628 *
629 * refined_proc = ->(s) {
630 * -> { s.shout }.call # nested block: "HI!"
631 * }.refined(StringRefinement)
632 *
633 * refined_proc = -> {
634 * obj = Object.new
635 * def obj.shout_hi = "hi".shout # the method sees the refinement
636 * obj.shout_hi #=> "HI!"
637 * }.refined(StringRefinement)
638 *
639 * Running the returned Proc requires a copy of the instruction sequence of the
640 * block and of all of its nested blocks, so that the copy can resolve methods
641 * through the refinements without affecting the original Proc. The copy is
642 * made when the Proc is first called, and is cached and reused for the same
643 * block and the same modules, whether they were given in one call or in a
644 * chain of calls; a Proc that is never called is never copied. Applying
645 * refinements therefore increases memory use roughly in proportion to the size
646 * of the block, once the Proc runs.
647 */
648static VALUE
649proc_refined(int argc, VALUE *argv, VALUE self)
650{
651 rb_proc_t *src;
652 GetProcPtr(self, src);
653
654 if (argc == 0) {
655 return self;
656 }
657
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");
660 }
661
662 for (int i = 0; i < argc; i++) {
663 Check_Type(argv[i], T_MODULE);
664 }
665
666 const rb_iseq_t *src_iseq = src->block.as.captured.code.iseq;
667 VALUE src_recipe = rb_proc_refinements_recipe(self);
668 const rb_cref_t *src_cref, *base_cref;
669 if (NIL_P(src_recipe)) {
670 src_cref = base_cref = rb_vm_get_cref(src->block.as.captured.ep);
671 }
672 else {
673 /* keep asking for the modules of the whole chain, so that a chained
674 * call ends up with the recipe of a single call of all of them */
675 src_cref = (const rb_cref_t *)RARRAY_AREF(src_recipe, REFINEMENT_RECIPE_CREF);
676 base_cref = (const rb_cref_t *)RARRAY_AREF(src_recipe, REFINEMENT_RECIPE_BASE_CREF);
677 }
678
679 /* A block that is itself a copy is short-lived, so it is not memoized, and
680 * it has to be copied here: ISEQ_REFINED_COPY has to keep meaning "the
681 * copy of this Proc". */
682 bool copied_src = FL_TEST_RAW((VALUE)src_iseq, ISEQ_REFINED_COPY);
683 if (copied_src) {
686 "Proc#refined on a Proc whose block was already copied by Proc#refined is not memoized"
687 );
688 }
689
690 VALUE recipe = copied_src ? Qnil :
691 refinement_memo_lookup(src_iseq, base_cref, src_recipe, argc, argv);
692 if (NIL_P(recipe)) {
693 rb_cref_t *cref = rb_vm_cref_dup(src_cref);
694 /* rb_using_module_recursive modifies shared subclass lists */
695 RB_VM_LOCKING() {
696 for (int i = 0; i < argc; i++) {
697 rb_using_module_recursive(cref, argv[i]);
698 }
699 }
700 /* Freeze the refinements table and mark it shareable so the memoized
701 * cref can be reused from any Ractor. */
702 VALUE refs = CREF_REFINEMENTS(cref);
703 if (!NIL_P(refs)) {
704 OBJ_FREEZE(refs);
706 }
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);
710 }
711
712 const rb_iseq_t *new_iseq = copied_src ?
713 rb_iseq_dup_with_independent_caches(src_iseq) : src_iseq;
714
715 return rb_proc_dup_with_iseq_and_recipe(self, new_iseq, recipe);
716}
717
718/*
719 * call-seq:
720 * prc.lambda? -> true or false
721 *
722 * Returns +true+ if a Proc object is lambda.
723 * +false+ if non-lambda.
724 *
725 * The lambda-ness affects argument handling and the behavior of +return+ and +break+.
726 *
727 * A Proc object generated by +proc+ ignores extra arguments.
728 *
729 * proc {|a,b| [a,b] }.call(1,2,3) #=> [1,2]
730 *
731 * It provides +nil+ for missing arguments.
732 *
733 * proc {|a,b| [a,b] }.call(1) #=> [1,nil]
734 *
735 * It expands a single array argument.
736 *
737 * proc {|a,b| [a,b] }.call([1,2]) #=> [1,2]
738 *
739 * A Proc object generated by +lambda+ doesn't have such tricks.
740 *
741 * lambda {|a,b| [a,b] }.call(1,2,3) #=> ArgumentError
742 * lambda {|a,b| [a,b] }.call(1) #=> ArgumentError
743 * lambda {|a,b| [a,b] }.call([1,2]) #=> ArgumentError
744 *
745 * Proc#lambda? is a predicate for the tricks.
746 * It returns +true+ if no tricks apply.
747 *
748 * lambda {}.lambda? #=> true
749 * proc {}.lambda? #=> false
750 *
751 * Proc.new is the same as +proc+.
752 *
753 * Proc.new {}.lambda? #=> false
754 *
755 * +lambda+, +proc+ and Proc.new preserve the tricks of
756 * a Proc object given by <code>&</code> argument.
757 *
758 * lambda(&lambda {}).lambda? #=> true
759 * proc(&lambda {}).lambda? #=> true
760 * Proc.new(&lambda {}).lambda? #=> true
761 *
762 * lambda(&proc {}).lambda? #=> false
763 * proc(&proc {}).lambda? #=> false
764 * Proc.new(&proc {}).lambda? #=> false
765 *
766 * A Proc object generated by <code>&</code> argument has the tricks
767 *
768 * def n(&b) b.lambda? end
769 * n {} #=> false
770 *
771 * The <code>&</code> argument preserves the tricks if a Proc object
772 * is given by <code>&</code> argument.
773 *
774 * n(&lambda {}) #=> true
775 * n(&proc {}) #=> false
776 * n(&Proc.new {}) #=> false
777 *
778 * A Proc object converted from a method has no tricks.
779 *
780 * def m() end
781 * method(:m).to_proc.lambda? #=> true
782 *
783 * n(&method(:m)) #=> true
784 * n(&method(:m).to_proc) #=> true
785 *
786 * +define_method+ is treated the same as method definition.
787 * The defined method has no tricks.
788 *
789 * class C
790 * define_method(:d) {}
791 * end
792 * C.new.d(1,2) #=> ArgumentError
793 * C.new.method(:d).to_proc.lambda? #=> true
794 *
795 * +define_method+ always defines a method without the tricks,
796 * even if a non-lambda Proc object is given.
797 * This is the only exception for which the tricks are not preserved.
798 *
799 * class C
800 * define_method(:e, &proc {})
801 * end
802 * C.new.e(1,2) #=> ArgumentError
803 * C.new.method(:e).to_proc.lambda? #=> true
804 *
805 * This exception ensures that methods never have tricks
806 * and makes it easy to have wrappers to define methods that behave as usual.
807 *
808 * class C
809 * def self.def2(name, &body)
810 * define_method(name, &body)
811 * end
812 *
813 * def2(:f) {}
814 * end
815 * C.new.f(1,2) #=> ArgumentError
816 *
817 * The wrapper <i>def2</i> defines a method which has no tricks.
818 *
819 */
820
821VALUE
823{
824 rb_proc_t *proc;
825 GetProcPtr(procval, proc);
826
827 return RBOOL(proc->header.is_lambda);
828}
829
830/* Binding */
831
832static void
833binding_free(void *ptr)
834{
835 RUBY_FREE_ENTER("binding");
836 SIZED_FREE((rb_binding_t *)ptr);
837 RUBY_FREE_LEAVE("binding");
838}
839
840static void
841binding_mark_and_move(void *ptr)
842{
843 rb_binding_t *bind = ptr;
844
845 block_mark_and_move((struct rb_block *)&bind->block);
846 rb_gc_mark_and_move((VALUE *)&bind->pathobj);
847}
848
849static size_t
850binding_memsize(const void *ptr)
851{
852 return sizeof(rb_binding_t);
853}
854
855const rb_data_type_t ruby_binding_data_type = {
856 "binding",
857 {
858 binding_mark_and_move,
859 binding_free,
860 binding_memsize,
861 binding_mark_and_move,
862 },
863 0, 0, RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_THREAD_SAFE_FREE
864};
865
866VALUE
867rb_binding_alloc(VALUE klass)
868{
869 VALUE obj;
870 rb_binding_t *bind;
871 obj = TypedData_Make_Struct(klass, rb_binding_t, &ruby_binding_data_type, bind);
872#if YJIT_STATS
873 rb_yjit_collect_binding_alloc();
874#endif
875 return obj;
876}
877
878static VALUE
879binding_copy(VALUE self)
880{
881 VALUE bindval = rb_binding_alloc(rb_cBinding);
882 rb_binding_t *src, *dst;
883 GetBindingPtr(self, src);
884 GetBindingPtr(bindval, dst);
885 rb_vm_block_copy(bindval, &dst->block, &src->block);
886 RB_OBJ_WRITE(bindval, &dst->pathobj, src->pathobj);
887 dst->first_lineno = src->first_lineno;
888 return bindval;
889}
890
891/* :nodoc: */
892static VALUE
893binding_dup(VALUE self)
894{
895 return rb_obj_dup_setup(self, binding_copy(self));
896}
897
898/* :nodoc: */
899static VALUE
900binding_clone(VALUE self)
901{
902 return rb_obj_clone_setup(self, binding_copy(self), Qnil);
903}
904
905VALUE
907{
908 rb_execution_context_t *ec = GET_EC();
909 return rb_vm_make_binding(ec, ec->cfp);
910}
911
912/*
913 * call-seq:
914 * binding -> a_binding
915 *
916 * Returns a Binding object, describing the variable and
917 * method bindings at the point of call. This object can be used when
918 * calling Binding#eval to execute the evaluated command in this
919 * environment, or extracting its local variables.
920 *
921 * class User
922 * def initialize(name, position)
923 * @name = name
924 * @position = position
925 * end
926 *
927 * def get_binding
928 * binding
929 * end
930 * end
931 *
932 * user = User.new('Joan', 'manager')
933 * template = '{name: @name, position: @position}'
934 *
935 * # evaluate template in context of the object
936 * eval(template, user.get_binding)
937 * #=> {name: "Joan", position: "manager"}
938 *
939 * Binding#local_variable_get can be used to access the variables
940 * whose names are reserved Ruby keywords:
941 *
942 * # This is valid parameter declaration, but `if` parameter can't
943 * # be accessed by name, because it is a reserved word.
944 * def validate(field, validation, if: nil)
945 * condition = binding.local_variable_get('if')
946 * return unless condition
947 *
948 * # ...Some implementation ...
949 * end
950 *
951 * validate(:name, :empty?, if: false) # skips validation
952 * validate(:name, :empty?, if: true) # performs validation
953 *
954 */
955
956static VALUE
957rb_f_binding(VALUE self)
958{
959 return rb_binding_new();
960}
961
962/*
963 * call-seq:
964 * binding.eval(string, filename = default_filename, lineno = 1) -> obj
965 *
966 * Evaluates the Ruby expression(s) in +string+ in the context of
967 * +self+. Returns the result of the last expression:
968 *
969 * def get_binding(param) = binding
970 * b = get_binding("hello")
971 * b.eval("param") #=> "hello"
972 *
973 * If the optional +filename+ is given, it will be used as the
974 * filename of the evaluation (for <tt>__FILE__</tt> and errors).
975 * Otherwise, it will default to <tt>(eval at __FILE__:__LINE__)</tt>
976 * where <tt>__FILE__</tt> and <tt>__LINE__</tt> are the filename and
977 * line number of the caller, respectively:
978 *
979 * b.eval("puts __FILE__") # => "(eval at test.rb:4)"
980 * b.eval("puts __FILE__", "foobar.rb") # => "foobar.rb"
981 *
982 * If the optional +lineno+ is given, it will be used as the
983 * line number of the evaluation (for <tt>__LINE__</tt> and errors).
984 * Otherwise, it will default to 1:
985 *
986 * b.eval("puts __LINE__") # => 1
987 * b.eval("puts __LINE__", "foobar.rb", 10) # => 10
988 */
989
990static VALUE
991bind_eval(int argc, VALUE *argv, VALUE bindval)
992{
993 VALUE args[4];
994
995 rb_scan_args(argc, argv, "12", &args[0], &args[2], &args[3]);
996 args[1] = bindval;
997 return rb_f_eval(argc+1, args, Qnil /* self will be searched in eval */);
998}
999
1000static const VALUE *
1001get_local_variable_ptr(const rb_env_t **envp, ID lid, bool search_outer)
1002{
1003 const rb_env_t *env = *envp;
1004 do {
1005 if (!VM_ENV_FLAGS(env->ep, VM_FRAME_FLAG_CFRAME)) {
1006 if (VM_ENV_FLAGS(env->ep, VM_ENV_FLAG_ISOLATED)) {
1007 return NULL;
1008 }
1009
1010 const rb_iseq_t *iseq = env->iseq;
1011
1012 VM_ASSERT(rb_obj_is_iseq((VALUE)iseq));
1013
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);
1024 }
1025 }
1026
1027 *envp = env;
1028 unsigned int last_lvar = env->env_size+VM_ENV_INDEX_LAST_LVAR
1029 - 1 /* errinfo */;
1030 return &env->env[last_lvar - (local_table_size - i)];
1031 }
1032 }
1033 }
1034 else {
1035 *envp = NULL;
1036 return NULL;
1037 }
1038 } while (search_outer && (env = rb_vm_env_prev_env(env)) != NULL);
1039
1040 *envp = NULL;
1041 return NULL;
1042}
1043
1044/*
1045 * check local variable name.
1046 * returns ID if it's an already interned symbol, or 0 with setting
1047 * local name in String to *namep.
1048 */
1049static ID
1050check_local_id(VALUE bindval, volatile VALUE *pname)
1051{
1052 ID lid = rb_check_id(pname);
1053 VALUE name = *pname;
1054
1055 if (lid) {
1056 if (!rb_is_local_id(lid)) {
1057 rb_name_err_raise("wrong local variable name '%1$s' for %2$s",
1058 bindval, ID2SYM(lid));
1059 }
1060 }
1061 else {
1062 if (!rb_is_local_name(name)) {
1063 rb_name_err_raise("wrong local variable name '%1$s' for %2$s",
1064 bindval, name);
1065 }
1066 return 0;
1067 }
1068 return lid;
1069}
1070
1071/*
1072 * call-seq:
1073 * binding.local_variables -> Array
1074 *
1075 * Returns the names of the binding's local variables as symbols.
1076 *
1077 * def foo
1078 * a = 1
1079 * 2.times do |n|
1080 * binding.local_variables #=> [:a, :n]
1081 * end
1082 * end
1083 *
1084 * This method is the short version of the following code:
1085 *
1086 * binding.eval("local_variables")
1087 *
1088 */
1089static VALUE
1090bind_local_variables(VALUE bindval)
1091{
1092 const rb_binding_t *bind;
1093 const rb_env_t *env;
1094
1095 GetBindingPtr(bindval, bind);
1096 env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
1097 return rb_vm_env_local_variables(env);
1098}
1099
1100int
1101rb_numparam_id_p(ID id)
1102{
1103 return (tNUMPARAM_1 << ID_SCOPE_SHIFT) <= id && id < ((tNUMPARAM_1 + 9) << ID_SCOPE_SHIFT);
1104}
1105
1106int
1107rb_implicit_param_p(ID id)
1108{
1109 return id == idItImplicit || rb_numparam_id_p(id);
1110}
1111
1112/*
1113 * call-seq:
1114 * binding.local_variable_get(symbol) -> obj
1115 *
1116 * Returns the value of the local variable +symbol+.
1117 *
1118 * def foo
1119 * a = 1
1120 * binding.local_variable_get(:a) #=> 1
1121 * binding.local_variable_get(:b) #=> NameError
1122 * end
1123 *
1124 * This method is the short version of the following code:
1125 *
1126 * binding.eval("#{symbol}")
1127 *
1128 */
1129static VALUE
1130bind_local_variable_get(VALUE bindval, VALUE sym)
1131{
1132 ID lid = check_local_id(bindval, &sym);
1133 const rb_binding_t *bind;
1134 const VALUE *ptr;
1135 const rb_env_t *env;
1136
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",
1140 bindval, ID2SYM(lid));
1141 }
1142
1143 GetBindingPtr(bindval, bind);
1144
1145 env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
1146 if ((ptr = get_local_variable_ptr(&env, lid, TRUE)) != NULL) {
1147 return *ptr;
1148 }
1149
1150 sym = ID2SYM(lid);
1151 undefined:
1152 rb_name_err_raise("local variable '%1$s' is not defined for %2$s",
1153 bindval, sym);
1155}
1156
1157/*
1158 * call-seq:
1159 * binding.local_variable_set(symbol, obj) -> obj
1160 *
1161 * Set local variable named +symbol+ as +obj+.
1162 *
1163 * def foo
1164 * a = 1
1165 * bind = binding
1166 * bind.local_variable_set(:a, 2) # set existing local variable `a'
1167 * bind.local_variable_set(:b, 3) # create new local variable `b'
1168 * # `b' exists only in binding
1169 *
1170 * p bind.local_variable_get(:a) #=> 2
1171 * p bind.local_variable_get(:b) #=> 3
1172 * p a #=> 2
1173 * p b #=> NameError
1174 * end
1175 *
1176 * This method behaves similarly to the following code:
1177 *
1178 * binding.eval("#{symbol} = #{obj}")
1179 *
1180 * if +obj+ can be dumped in Ruby code.
1181 */
1182static VALUE
1183bind_local_variable_set(VALUE bindval, VALUE sym, VALUE val)
1184{
1185 ID lid = check_local_id(bindval, &sym);
1186 rb_binding_t *bind;
1187 const VALUE *ptr;
1188 const rb_env_t *env;
1189
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",
1193 bindval, ID2SYM(lid));
1194 }
1195
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) {
1199 /* not found. create new env */
1200 ptr = rb_binding_add_dynavars(bindval, bind, 1, &lid);
1201 env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
1202 }
1203
1204#if YJIT_STATS
1205 rb_yjit_collect_binding_set();
1206#endif
1207
1208 RB_OBJ_WRITE(env, ptr, val);
1209
1210 return val;
1211}
1212
1213/*
1214 * call-seq:
1215 * binding.local_variable_defined?(symbol) -> obj
1216 *
1217 * Returns +true+ if a local variable +symbol+ exists.
1218 *
1219 * def foo
1220 * a = 1
1221 * binding.local_variable_defined?(:a) #=> true
1222 * binding.local_variable_defined?(:b) #=> false
1223 * end
1224 *
1225 * This method is the short version of the following code:
1226 *
1227 * binding.eval("defined?(#{symbol}) == 'local-variable'")
1228 *
1229 */
1230static VALUE
1231bind_local_variable_defined_p(VALUE bindval, VALUE sym)
1232{
1233 ID lid = check_local_id(bindval, &sym);
1234 const rb_binding_t *bind;
1235 const rb_env_t *env;
1236
1237 if (!lid) return Qfalse;
1238 if (rb_numparam_id_p(lid)) {
1239 rb_name_err_raise("numbered parameter '%1$s' is not a local variable",
1240 bindval, ID2SYM(lid));
1241 }
1242
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));
1246}
1247
1248/*
1249 * call-seq:
1250 * binding.implicit_parameters -> Array
1251 *
1252 * Returns the names of numbered parameters and "it" parameter
1253 * that are defined in the binding.
1254 *
1255 * def foo
1256 * [42].each do
1257 * it
1258 * binding.implicit_parameters #=> [:it]
1259 * end
1260 *
1261 * { k: 42 }.each do
1262 * _2
1263 * binding.implicit_parameters #=> [:_1, :_2]
1264 * end
1265 * end
1266 *
1267 */
1268static VALUE
1269bind_implicit_parameters(VALUE bindval)
1270{
1271 const rb_binding_t *bind;
1272 const rb_env_t *env;
1273
1274 GetBindingPtr(bindval, bind);
1275 env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
1276
1277 if (get_local_variable_ptr(&env, idItImplicit, FALSE)) {
1278 return rb_ary_new_from_args(1, ID2SYM(idIt));
1279 }
1280
1281 env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
1282 return rb_vm_env_numbered_parameters(env);
1283}
1284
1285/*
1286 * call-seq:
1287 * binding.implicit_parameter_get(symbol) -> obj
1288 *
1289 * Returns the value of the numbered parameter or "it" parameter.
1290 *
1291 * def foo
1292 * [42].each do
1293 * it
1294 * binding.implicit_parameter_get(:it) #=> 42
1295 * end
1296 *
1297 * { k: 42 }.each do
1298 * _2
1299 * binding.implicit_parameter_get(:_1) #=> :k
1300 * binding.implicit_parameter_get(:_2) #=> 42
1301 * end
1302 * end
1303 *
1304 */
1305static VALUE
1306bind_implicit_parameter_get(VALUE bindval, VALUE sym)
1307{
1308 ID lid = check_local_id(bindval, &sym);
1309 const rb_binding_t *bind;
1310 const VALUE *ptr;
1311 const rb_env_t *env;
1312
1313 if (lid == idIt) lid = idItImplicit;
1314
1315 if (!lid || !rb_implicit_param_p(lid)) {
1316 rb_name_err_raise("'%1$s' is not an implicit parameter",
1317 bindval, sym);
1318 }
1319
1320 GetBindingPtr(bindval, bind);
1321
1322 env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
1323 if ((ptr = get_local_variable_ptr(&env, lid, FALSE)) != NULL) {
1324 return *ptr;
1325 }
1326
1327 if (lid == idItImplicit) lid = idIt;
1328 rb_name_err_raise("implicit parameter '%1$s' is not defined for %2$s", bindval, ID2SYM(lid));
1330}
1331
1332/*
1333 * call-seq:
1334 * binding.implicit_parameter_defined?(symbol) -> obj
1335 *
1336 * Returns +true+ if the numbered parameter or "it" parameter exists.
1337 *
1338 * def foo
1339 * [42].each do
1340 * it
1341 * binding.implicit_parameter_defined?(:it) #=> true
1342 * binding.implicit_parameter_defined?(:_1) #=> false
1343 * end
1344 *
1345 * { k: 42 }.each do
1346 * _2
1347 * binding.implicit_parameter_defined?(:_1) #=> true
1348 * binding.implicit_parameter_defined?(:_2) #=> true
1349 * binding.implicit_parameter_defined?(:_3) #=> false
1350 * binding.implicit_parameter_defined?(:it) #=> false
1351 * end
1352 * end
1353 *
1354 */
1355static VALUE
1356bind_implicit_parameter_defined_p(VALUE bindval, VALUE sym)
1357{
1358 ID lid = check_local_id(bindval, &sym);
1359 const rb_binding_t *bind;
1360 const rb_env_t *env;
1361
1362 if (lid == idIt) lid = idItImplicit;
1363
1364 if (!lid || !rb_implicit_param_p(lid)) {
1365 rb_name_err_raise("'%1$s' is not an implicit parameter",
1366 bindval, sym);
1367 }
1368
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));
1372}
1373
1374/*
1375 * call-seq:
1376 * binding.receiver -> object
1377 *
1378 * Returns the bound receiver of the binding object.
1379 */
1380static VALUE
1381bind_receiver(VALUE bindval)
1382{
1383 const rb_binding_t *bind;
1384 GetBindingPtr(bindval, bind);
1385 return vm_block_self(&bind->block);
1386}
1387
1388/*
1389 * call-seq:
1390 * binding.source_location -> [String, Integer]
1391 *
1392 * Returns the Ruby source filename and line number of the binding object.
1393 */
1394static VALUE
1395bind_location(VALUE bindval)
1396{
1397 VALUE loc[2];
1398 const rb_binding_t *bind;
1399 GetBindingPtr(bindval, bind);
1400 loc[0] = pathobj_path(bind->pathobj);
1401 loc[1] = INT2FIX(bind->first_lineno);
1402
1403 return rb_ary_new4(2, loc);
1404}
1405
1406static VALUE
1407cfunc_proc_new(VALUE klass, VALUE ifunc)
1408{
1409 rb_proc_t *proc;
1410 cfunc_proc_t *sproc;
1411 VALUE procval = TypedData_Make_Struct(klass, cfunc_proc_t, &proc_data_type, sproc);
1412 VALUE *ep;
1413
1414 proc = &sproc->basic;
1415 vm_block_type_set(&proc->block, block_type_ifunc);
1416
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; /* envval */
1422
1423 /* self? */
1424 RB_OBJ_WRITE(procval, &proc->block.as.captured.code.ifunc, ifunc);
1425 proc->header.is_lambda = TRUE;
1426 return procval;
1427}
1428
1429VALUE
1430rb_func_proc_dup(VALUE src_obj)
1431{
1432 RUBY_ASSERT(rb_typeddata_is_instance_of(src_obj, &proc_data_type));
1433
1434 rb_proc_t *src_proc;
1435 GetProcPtr(src_obj, src_proc);
1436 RUBY_ASSERT(vm_block_type(&src_proc->block) == block_type_ifunc);
1437
1438 cfunc_proc_t *proc;
1439 VALUE proc_obj = TypedData_Make_Struct(rb_obj_class(src_obj), cfunc_proc_t, &proc_data_type, proc);
1440
1441 memcpy(&proc->basic, src_proc, sizeof(rb_proc_t));
1442 RB_OBJ_WRITTEN(proc_obj, Qundef, proc->basic.block.as.captured.self);
1443 RB_OBJ_WRITTEN(proc_obj, Qundef, proc->basic.block.as.captured.code.val);
1444
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]);
1452 }
1453 else {
1454 rb_vm_block_ep_update(proc_obj, &proc->basic.block, src_ep);
1455 }
1456
1457 return proc_obj;
1458}
1459
1460static VALUE
1461sym_proc_new(VALUE klass, VALUE sym)
1462{
1463 VALUE procval = rb_proc_alloc(klass, block_type_symbol);
1464 rb_proc_t *proc;
1465 GetProcPtr(procval, proc);
1466
1467 vm_block_type_set(&proc->block, block_type_symbol);
1468 proc->header.is_lambda = TRUE;
1469 RB_OBJ_WRITE(procval, &proc->symbol.symbol, sym);
1470 return procval;
1471}
1472
1473struct vm_ifunc *
1474rb_vm_ifunc_new(rb_block_call_func_t func, const void *data, int min_argc, int max_argc)
1475{
1476 if (min_argc < UNLIMITED_ARGUMENTS ||
1477#if SIZEOF_INT * 2 > SIZEOF_VALUE
1478 min_argc >= (int)(1U << (SIZEOF_VALUE * CHAR_BIT) / 2) ||
1479#endif
1480 0) {
1481 rb_raise(rb_eRangeError, "minimum argument number out of range: %d",
1482 min_argc);
1483 }
1484 if (max_argc < UNLIMITED_ARGUMENTS ||
1485#if SIZEOF_INT * 2 > SIZEOF_VALUE
1486 max_argc >= (int)(1U << (SIZEOF_VALUE * CHAR_BIT) / 2) ||
1487#endif
1488 0) {
1489 rb_raise(rb_eRangeError, "maximum argument number out of range: %d",
1490 max_argc);
1491 }
1492 rb_execution_context_t *ec = GET_EC();
1493
1494 struct vm_ifunc *ifunc = IMEMO_NEW(struct vm_ifunc, imemo_ifunc, (VALUE)rb_vm_svar_lep(ec, ec->cfp));
1495
1496 rb_gc_register_pinning_obj((VALUE)ifunc);
1497
1498 ifunc->func = func;
1499 ifunc->data = data;
1500 ifunc->argc.min = min_argc;
1501 ifunc->argc.max = max_argc;
1502
1503 return ifunc;
1504}
1505
1506VALUE
1507rb_func_lambda_new(rb_block_call_func_t func, VALUE val, int min_argc, int max_argc)
1508{
1509 struct vm_ifunc *ifunc = rb_vm_ifunc_new(func, (void *)val, min_argc, max_argc);
1510 return cfunc_proc_new(rb_cProc, (VALUE)ifunc);
1511}
1512
1513static const char proc_without_block[] = "tried to create Proc object without a block";
1514
1515static VALUE
1516proc_new(VALUE klass, int8_t is_lambda)
1517{
1518 VALUE procval;
1519 const rb_execution_context_t *ec = GET_EC();
1520 rb_control_frame_t *cfp = ec->cfp;
1521 VALUE block_handler;
1522
1523 if ((block_handler = rb_vm_frame_block_handler(cfp)) == VM_BLOCK_HANDLER_NONE) {
1524 rb_raise(rb_eArgError, proc_without_block);
1525 }
1526
1527 /* block is in cf */
1528 switch (vm_block_handler_type(block_handler)) {
1529 case block_handler_type_proc:
1530 procval = VM_BH_TO_PROC(block_handler);
1531
1532 if (RBASIC_CLASS(procval) == klass) {
1533 return procval;
1534 }
1535 else {
1536 VALUE newprocval = rb_proc_dup(procval);
1537 RBASIC_SET_CLASS(newprocval, klass);
1538 return newprocval;
1539 }
1540 break;
1541
1542 case block_handler_type_symbol:
1543 return (klass != rb_cProc) ?
1544 sym_proc_new(klass, VM_BH_TO_SYMBOL(block_handler)) :
1545 rb_sym_to_proc(VM_BH_TO_SYMBOL(block_handler));
1546 break;
1547
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);
1551 }
1552 VM_UNREACHABLE(proc_new);
1553 return Qnil;
1554}
1555
1556/*
1557 * call-seq:
1558 * Proc.new {|...| block } -> a_proc
1559 *
1560 * Creates a new Proc object, bound to the current context.
1561 *
1562 * proc = Proc.new { "hello" }
1563 * proc.call #=> "hello"
1564 *
1565 * Raises ArgumentError if called without a block.
1566 *
1567 * Proc.new #=> ArgumentError
1568 */
1569
1570static VALUE
1571rb_proc_s_new(int argc, VALUE *argv, VALUE klass)
1572{
1573 VALUE block = proc_new(klass, FALSE);
1574
1575 rb_obj_call_init_kw(block, argc, argv, RB_PASS_CALLED_KEYWORDS);
1576 return block;
1577}
1578
1579VALUE
1581{
1582 return proc_new(rb_cProc, FALSE);
1583}
1584
1585/*
1586 * call-seq:
1587 * proc { |...| block } -> a_proc
1588 *
1589 * Equivalent to Proc.new.
1590 */
1591
1592static VALUE
1593f_proc(VALUE _)
1594{
1595 return proc_new(rb_cProc, FALSE);
1596}
1597
1598VALUE
1600{
1601 return proc_new(rb_cProc, TRUE);
1602}
1603
1604static void
1605f_lambda_filter_non_literal(void)
1606{
1607 rb_control_frame_t *cfp = GET_EC()->cfp;
1608 VALUE block_handler = rb_vm_frame_block_handler(cfp);
1609
1610 if (block_handler == VM_BLOCK_HANDLER_NONE) {
1611 // no block error raised else where
1612 return;
1613 }
1614
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) {
1618 return;
1619 }
1620 break;
1621 case block_handler_type_symbol:
1622 return;
1623 case block_handler_type_proc:
1624 if (rb_proc_lambda_p(VM_BH_TO_PROC(block_handler))) {
1625 return;
1626 }
1627 break;
1628 case block_handler_type_ifunc:
1629 break;
1630 }
1631
1632 rb_raise(rb_eArgError, "the lambda method requires a literal block");
1633}
1634
1635/*
1636 * call-seq:
1637 * lambda { |...| block } -> a_proc
1638 *
1639 * Equivalent to Proc.new, except the resulting Proc objects check the
1640 * number of parameters passed when called.
1641 */
1642
1643static VALUE
1644f_lambda(VALUE _)
1645{
1646 f_lambda_filter_non_literal();
1647 return rb_block_lambda();
1648}
1649
1650/* Document-method: Proc#===
1651 *
1652 * call-seq:
1653 * proc === obj -> result_of_proc
1654 *
1655 * Invokes the block with +obj+ as the proc's parameter like Proc#call.
1656 * This allows a proc object to be the target of a +when+ clause
1657 * in a case statement.
1658 */
1659
1660/* CHECKME: are the argument checking semantics correct? */
1661
1662/*
1663 * Document-method: Proc#[]
1664 * Document-method: Proc#call
1665 * Document-method: Proc#yield
1666 *
1667 * call-seq:
1668 * call(...) -> obj
1669 * self[...] -> obj
1670 * yield(...) -> obj
1671 *
1672 * Invokes the block, setting the block's parameters to the arguments
1673 * using something close to method calling semantics.
1674 * Returns the value of the last expression evaluated in the block.
1675 *
1676 * a_proc = Proc.new {|scalar, *values| values.map {|value| value*scalar } }
1677 * a_proc.call(9, 1, 2, 3) #=> [9, 18, 27]
1678 * a_proc[9, 1, 2, 3] #=> [9, 18, 27]
1679 * a_proc.(9, 1, 2, 3) #=> [9, 18, 27]
1680 * a_proc.yield(9, 1, 2, 3) #=> [9, 18, 27]
1681 *
1682 * Note that <code>prc.()</code> invokes <code>prc.call()</code> with
1683 * the parameters given. It's syntactic sugar to hide "call".
1684 *
1685 * For procs created using #lambda or <code>->()</code> an error is
1686 * generated if the wrong number of parameters are passed to the
1687 * proc. For procs created using Proc.new or Kernel.proc, extra
1688 * parameters are silently discarded and missing parameters are set
1689 * to +nil+.
1690 *
1691 * a_proc = proc {|a,b| [a,b] }
1692 * a_proc.call(1) #=> [1, nil]
1693 *
1694 * a_proc = lambda {|a,b| [a,b] }
1695 * a_proc.call(1) # ArgumentError: wrong number of arguments (given 1, expected 2)
1696 *
1697 * See also Proc#lambda?.
1698 */
1699#if 0
1700static VALUE
1701proc_call(int argc, VALUE *argv, VALUE procval)
1702{
1703 /* removed */
1704}
1705#endif
1706
1707#if SIZEOF_LONG > SIZEOF_INT
1708static inline int
1709check_argc(long argc)
1710{
1711 if (argc > INT_MAX || argc < 0) {
1712 rb_raise(rb_eArgError, "too many arguments (%lu)",
1713 (unsigned long)argc);
1714 }
1715 return (int)argc;
1716}
1717#else
1718#define check_argc(argc) (argc)
1719#endif
1720
1721VALUE
1722rb_proc_call_kw(VALUE self, VALUE args, int kw_splat)
1723{
1724 VALUE vret;
1725 rb_proc_t *proc;
1726 int argc = check_argc(RARRAY_LEN(args));
1727
1728 // rb_vm_invoke_proc may end up modifying argv as part of calling and so we
1729 // must use RARRAY_PTR, which marks the array as WB_UNPROTECTED instead of
1730 // RARRAY_CONST_PTR. Unfortunately this is worse for GC.
1731 // See invoke_block_from_c_proc
1732 VALUE *argv = RARRAY_PTR(args);
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));
1737 RB_GC_GUARD(self);
1738 RB_GC_GUARD(args);
1739 return vret;
1740}
1741
1742VALUE
1744{
1745 return rb_proc_call_kw(self, args, RB_NO_KEYWORDS);
1746}
1747
1748static VALUE
1749proc_to_block_handler(VALUE procval)
1750{
1751 return NIL_P(procval) ? VM_BLOCK_HANDLER_NONE : procval;
1752}
1753
1754VALUE
1755rb_proc_call_with_block_kw(VALUE self, int argc, const VALUE *argv, VALUE passed_procval, int kw_splat)
1756{
1757 rb_execution_context_t *ec = GET_EC();
1758 VALUE vret;
1759 rb_proc_t *proc;
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));
1763 RB_GC_GUARD(self);
1764 return vret;
1765}
1766
1767VALUE
1768rb_proc_call_with_block(VALUE self, int argc, const VALUE *argv, VALUE passed_procval)
1769{
1770 return rb_proc_call_with_block_kw(self, argc, argv, passed_procval, RB_NO_KEYWORDS);
1771}
1772
1773
1774/*
1775 * call-seq:
1776 * prc.arity -> integer
1777 *
1778 * Returns the number of mandatory arguments. If the block
1779 * is declared to take no arguments, returns 0. If the block is known
1780 * to take exactly n arguments, returns n.
1781 * If the block has optional arguments, returns -n-1, where n is the
1782 * number of mandatory arguments, with the exception for blocks that
1783 * are not lambdas and have only a finite number of optional arguments;
1784 * in this latter case, returns n.
1785 * Keyword arguments will be considered as a single additional argument,
1786 * that argument being mandatory if any keyword argument is mandatory.
1787 * A #proc with no argument declarations is the same as a block
1788 * declaring <code>||</code> as its arguments.
1789 *
1790 * proc {}.arity #=> 0
1791 * proc { || }.arity #=> 0
1792 * proc { |a| }.arity #=> 1
1793 * proc { |a, b| }.arity #=> 2
1794 * proc { |a, b, c| }.arity #=> 3
1795 * proc { |*a| }.arity #=> -1
1796 * proc { |a, *b| }.arity #=> -2
1797 * proc { |a, *b, c| }.arity #=> -3
1798 * proc { |x:, y:, z:0| }.arity #=> 1
1799 * proc { |*a, x:, y:0| }.arity #=> -2
1800 *
1801 * proc { |a=0| }.arity #=> 0
1802 * lambda { |a=0| }.arity #=> -1
1803 * proc { |a=0, b| }.arity #=> 1
1804 * lambda { |a=0, b| }.arity #=> -2
1805 * proc { |a=0, b=0| }.arity #=> 0
1806 * lambda { |a=0, b=0| }.arity #=> -1
1807 * proc { |a, b=0| }.arity #=> 1
1808 * lambda { |a, b=0| }.arity #=> -2
1809 * proc { |(a, b), c=0| }.arity #=> 1
1810 * lambda { |(a, b), c=0| }.arity #=> -2
1811 * proc { |a, x:0, y:0| }.arity #=> 1
1812 * lambda { |a, x:0, y:0| }.arity #=> -2
1813 */
1814
1815static VALUE
1816proc_arity(VALUE self)
1817{
1818 int arity = rb_proc_arity(self);
1819 return INT2FIX(arity);
1820}
1821
1822static inline int
1823rb_iseq_min_max_arity(const rb_iseq_t *iseq, int *max)
1824{
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);
1830}
1831
1832static int
1833rb_vm_block_min_max_arity(const struct rb_block *block, int *max)
1834{
1835 again:
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);
1841 goto again;
1842 case block_type_ifunc:
1843 {
1844 const struct vm_ifunc *ifunc = block->as.captured.code.ifunc;
1845 if (IS_METHOD_PROC_IFUNC(ifunc)) {
1846 /* e.g. method(:foo).to_proc.arity */
1847 return method_min_max_arity((VALUE)ifunc->data, max);
1848 }
1849 *max = ifunc->argc.max;
1850 return ifunc->argc.min;
1851 }
1852 case block_type_symbol:
1853 *max = UNLIMITED_ARGUMENTS;
1854 return 1;
1855 }
1856 *max = UNLIMITED_ARGUMENTS;
1857 return 0;
1858}
1859
1860/*
1861 * Returns the number of required parameters and stores the maximum
1862 * number of parameters in max, or UNLIMITED_ARGUMENTS if no max.
1863 * For non-lambda procs, the maximum is the number of non-ignored
1864 * parameters even though there is no actual limit to the number of parameters
1865 */
1866static int
1867rb_proc_min_max_arity(VALUE self, int *max)
1868{
1869 rb_proc_t *proc;
1870 GetProcPtr(self, proc);
1871 return rb_vm_block_min_max_arity(&proc->block, max);
1872}
1873
1874int
1876{
1877 rb_proc_t *proc;
1878 int max, min;
1879 GetProcPtr(self, proc);
1880 min = rb_vm_block_min_max_arity(&proc->block, &max);
1881 return (proc->header.is_lambda ? min == max : max != UNLIMITED_ARGUMENTS) ? min : -min-1;
1882}
1883
1884static void
1885block_setup(struct rb_block *block, VALUE block_handler)
1886{
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);
1891 break;
1892 case block_handler_type_ifunc:
1893 block->type = block_type_ifunc;
1894 block->as.captured = *VM_BH_TO_IFUNC_BLOCK(block_handler);
1895 break;
1896 case block_handler_type_symbol:
1897 block->type = block_type_symbol;
1898 block->as.symbol = VM_BH_TO_SYMBOL(block_handler);
1899 break;
1900 case block_handler_type_proc:
1901 block->type = block_type_proc;
1902 block->as.proc = VM_BH_TO_PROC(block_handler);
1903 }
1904}
1905
1906int
1907rb_block_pair_yield_optimizable(void)
1908{
1909 int min, max;
1910 const rb_execution_context_t *ec = GET_EC();
1911 rb_control_frame_t *cfp = ec->cfp;
1912 VALUE block_handler = rb_vm_frame_block_handler(cfp);
1913 struct rb_block block;
1914
1915 if (block_handler == VM_BLOCK_HANDLER_NONE) {
1916 rb_raise(rb_eArgError, "no block given");
1917 }
1918
1919 block_setup(&block, block_handler);
1920 min = rb_vm_block_min_max_arity(&block, &max);
1921
1922 switch (vm_block_type(&block)) {
1923 case block_type_symbol:
1924 return 0;
1925
1926 case block_type_proc:
1927 {
1928 VALUE procval = block_handler;
1929 rb_proc_t *proc;
1930 GetProcPtr(procval, proc);
1931 if (proc->header.is_lambda) return 0;
1932 if (min != max) return 0;
1933 return min > 1;
1934 }
1935
1936 case block_type_ifunc:
1937 {
1938 const struct vm_ifunc *ifunc = block.as.captured.code.ifunc;
1939 if (ifunc->flags & IFUNC_YIELD_OPTIMIZABLE) return 1;
1940 }
1941
1942 default:
1943 return min > 1;
1944 }
1945}
1946
1947int
1948rb_block_arity(void)
1949{
1950 int min, max;
1951 const rb_execution_context_t *ec = GET_EC();
1952 rb_control_frame_t *cfp = ec->cfp;
1953 VALUE block_handler = rb_vm_frame_block_handler(cfp);
1954 struct rb_block block;
1955
1956 if (block_handler == VM_BLOCK_HANDLER_NONE) {
1957 rb_raise(rb_eArgError, "no block given");
1958 }
1959
1960 block_setup(&block, block_handler);
1961
1962 switch (vm_block_type(&block)) {
1963 case block_type_symbol:
1964 return -1;
1965
1966 case block_type_proc:
1967 return rb_proc_arity(block_handler);
1968
1969 default:
1970 min = rb_vm_block_min_max_arity(&block, &max);
1971 return max != UNLIMITED_ARGUMENTS ? min : -min-1;
1972 }
1973}
1974
1975int
1976rb_block_min_max_arity(int *max)
1977{
1978 const rb_execution_context_t *ec = GET_EC();
1979 rb_control_frame_t *cfp = ec->cfp;
1980 VALUE block_handler = rb_vm_frame_block_handler(cfp);
1981 struct rb_block block;
1982
1983 if (block_handler == VM_BLOCK_HANDLER_NONE) {
1984 rb_raise(rb_eArgError, "no block given");
1985 }
1986
1987 block_setup(&block, block_handler);
1988 return rb_vm_block_min_max_arity(&block, max);
1989}
1990
1991const rb_iseq_t *
1992rb_proc_get_iseq(VALUE self, int *is_proc)
1993{
1994 const rb_proc_t *proc;
1995 const struct rb_block *block;
1996
1997 GetProcPtr(self, proc);
1998 block = &proc->block;
1999 if (is_proc) *is_proc = !proc->header.is_lambda;
2000
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:
2007 {
2008 const struct vm_ifunc *ifunc = block->as.captured.code.ifunc;
2009 if (IS_METHOD_PROC_IFUNC(ifunc)) {
2010 /* method(:foo).to_proc */
2011 if (is_proc) *is_proc = 0;
2012 return rb_method_iseq((VALUE)ifunc->data);
2013 }
2014 else {
2015 return NULL;
2016 }
2017 }
2018 case block_type_symbol:
2019 return NULL;
2020 }
2021
2022 VM_UNREACHABLE(rb_proc_get_iseq);
2023 return NULL;
2024}
2025
2026/* call-seq:
2027 * self == other -> true or false
2028 * eql?(other) -> true or false
2029 *
2030 * Returns whether +self+ and +other+ were created from the same code block:
2031 *
2032 * def return_block(&block)
2033 * block
2034 * end
2035 *
2036 * def pass_block_twice(&block)
2037 * [return_block(&block), return_block(&block)]
2038 * end
2039 *
2040 * block1, block2 = pass_block_twice { puts 'test' }
2041 * # Blocks might be instantiated into Proc's lazily, so they may, or may not,
2042 * # be the same object.
2043 * # But they are produced from the same code block, so they are equal
2044 * block1 == block2
2045 * #=> true
2046 *
2047 * # Another Proc will never be equal, even if the code is the "same"
2048 * block1 == proc { puts 'test' }
2049 * #=> false
2050 *
2051 */
2052VALUE
2053rb_proc_eq(VALUE self, VALUE other)
2054{
2055 const rb_proc_t *self_proc, *other_proc;
2056 const struct rb_block *self_block, *other_block;
2057
2058 if (rb_obj_class(self) != rb_obj_class(other)) {
2059 return Qfalse;
2060 }
2061
2062 GetProcPtr(self, self_proc);
2063 GetProcPtr(other, other_proc);
2064
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) {
2068 return Qfalse;
2069 }
2070
2071 self_block = &self_proc->block;
2072 other_block = &other_proc->block;
2073
2074 if (vm_block_type(self_block) != vm_block_type(other_block)) {
2075 return Qfalse;
2076 }
2077
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) {
2082 return Qfalse;
2083 }
2084 /* a refined Proc's block iseq flips from the source to the copy on
2085 * the first call; compare what the Procs were built from instead */
2086 if (self_proc->header.is_refined) {
2087 if (!refinement_recipe_eq(rb_proc_refinements_recipe(self),
2088 rb_proc_refinements_recipe(other))) {
2089 return Qfalse;
2090 }
2091 }
2092 else if (self_block->as.captured.code.iseq != \
2093 other_block->as.captured.code.iseq) {
2094 return Qfalse;
2095 }
2096 break;
2097 case block_type_ifunc:
2098 if (self_block->as.captured.code.ifunc != \
2099 other_block->as.captured.code.ifunc) {
2100 return Qfalse;
2101 }
2102
2103 if (memcmp(
2104 ((cfunc_proc_t *)self_proc)->env,
2105 ((cfunc_proc_t *)other_proc)->env,
2106 sizeof(((cfunc_proc_t *)self_proc)->env))) {
2107 return Qfalse;
2108 }
2109 break;
2110 case block_type_proc:
2111 if (self_block->as.proc != other_block->as.proc) {
2112 return Qfalse;
2113 }
2114 break;
2115 case block_type_symbol:
2116 if (self_block->as.symbol != other_block->as.symbol) {
2117 return Qfalse;
2118 }
2119 break;
2120 }
2121
2122 return Qtrue;
2123}
2124
2125static VALUE
2126iseq_location(const rb_iseq_t *iseq)
2127{
2128 VALUE loc[2];
2129
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);
2134
2135 return rb_ary_new4(2, loc);
2136}
2137
2138VALUE
2139rb_iseq_location(const rb_iseq_t *iseq)
2140{
2141 return iseq_location(iseq);
2142}
2143
2144/*
2145 * call-seq:
2146 * prc.source_location -> [String, Integer]
2147 *
2148 * Returns the Ruby source filename and line number containing this proc
2149 * or +nil+ if this proc was not defined in Ruby (i.e. native).
2150 */
2151
2152VALUE
2153rb_proc_location(VALUE self)
2154{
2155 return iseq_location(rb_proc_get_iseq(self, 0));
2156}
2157
2158/*
2159 * call-seq:
2160 * prc.source_range -> Ruby::SourceRange or nil
2161 *
2162 * Returns a Ruby::SourceRange for this proc, or +nil+ if this proc was
2163 * not defined in Ruby (i.e. native) or has no source path.
2164 *
2165 * The returned Ruby::SourceRange includes the source path, absolute path when
2166 * available, and the start and end line and byte-column coordinates.
2167 *
2168 * See https://github.com/ruby/spec/blob/master/core/proc/source_range_spec.rb
2169 * for the location of start/end line/column in various cases.
2170 */
2171static VALUE
2172rb_proc_source_range(VALUE self)
2173{
2174 return source_range_new(rb_proc_get_iseq(self, 0));
2175}
2176
2177VALUE
2178rb_unnamed_parameters(int arity)
2179{
2180 VALUE a, param = rb_ary_new2((arity < 0) ? -arity : arity);
2181 int n = (arity < 0) ? ~arity : arity;
2182 ID req, rest;
2183 CONST_ID(req, "req");
2184 a = rb_ary_new3(1, ID2SYM(req));
2185 OBJ_FREEZE(a);
2186 for (; n; --n) {
2187 rb_ary_push(param, a);
2188 }
2189 if (arity < 0) {
2190 CONST_ID(rest, "rest");
2191 rb_ary_store(param, ~arity, rb_ary_new3(1, ID2SYM(rest)));
2192 }
2193 return param;
2194}
2195
2196/*
2197 * call-seq:
2198 * prc.parameters(lambda: nil) -> array
2199 *
2200 * Returns the parameter information of this proc. If the lambda
2201 * keyword is provided and not nil, treats the proc as a lambda if
2202 * true and as a non-lambda if false.
2203 *
2204 * prc = proc{|x, y=42, *other|}
2205 * prc.parameters #=> [[:opt, :x], [:opt, :y], [:rest, :other]]
2206 * prc = lambda{|x, y=42, *other|}
2207 * prc.parameters #=> [[:req, :x], [:opt, :y], [:rest, :other]]
2208 * prc = proc{|x, y=42, *other|}
2209 * prc.parameters(lambda: true) #=> [[:req, :x], [:opt, :y], [:rest, :other]]
2210 * prc = lambda{|x, y=42, *other|}
2211 * prc.parameters(lambda: false) #=> [[:opt, :x], [:opt, :y], [:rest, :other]]
2212 */
2213
2214static VALUE
2215rb_proc_parameters(int argc, VALUE *argv, VALUE self)
2216{
2217 static ID keyword_ids[1];
2218 VALUE opt, lambda;
2219 VALUE kwargs[1];
2220 int is_proc ;
2221 const rb_iseq_t *iseq;
2222
2223 iseq = rb_proc_get_iseq(self, &is_proc);
2224
2225 if (!keyword_ids[0]) {
2226 CONST_ID(keyword_ids[0], "lambda");
2227 }
2228
2229 rb_scan_args(argc, argv, "0:", &opt);
2230 if (!NIL_P(opt)) {
2231 rb_get_kwargs(opt, keyword_ids, 0, 1, kwargs);
2232 lambda = kwargs[0];
2233 if (!NIL_P(lambda)) {
2234 is_proc = !RTEST(lambda);
2235 }
2236 }
2237
2238 if (!iseq) {
2239 return rb_unnamed_parameters(rb_proc_arity(self));
2240 }
2241 return rb_iseq_parameters(iseq, is_proc);
2242}
2243
2244static st_index_t
2245iseq_location_hash(st_index_t hash, const rb_iseq_t *iseq)
2246{
2247 const struct rb_iseq_constant_body *body = ISEQ_BODY(iseq);
2248 if (body) {
2249 const rb_iseq_location_t *loc = &body->location;
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);
2254 }
2255 return hash;
2256}
2257
2258st_index_t
2259rb_hash_proc(st_index_t hash, VALUE prc)
2260{
2261 rb_proc_t *proc;
2262 GetProcPtr(prc, proc);
2263
2264 switch (vm_block_type(&proc->block)) {
2265 case block_type_iseq:
2266 if (proc->header.is_refined) {
2267 /* from the recipe, not the block iseq: the latter flips from the
2268 * source to the copy on the first call, and the hash must not */
2269 VALUE recipe = rb_proc_refinements_recipe(prc);
2270 long len = RARRAY_LEN(recipe);
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));
2275 }
2276 }
2277 else {
2278 hash = iseq_location_hash(hash, proc->block.as.captured.code.iseq);
2279 }
2280 break;
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);
2284 break;
2285 case block_type_symbol:
2286 hash = rb_st_hash_uint(hash, rb_any_hash(proc->block.as.symbol));
2287 break;
2288 case block_type_proc:
2289 hash = rb_st_hash_uint(hash, rb_any_hash(proc->block.as.proc));
2290 break;
2291 default:
2292 rb_bug("rb_hash_proc: unknown block type %d", vm_block_type(&proc->block));
2293 }
2294
2295 /* ifunc procs have their own allocated ep. If an ifunc is duplicated, they
2296 * will point to different ep but they should return the same hash code, so
2297 * we cannot include the ep in the hash. Symbol and proc type blocks are
2298 * smaller and do not have an ep at all. */
2299 if (vm_block_type(&proc->block) == block_type_iseq) {
2300 hash = rb_hash_uint(hash, (st_index_t)proc->block.as.captured.ep);
2301 }
2302
2303 return hash;
2304}
2305
2306static VALUE sym_proc_cache = Qfalse;
2307
2308/*
2309 * call-seq:
2310 * to_proc
2311 *
2312 * Returns a Proc object which calls the method with name of +self+
2313 * on the first parameter and passes the remaining parameters to the method.
2314 *
2315 * proc = :to_s.to_proc # => #<Proc:0x000001afe0e48680(&:to_s) (lambda)>
2316 * proc.call(1000) # => "1000"
2317 * proc.call(1000, 16) # => "3e8"
2318 * (1..3).collect(&:to_s) # => ["1", "2", "3"]
2319 *
2320 */
2321
2322VALUE
2323rb_sym_to_proc(VALUE sym)
2324{
2325 enum {SYM_PROC_CACHE_SIZE = 67};
2326
2327 if (rb_ractor_main_p()) {
2328 if (!sym_proc_cache) {
2329 sym_proc_cache = rb_ary_hidden_new(SYM_PROC_CACHE_SIZE);
2330 rb_ary_store(sym_proc_cache, SYM_PROC_CACHE_SIZE - 1, Qnil);
2331 }
2332
2333 ID id = SYM2ID(sym);
2334 long index = (id % SYM_PROC_CACHE_SIZE);
2335 VALUE procval = RARRAY_AREF(sym_proc_cache, index);
2336 if (RTEST(procval)) {
2337 rb_proc_t *proc;
2338 GetProcPtr(procval, proc);
2339
2340 if (proc->block.as.symbol == sym) {
2341 return procval;
2342 }
2343 }
2344
2345 procval = sym_proc_new(rb_cProc, sym);
2346 RARRAY_ASET(sym_proc_cache, index, procval);
2347
2348 return RB_GC_GUARD(procval);
2349 }
2350 else {
2351 return sym_proc_new(rb_cProc, sym);
2352 }
2353}
2354
2355/*
2356 * call-seq:
2357 * prc.hash -> integer
2358 *
2359 * Returns a hash value corresponding to proc body.
2360 *
2361 * See also Object#hash.
2362 */
2363
2364static VALUE
2365proc_hash(VALUE self)
2366{
2367 st_index_t hash;
2368 hash = rb_hash_start(0);
2369 hash = rb_hash_proc(hash, self);
2370 hash = rb_hash_end(hash);
2371 return ST2FIX(hash);
2372}
2373
2374VALUE
2375rb_block_to_s(VALUE self, const struct rb_block *block, const char *additional_info)
2376{
2377 VALUE cname = rb_obj_class(self);
2378 VALUE str = rb_sprintf("#<%"PRIsVALUE":", cname);
2379
2380 again:
2381 switch (vm_block_type(block)) {
2382 case block_type_proc:
2383 block = vm_proc_block(block->as.proc);
2384 goto again;
2385 case block_type_iseq:
2386 {
2387 const rb_iseq_t *iseq = rb_iseq_check(block->as.captured.code.iseq);
2388 rb_str_catf(str, "%p %"PRIsVALUE":%d", (void *)self,
2389 rb_iseq_path(iseq),
2390 ISEQ_BODY(iseq)->location.first_lineno);
2391 }
2392 break;
2393 case block_type_symbol:
2394 rb_str_catf(str, "%p(&%+"PRIsVALUE")", (void *)self, block->as.symbol);
2395 break;
2396 case block_type_ifunc:
2397 rb_str_catf(str, "%p", (void *)block->as.captured.code.ifunc);
2398 break;
2399 }
2400
2401 if (additional_info) rb_str_cat_cstr(str, additional_info);
2402 rb_str_cat_cstr(str, ">");
2403 return str;
2404}
2405
2406/*
2407 * call-seq:
2408 * prc.to_s -> string
2409 *
2410 * Returns the unique identifier for this proc, along with
2411 * an indication of where the proc was defined.
2412 */
2413
2414static VALUE
2415proc_to_s(VALUE self)
2416{
2417 const rb_proc_t *proc;
2418 GetProcPtr(self, proc);
2419 return rb_block_to_s(self, &proc->block, proc->header.is_lambda ? " (lambda)" : NULL);
2420}
2421
2422/*
2423 * call-seq:
2424 * prc.to_proc -> proc
2425 *
2426 * Part of the protocol for converting objects to Proc objects.
2427 * Instances of class Proc simply return themselves.
2428 */
2429
2430static VALUE
2431proc_to_proc(VALUE self)
2432{
2433 return self;
2434}
2435
2436static void
2437bm_mark_and_move(void *ptr)
2438{
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);
2444 rb_gc_mark_and_move_ptr((rb_method_entry_t **)&data->me);
2445}
2446
2447static const rb_data_type_t method_data_type = {
2448 "method",
2449 {
2450 bm_mark_and_move,
2452 NULL, // No external memory to report,
2453 bm_mark_and_move,
2454 },
2455 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE | RUBY_TYPED_FROZEN_SHAREABLE_NO_REC
2456};
2457
2458VALUE
2460{
2461 return RBOOL(rb_typeddata_is_kind_of(m, &method_data_type));
2462}
2463
2464static int
2465respond_to_missing_p(VALUE klass, VALUE obj, VALUE sym, int scope)
2466{
2467 /* TODO: merge with obj_respond_to() */
2468 ID rmiss = idRespond_to_missing;
2469
2470 if (UNDEF_P(obj)) return 0;
2471 if (rb_method_basic_definition_p(klass, rmiss)) return 0;
2472 return RTEST(rb_funcall(obj, rmiss, 2, sym, RBOOL(!scope)));
2473}
2474
2475
2476static VALUE
2477mnew_missing(VALUE klass, VALUE obj, ID id, VALUE mclass)
2478{
2479 struct METHOD *data;
2480 VALUE method = TypedData_Make_Struct(mclass, struct METHOD, &method_data_type, data);
2483
2484 RB_OBJ_WRITE(method, &data->recv, obj);
2485 RB_OBJ_WRITE(method, &data->klass, klass);
2486 RB_OBJ_WRITE(method, &data->owner, klass);
2487
2489 def->type = VM_METHOD_TYPE_MISSING;
2490 def->original_id = id;
2491
2492 me = rb_method_entry_create(id, klass, METHOD_VISI_UNDEF, def);
2493
2494 RB_OBJ_WRITE(method, &data->me, me);
2495
2496 return method;
2497}
2498
2499static VALUE
2500mnew_missing_by_name(VALUE klass, VALUE obj, VALUE *name, int scope, VALUE mclass)
2501{
2502 VALUE vid = rb_str_intern(*name);
2503 *name = vid;
2504 if (!respond_to_missing_p(klass, obj, vid, scope)) return Qfalse;
2505 return mnew_missing(klass, obj, SYM2ID(vid), mclass);
2506}
2507
2508VALUE rb_zsuper_to_super(int argc, VALUE *argv, VALUE self);
2509
2510static VALUE
2511mnew_internal(const rb_method_entry_t *me, VALUE klass, VALUE iclass,
2512 VALUE obj, ID id, VALUE mclass, int scope, int error)
2513{
2514 struct METHOD *data;
2515 VALUE method;
2516 const rb_method_entry_t *original_me = me;
2517 rb_method_visibility_t visi = METHOD_VISI_UNDEF;
2518
2519 again:
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);
2523 }
2524 if (!error) return Qnil;
2525 rb_print_undef(klass, id, METHOD_VISI_UNDEF);
2526 }
2527 if (visi == METHOD_VISI_UNDEF) {
2528 visi = METHOD_ENTRY_VISI(me);
2529 RUBY_ASSERT(visi != METHOD_VISI_UNDEF); /* !UNDEFINED_METHOD_ENTRY_P(me) */
2530 if (scope && (visi != METHOD_VISI_PUBLIC)) {
2531 if (!error) return Qnil;
2532 rb_print_inaccessible(klass, id, visi);
2533 }
2534 }
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) {
2538 VALUE klass = RCLASS_SUPER(RCLASS_ORIGIN(me->defined_class));
2539 id = me->def->original_id;
2540 me = (rb_method_entry_t *)rb_callable_method_entry_with_refinements(klass, id, &iclass);
2541 }
2542 else {
2543 VALUE klass = RCLASS_SUPER(RCLASS_ORIGIN(me->owner));
2544 id = me->def->original_id;
2545 me = rb_method_entry_without_refinements(klass, id, &iclass);
2546 }
2547 goto again;
2548 }
2549
2550 method = TypedData_Make_Struct(mclass, struct METHOD, &method_data_type, data);
2551
2552 if (UNDEF_P(obj)) {
2553 RB_OBJ_WRITE(method, &data->recv, Qundef);
2554 RB_OBJ_WRITE(method, &data->klass, Qundef);
2555 }
2556 else {
2557 RB_OBJ_WRITE(method, &data->recv, obj);
2558 RB_OBJ_WRITE(method, &data->klass, klass);
2559 }
2560 RB_OBJ_WRITE(method, &data->iclass, iclass);
2561 RB_OBJ_WRITE(method, &data->owner, original_me->owner);
2562 RB_OBJ_WRITE(method, &data->me, me);
2563
2564 return method;
2565}
2566
2567static VALUE
2568mnew_from_me(const rb_method_entry_t *me, VALUE klass, VALUE iclass,
2569 VALUE obj, ID id, VALUE mclass, int scope)
2570{
2571 return mnew_internal(me, klass, iclass, obj, id, mclass, scope, TRUE);
2572}
2573
2574static VALUE
2575mnew_callable(VALUE klass, VALUE obj, ID id, VALUE mclass, int scope)
2576{
2577 const rb_method_entry_t *me;
2578 VALUE iclass = Qnil;
2579
2580 ASSUME(!UNDEF_P(obj));
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);
2583}
2584
2585static VALUE
2586mnew_unbound(VALUE klass, ID id, VALUE mclass, int scope)
2587{
2588 const rb_method_entry_t *me;
2589 VALUE iclass = Qnil;
2590
2591 me = rb_method_entry_with_refinements(klass, id, &iclass);
2592 return mnew_from_me(me, klass, iclass, Qundef, id, mclass, scope);
2593}
2594
2595static inline VALUE
2596method_entry_defined_class(const rb_method_entry_t *me)
2597{
2598 VALUE defined_class = me->defined_class;
2599 return defined_class ? defined_class : me->owner;
2600}
2601
2602/**********************************************************************
2603 *
2604 * Document-class: Method
2605 *
2606 * +Method+ objects are created by Object#method, and are associated
2607 * with a particular object (not just with a class). They may be
2608 * used to invoke the method within the object, and as a block
2609 * associated with an iterator. They may also be unbound from one
2610 * object (creating an UnboundMethod) and bound to another.
2611 *
2612 * class Thing
2613 * def square(n)
2614 * n*n
2615 * end
2616 * end
2617 * thing = Thing.new
2618 * meth = thing.method(:square)
2619 *
2620 * meth.call(9) #=> 81
2621 * [ 1, 2, 3 ].collect(&meth) #=> [1, 4, 9]
2622 *
2623 * [ 1, 2, 3 ].each(&method(:puts)) #=> prints 1, 2, 3
2624 *
2625 * require 'date'
2626 * %w[2017-03-01 2017-03-02].collect(&Date.method(:parse))
2627 * #=> [#<Date: 2017-03-01 ((2457814j,0s,0n),+0s,2299161j)>, #<Date: 2017-03-02 ((2457815j,0s,0n),+0s,2299161j)>]
2628 */
2629
2630/*
2631 * call-seq:
2632 * self == other -> true or false
2633 *
2634 * Returns whether +self+ and +other+ are bound to the same
2635 * object and refer to the same method definition and the classes
2636 * defining the methods are the same class or module.
2637 */
2638
2639static VALUE
2640method_eq(VALUE method, VALUE other)
2641{
2642 struct METHOD *m1, *m2;
2643 VALUE klass1, klass2;
2644
2645 if (!rb_obj_is_method(other))
2646 return Qfalse;
2647 if (CLASS_OF(method) != CLASS_OF(other))
2648 return Qfalse;
2649
2650 Check_TypedStruct(method, &method_data_type);
2651 m1 = (struct METHOD *)RTYPEDDATA_GET_DATA(method);
2652 m2 = (struct METHOD *)RTYPEDDATA_GET_DATA(other);
2653
2654 klass1 = method_entry_defined_class(m1->me);
2655 klass2 = method_entry_defined_class(m2->me);
2656 if (RB_TYPE_P(klass1, T_ICLASS)) klass1 = RBASIC_CLASS(klass1);
2657 if (RB_TYPE_P(klass2, T_ICLASS)) klass2 = RBASIC_CLASS(klass2);
2658
2659 if (!rb_method_entry_eq(m1->me, m2->me) ||
2660 klass1 != klass2 ||
2661 m1->klass != m2->klass ||
2662 m1->recv != m2->recv) {
2663 return Qfalse;
2664 }
2665
2666 return Qtrue;
2667}
2668
2669/*
2670 * call-seq:
2671 * meth.eql?(other_meth) -> true or false
2672 * meth == other_meth -> true or false
2673 *
2674 * Two unbound method objects are equal if they refer to the same
2675 * method definition.
2676 *
2677 * Array.instance_method(:each_slice) == Enumerable.instance_method(:each_slice)
2678 * #=> true
2679 *
2680 * Array.instance_method(:sum) == Enumerable.instance_method(:sum)
2681 * #=> false, Array redefines the method for efficiency
2682 */
2683#define unbound_method_eq method_eq
2684
2685/*
2686 * call-seq:
2687 * meth.hash -> integer
2688 *
2689 * Returns a hash value corresponding to the method object.
2690 *
2691 * See also Object#hash.
2692 */
2693
2694static VALUE
2695method_hash(VALUE method)
2696{
2697 struct METHOD *m;
2698 st_index_t hash;
2699
2700 TypedData_Get_Struct(method, struct METHOD, &method_data_type, m);
2701 hash = rb_hash_start((st_index_t)m->recv);
2702 hash = rb_hash_method_entry(hash, m->me);
2703 hash = rb_hash_end(hash);
2704
2705 return ST2FIX(hash);
2706}
2707
2708/*
2709 * call-seq:
2710 * meth.unbind -> unbound_method
2711 *
2712 * Dissociates <i>meth</i> from its current receiver. The resulting
2713 * UnboundMethod can subsequently be bound to a new object of the
2714 * same class (see UnboundMethod).
2715 */
2716
2717static VALUE
2718method_unbind(VALUE obj)
2719{
2720 VALUE method;
2721 struct METHOD *orig, *data;
2722
2723 TypedData_Get_Struct(obj, struct METHOD, &method_data_type, orig);
2725 &method_data_type, data);
2726 RB_OBJ_WRITE(method, &data->recv, Qundef);
2727 RB_OBJ_WRITE(method, &data->klass, Qundef);
2728 RB_OBJ_WRITE(method, &data->iclass, orig->iclass);
2729 RB_OBJ_WRITE(method, &data->owner, orig->me->owner);
2730 RB_OBJ_WRITE(method, &data->me, rb_method_entry_clone(orig->me));
2731
2732 return method;
2733}
2734
2735/*
2736 * call-seq:
2737 * meth.receiver -> object
2738 *
2739 * Returns the bound receiver of the method object.
2740 *
2741 * (1..3).method(:map).receiver # => 1..3
2742 */
2743
2744static VALUE
2745method_receiver(VALUE obj)
2746{
2747 struct METHOD *data;
2748
2749 TypedData_Get_Struct(obj, struct METHOD, &method_data_type, data);
2750 return data->recv;
2751}
2752
2753/*
2754 * call-seq:
2755 * meth.name -> symbol
2756 *
2757 * Returns the name of the method.
2758 */
2759
2760static VALUE
2761method_name(VALUE obj)
2762{
2763 struct METHOD *data;
2764
2765 TypedData_Get_Struct(obj, struct METHOD, &method_data_type, data);
2766 return ID2SYM(data->me->called_id);
2767}
2768
2769/*
2770 * call-seq:
2771 * meth.original_name -> symbol
2772 *
2773 * Returns the original name of the method.
2774 *
2775 * class C
2776 * def foo; end
2777 * alias bar foo
2778 * end
2779 * C.instance_method(:bar).original_name # => :foo
2780 */
2781
2782static VALUE
2783method_original_name(VALUE obj)
2784{
2785 struct METHOD *data;
2786
2787 TypedData_Get_Struct(obj, struct METHOD, &method_data_type, data);
2788 return ID2SYM(data->me->def->original_id);
2789}
2790
2791/*
2792 * call-seq:
2793 * meth.owner -> class_or_module
2794 *
2795 * Returns the class or module on which this method is defined.
2796 * In other words,
2797 *
2798 * meth.owner.instance_methods(false).include?(meth.name) # => true
2799 *
2800 * holds as long as the method is not removed/undefined/replaced,
2801 * (with private_instance_methods instead of instance_methods if the method
2802 * is private).
2803 *
2804 * See also Method#receiver.
2805 *
2806 * (1..3).method(:map).owner #=> Enumerable
2807 */
2808
2809static VALUE
2810method_owner(VALUE obj)
2811{
2812 struct METHOD *data;
2813 TypedData_Get_Struct(obj, struct METHOD, &method_data_type, data);
2814 return data->owner;
2815}
2816
2817/*
2818 * call-seq:
2819 * meth.box -> box or nil
2820 *
2821 * Returns the Ruby::Box where +meth+ is defined in.
2822 */
2823static VALUE
2824method_box(VALUE obj)
2825{
2826 struct METHOD *data;
2827 const rb_box_t *box;
2828
2829 TypedData_Get_Struct(obj, struct METHOD, &method_data_type, data);
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);
2835}
2836
2837void
2838rb_method_name_error(VALUE klass, VALUE str)
2839{
2840#define MSG(s) rb_fstring_lit("undefined method '%1$s' for"s" '%2$s'")
2841 VALUE c = klass;
2842 VALUE s = Qundef;
2843
2844 if (RCLASS_SINGLETON_P(c)) {
2845 VALUE obj = RCLASS_ATTACHED_OBJECT(klass);
2846
2847 switch (BUILTIN_TYPE(obj)) {
2848 case T_MODULE:
2849 case T_CLASS:
2850 c = obj;
2851 break;
2852 default:
2853 break;
2854 }
2855 }
2856 else if (RB_TYPE_P(c, T_MODULE)) {
2857 s = MSG(" module");
2858 }
2859 if (UNDEF_P(s)) {
2860 s = MSG(" class");
2861 }
2862 rb_name_err_raise_str(s, c, str);
2863#undef MSG
2864}
2865
2866static VALUE
2867obj_method(VALUE obj, VALUE vid, int scope)
2868{
2869 ID id = rb_check_id(&vid);
2870 const VALUE klass = CLASS_OF(obj);
2871 const VALUE mclass = rb_cMethod;
2872
2873 if (!id) {
2874 VALUE m = mnew_missing_by_name(klass, obj, &vid, scope, mclass);
2875 if (m) return m;
2876 rb_method_name_error(klass, vid);
2877 }
2878 return mnew_callable(klass, obj, id, mclass, scope);
2879}
2880
2881/*
2882 * call-seq:
2883 * obj.method(sym) -> method
2884 *
2885 * Looks up the named method as a receiver in <i>obj</i>, returning a
2886 * +Method+ object (or raising NameError). The +Method+ object acts as a
2887 * closure in <i>obj</i>'s object instance, so instance variables and
2888 * the value of <code>self</code> remain available.
2889 *
2890 * class Demo
2891 * def initialize(n)
2892 * @iv = n
2893 * end
2894 * def hello()
2895 * "Hello, @iv = #{@iv}"
2896 * end
2897 * end
2898 *
2899 * k = Demo.new(99)
2900 * m = k.method(:hello)
2901 * m.call #=> "Hello, @iv = 99"
2902 *
2903 * l = Demo.new('Fred')
2904 * m = l.method("hello")
2905 * m.call #=> "Hello, @iv = Fred"
2906 *
2907 * Note that +Method+ implements <code>to_proc</code> method, which
2908 * means it can be used with iterators.
2909 *
2910 * [ 1, 2, 3 ].each(&method(:puts)) # => prints 3 lines to stdout
2911 *
2912 * out = File.open('test.txt', 'w')
2913 * [ 1, 2, 3 ].each(&out.method(:puts)) # => prints 3 lines to file
2914 *
2915 * require 'date'
2916 * %w[2017-03-01 2017-03-02].collect(&Date.method(:parse))
2917 * #=> [#<Date: 2017-03-01 ((2457814j,0s,0n),+0s,2299161j)>, #<Date: 2017-03-02 ((2457815j,0s,0n),+0s,2299161j)>]
2918 */
2919
2920VALUE
2922{
2923 return obj_method(obj, vid, FALSE);
2924}
2925
2926/*
2927 * call-seq:
2928 * obj.public_method(sym) -> method
2929 *
2930 * Similar to _method_, searches public method only.
2931 */
2932
2933VALUE
2934rb_obj_public_method(VALUE obj, VALUE vid)
2935{
2936 return obj_method(obj, vid, TRUE);
2937}
2938
2939static VALUE
2940rb_obj_singleton_method_lookup(VALUE arg)
2941{
2942 VALUE *args = (VALUE *)arg;
2943 return rb_obj_method(args[0], args[1]);
2944}
2945
2946static VALUE
2947rb_obj_singleton_method_lookup_fail(VALUE arg1, VALUE arg2)
2948{
2949 return Qfalse;
2950}
2951
2952/*
2953 * call-seq:
2954 * obj.singleton_method(sym) -> method
2955 *
2956 * Similar to _method_, searches singleton method only.
2957 *
2958 * class Demo
2959 * def initialize(n)
2960 * @iv = n
2961 * end
2962 * def hello()
2963 * "Hello, @iv = #{@iv}"
2964 * end
2965 * end
2966 *
2967 * k = Demo.new(99)
2968 * def k.hi
2969 * "Hi, @iv = #{@iv}"
2970 * end
2971 * m = k.singleton_method(:hi)
2972 * m.call #=> "Hi, @iv = 99"
2973 * m = k.singleton_method(:hello) #=> NameError
2974 */
2975
2976VALUE
2977rb_obj_singleton_method(VALUE obj, VALUE vid)
2978{
2979 VALUE sc = rb_singleton_class_get(obj);
2980 VALUE klass;
2981 ID id = rb_check_id(&vid);
2982
2983 if (NIL_P(sc) ||
2984 NIL_P(klass = RCLASS_ORIGIN(sc)) ||
2985 !NIL_P(rb_special_singleton_class(obj))) {
2986 /* goto undef; */
2987 }
2988 else if (! id) {
2989 VALUE m = mnew_missing_by_name(klass, obj, &vid, FALSE, rb_cMethod);
2990 if (m) return m;
2991 /* else goto undef; */
2992 }
2993 else {
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);
2996 if (ruby_method) {
2997 struct METHOD *method = (struct METHOD *)RTYPEDDATA_GET_DATA(ruby_method);
2998 VALUE lookup_class = RBASIC_CLASS(obj);
2999 VALUE stop_class = rb_class_superclass(sc);
3000 VALUE method_class = method->iclass;
3001
3002 /* Determine if method is in singleton class, or module included in or prepended to it */
3003 do {
3004 if (lookup_class == method_class) {
3005 return ruby_method;
3006 }
3007 lookup_class = RCLASS_SUPER(lookup_class);
3008 } while (lookup_class && lookup_class != stop_class);
3009 }
3010 }
3011
3012 /* undef: */
3013 vid = ID2SYM(id);
3014 rb_name_err_raise("undefined singleton method '%1$s' for '%2$s'",
3015 obj, vid);
3017}
3018
3019/*
3020 * call-seq:
3021 * mod.instance_method(symbol) -> unbound_method
3022 *
3023 * Returns an +UnboundMethod+ representing the given
3024 * instance method in _mod_.
3025 * See +UnboundMethod+ about how to utilize it
3026 *
3027 * class Person
3028 * def initialize(name)
3029 * @name = name
3030 * end
3031 *
3032 * def hi
3033 * puts "Hi, I'm #{@name}!"
3034 * end
3035 * end
3036 *
3037 * dave = Person.new('Dave')
3038 * thomas = Person.new('Thomas')
3039 *
3040 * hi = Person.instance_method(:hi)
3041 * hi.bind_call(dave)
3042 * hi.bind_call(thomas)
3043 *
3044 * <em>produces:</em>
3045 *
3046 * Hi, I'm Dave!
3047 * Hi, I'm Thomas!
3048 */
3049
3050static VALUE
3051rb_mod_instance_method(VALUE mod, VALUE vid)
3052{
3053 ID id = rb_check_id(&vid);
3054 if (!id) {
3055 rb_method_name_error(mod, vid);
3056 }
3057 return mnew_unbound(mod, id, rb_cUnboundMethod, FALSE);
3058}
3059
3060/*
3061 * call-seq:
3062 * mod.public_instance_method(symbol) -> unbound_method
3063 *
3064 * Similar to _instance_method_, searches public method only.
3065 */
3066
3067static VALUE
3068rb_mod_public_instance_method(VALUE mod, VALUE vid)
3069{
3070 ID id = rb_check_id(&vid);
3071 if (!id) {
3072 rb_method_name_error(mod, vid);
3073 }
3074 return mnew_unbound(mod, id, rb_cUnboundMethod, TRUE);
3075}
3076
3077static VALUE
3078rb_mod_define_method_with_visibility(int argc, VALUE *argv, VALUE mod, const struct rb_scope_visi_struct* scope_visi)
3079{
3080 ID id;
3081 VALUE body;
3082 VALUE name;
3083 int is_method = FALSE;
3084
3085 rb_check_arity(argc, 1, 2);
3086 name = argv[0];
3087 id = rb_check_id(&name);
3088 if (argc == 1) {
3089 body = rb_block_lambda();
3090 }
3091 else {
3092 body = argv[1];
3093
3094 if (rb_obj_is_method(body)) {
3095 is_method = TRUE;
3096 }
3097 else if (rb_obj_is_proc(body)) {
3098 is_method = FALSE;
3099 }
3100 else {
3101 rb_raise(rb_eTypeError,
3102 "wrong argument type %s (expected Proc/Method/UnboundMethod)",
3103 rb_obj_classname(body));
3104 }
3105 }
3106 if (!id) id = rb_to_id(name);
3107
3108 if (is_method) {
3109 struct METHOD *method = (struct METHOD *)RTYPEDDATA_GET_DATA(body);
3110 if (method->me->owner != mod && !RB_TYPE_P(method->me->owner, T_MODULE) &&
3111 !RTEST(rb_class_inherited_p(mod, method->me->owner))) {
3112 if (RCLASS_SINGLETON_P(method->me->owner)) {
3113 rb_raise(rb_eTypeError,
3114 "can't bind singleton method to a different class");
3115 }
3116 else {
3117 rb_raise(rb_eTypeError,
3118 "bind argument must be a subclass of % "PRIsVALUE,
3119 method->me->owner);
3120 }
3121 }
3122 rb_method_entry_set(mod, id, method->me, scope_visi->method_visi);
3123 if (scope_visi->module_func) {
3124 rb_method_entry_set(rb_singleton_class(mod), id, method->me, METHOD_VISI_PUBLIC);
3125 }
3126 RB_GC_GUARD(body);
3127 }
3128 else {
3129 rb_proc_t *body_proc;
3130 GetProcPtr(body, body_proc);
3131 /* A bmethod never reads the refinement cref carried on the proc;
3132 * reject rather than silently drop the refinements. */
3133 if (body_proc->header.is_refined) {
3134 rb_raise(rb_eArgError,
3135 "can't define a method from a Proc with refinements");
3136 }
3137 VALUE procval = rb_proc_dup(body);
3138 if (vm_proc_iseq(procval) != NULL) {
3139 rb_proc_t *proc;
3140 GetProcPtr(procval, proc);
3141 proc->header.is_lambda = TRUE;
3142 proc->header.is_from_method = TRUE;
3143 }
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);
3147 }
3148 }
3149
3150 return ID2SYM(id);
3151}
3152
3153/*
3154 * call-seq:
3155 * define_method(symbol, method) -> symbol
3156 * define_method(symbol) { block } -> symbol
3157 *
3158 * Defines an instance method in the receiver. The _method_
3159 * parameter can be a +Proc+, a +Method+ or an +UnboundMethod+ object.
3160 * If a block is specified, it is used as the method body.
3161 * If a block or the _method_ parameter has parameters,
3162 * they're used as method parameters.
3163 * This block is evaluated using #instance_eval.
3164 *
3165 * class A
3166 * def fred
3167 * puts "In Fred"
3168 * end
3169 * def create_method(name, &block)
3170 * self.class.define_method(name, &block)
3171 * end
3172 * define_method(:wilma) { puts "Charge it!" }
3173 * define_method(:flint) {|name| puts "I'm #{name}!"}
3174 * end
3175 * class B < A
3176 * define_method(:barney, instance_method(:fred))
3177 * end
3178 * a = B.new
3179 * a.barney
3180 * a.wilma
3181 * a.flint('Dino')
3182 * a.create_method(:betty) { p self }
3183 * a.betty
3184 *
3185 * <em>produces:</em>
3186 *
3187 * In Fred
3188 * Charge it!
3189 * I'm Dino!
3190 * #<B:0x401b39e8>
3191 */
3192
3193static VALUE
3194rb_mod_define_method(int argc, VALUE *argv, VALUE mod)
3195{
3196 const rb_cref_t *cref = rb_vm_cref_in_context(mod, mod);
3197 const rb_scope_visibility_t default_scope_visi = {METHOD_VISI_PUBLIC, FALSE};
3198 const rb_scope_visibility_t *scope_visi = &default_scope_visi;
3199
3200 if (cref) {
3201 scope_visi = CREF_SCOPE_VISI(cref);
3202 }
3203
3204 return rb_mod_define_method_with_visibility(argc, argv, mod, scope_visi);
3205}
3206
3207/*
3208 * call-seq:
3209 * define_singleton_method(symbol, method) -> symbol
3210 * define_singleton_method(symbol) { block } -> symbol
3211 *
3212 * Defines a public singleton method in the receiver. The _method_
3213 * parameter can be a +Proc+, a +Method+ or an +UnboundMethod+ object.
3214 * If a block is specified, it is used as the method body.
3215 * If a block or a method has parameters, they're used as method parameters.
3216 *
3217 * class A
3218 * class << self
3219 * def class_name
3220 * to_s
3221 * end
3222 * end
3223 * end
3224 * A.define_singleton_method(:who_am_i) do
3225 * "I am: #{class_name}"
3226 * end
3227 * A.who_am_i # ==> "I am: A"
3228 *
3229 * guy = "Bob"
3230 * guy.define_singleton_method(:hello) { "#{self}: Hello there!" }
3231 * guy.hello #=> "Bob: Hello there!"
3232 *
3233 * chris = "Chris"
3234 * chris.define_singleton_method(:greet) {|greeting| "#{greeting}, I'm Chris!" }
3235 * chris.greet("Hi") #=> "Hi, I'm Chris!"
3236 */
3237
3238static VALUE
3239rb_obj_define_method(int argc, VALUE *argv, VALUE obj)
3240{
3241 VALUE klass = rb_singleton_class(obj);
3242 const rb_scope_visibility_t scope_visi = {METHOD_VISI_PUBLIC, FALSE};
3243
3244 return rb_mod_define_method_with_visibility(argc, argv, klass, &scope_visi);
3245}
3246
3247/*
3248 * define_method(symbol, method) -> symbol
3249 * define_method(symbol) { block } -> symbol
3250 *
3251 * Defines a global function by _method_ or the block.
3252 */
3253
3254static VALUE
3255top_define_method(int argc, VALUE *argv, VALUE obj)
3256{
3257 return rb_mod_define_method(argc, argv, rb_top_main_class("define_method"));
3258}
3259
3260/*
3261 * call-seq:
3262 * method.clone -> new_method
3263 *
3264 * Returns a clone of this method.
3265 *
3266 * class A
3267 * def foo
3268 * return "bar"
3269 * end
3270 * end
3271 *
3272 * m = A.new.method(:foo)
3273 * m.call # => "bar"
3274 * n = m.clone.call # => "bar"
3275 */
3276
3277static VALUE
3278method_clone(VALUE self)
3279{
3280 VALUE clone;
3281 struct METHOD *orig, *data;
3282
3283 TypedData_Get_Struct(self, struct METHOD, &method_data_type, orig);
3284 clone = TypedData_Make_Struct(rb_obj_class(self), struct METHOD, &method_data_type, data);
3285 rb_obj_clone_setup(self, clone, Qnil);
3286 RB_OBJ_WRITE(clone, &data->recv, orig->recv);
3287 RB_OBJ_WRITE(clone, &data->klass, orig->klass);
3288 RB_OBJ_WRITE(clone, &data->iclass, orig->iclass);
3289 RB_OBJ_WRITE(clone, &data->owner, orig->owner);
3290 RB_OBJ_WRITE(clone, &data->me, rb_method_entry_clone(orig->me));
3291 return clone;
3292}
3293
3294/* :nodoc: */
3295static VALUE
3296method_dup(VALUE self)
3297{
3298 VALUE clone;
3299 struct METHOD *orig, *data;
3300
3301 TypedData_Get_Struct(self, struct METHOD, &method_data_type, orig);
3302 clone = TypedData_Make_Struct(rb_obj_class(self), struct METHOD, &method_data_type, data);
3303 rb_obj_dup_setup(self, clone);
3304 RB_OBJ_WRITE(clone, &data->recv, orig->recv);
3305 RB_OBJ_WRITE(clone, &data->klass, orig->klass);
3306 RB_OBJ_WRITE(clone, &data->iclass, orig->iclass);
3307 RB_OBJ_WRITE(clone, &data->owner, orig->owner);
3308 RB_OBJ_WRITE(clone, &data->me, rb_method_entry_clone(orig->me));
3309 return clone;
3310}
3311
3312/*
3313 * call-seq:
3314 * call(...) -> obj
3315 * self[...] -> obj
3316 * self === obj -> result_of_method
3317 *
3318 * Invokes +self+ with the specified arguments, returning the
3319 * method's return value.
3320 *
3321 * m = 12.method("+")
3322 * m.call(3) #=> 15
3323 * m.call(20) #=> 32
3324 *
3325 * Using Method#=== allows a method object to be the target of a +when+ clause
3326 * in a case statement.
3327 *
3328 * require 'prime'
3329 *
3330 * case 1373
3331 * when Prime.method(:prime?)
3332 * # ...
3333 * end
3334 */
3335
3336static VALUE
3337rb_method_call_pass_called_kw(int argc, const VALUE *argv, VALUE method)
3338{
3339 return rb_method_call_kw(argc, argv, method, RB_PASS_CALLED_KEYWORDS);
3340}
3341
3342VALUE
3343rb_method_call_kw(int argc, const VALUE *argv, VALUE method, int kw_splat)
3344{
3345 VALUE procval = rb_block_given_p() ? rb_block_proc() : Qnil;
3346 return rb_method_call_with_block_kw(argc, argv, method, procval, kw_splat);
3347}
3348
3349VALUE
3350rb_method_call(int argc, const VALUE *argv, VALUE method)
3351{
3352 VALUE procval = rb_block_given_p() ? rb_block_proc() : Qnil;
3353 return rb_method_call_with_block(argc, argv, method, procval);
3354}
3355
3356static const rb_callable_method_entry_t *
3357method_callable_method_entry(const struct METHOD *data)
3358{
3359 if (data->me->defined_class == 0) rb_bug("method_callable_method_entry: not callable.");
3360 return (const rb_callable_method_entry_t *)data->me;
3361}
3362
3363static inline VALUE
3364call_method_data(rb_execution_context_t *ec, const struct METHOD *data,
3365 int argc, const VALUE *argv, VALUE passed_procval, int kw_splat)
3366{
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);
3370}
3371
3372VALUE
3373rb_method_call_with_block_kw(int argc, const VALUE *argv, VALUE method, VALUE passed_procval, int kw_splat)
3374{
3375 const struct METHOD *data;
3376 rb_execution_context_t *ec = GET_EC();
3377
3378 TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
3379 if (UNDEF_P(data->recv)) {
3380 rb_raise(rb_eTypeError, "can't call unbound method; bind first");
3381 }
3382 return call_method_data(ec, data, argc, argv, passed_procval, kw_splat);
3383}
3384
3385VALUE
3386rb_method_call_with_block(int argc, const VALUE *argv, VALUE method, VALUE passed_procval)
3387{
3388 return rb_method_call_with_block_kw(argc, argv, method, passed_procval, RB_NO_KEYWORDS);
3389}
3390
3391/**********************************************************************
3392 *
3393 * Document-class: UnboundMethod
3394 *
3395 * Ruby supports two forms of objectified methods. Class +Method+ is
3396 * used to represent methods that are associated with a particular
3397 * object: these method objects are bound to that object. Bound
3398 * method objects for an object can be created using Object#method.
3399 *
3400 * Ruby also supports unbound methods; methods objects that are not
3401 * associated with a particular object. These can be created either
3402 * by calling Module#instance_method or by calling #unbind on a bound
3403 * method object. The result of both of these is an UnboundMethod
3404 * object.
3405 *
3406 * Unbound methods can only be called after they are bound to an
3407 * object. That object must be a kind_of? the method's original
3408 * class.
3409 *
3410 * class Square
3411 * def area
3412 * @side * @side
3413 * end
3414 * def initialize(side)
3415 * @side = side
3416 * end
3417 * end
3418 *
3419 * area_un = Square.instance_method(:area)
3420 *
3421 * s = Square.new(12)
3422 * area = area_un.bind(s)
3423 * area.call #=> 144
3424 *
3425 * Unbound methods are a reference to the method at the time it was
3426 * objectified: subsequent changes to the underlying class will not
3427 * affect the unbound method.
3428 *
3429 * class Test
3430 * def test
3431 * :original
3432 * end
3433 * end
3434 * um = Test.instance_method(:test)
3435 * class Test
3436 * def test
3437 * :modified
3438 * end
3439 * end
3440 * t = Test.new
3441 * t.test #=> :modified
3442 * um.bind(t).call #=> :original
3443 *
3444 */
3445
3446static void
3447convert_umethod_to_method_components(const struct METHOD *data, VALUE recv, VALUE *methclass_out, VALUE *klass_out, VALUE *iclass_out, const rb_method_entry_t **me_out, const bool clone)
3448{
3449 VALUE methclass = data->owner;
3450 VALUE iclass = data->me->defined_class;
3451 VALUE klass = CLASS_OF(recv);
3452
3453 if (RB_TYPE_P(methclass, T_MODULE)) {
3454 VALUE refined_class = rb_refinement_module_get_refined_class(methclass);
3455 if (!NIL_P(refined_class)) methclass = refined_class;
3456 }
3457 if (!RB_TYPE_P(methclass, T_MODULE) && !RTEST(rb_obj_is_kind_of(recv, methclass))) {
3458 if (RCLASS_SINGLETON_P(methclass)) {
3459 rb_raise(rb_eTypeError,
3460 "singleton method called for a different object");
3461 }
3462 else {
3463 rb_raise(rb_eTypeError, "bind argument must be an instance of % "PRIsVALUE,
3464 methclass);
3465 }
3466 }
3467
3468 const rb_method_entry_t *me;
3469 if (clone) {
3470 me = rb_method_entry_clone(data->me);
3471 }
3472 else {
3473 me = data->me;
3474 }
3475
3476 if (RB_TYPE_P(me->owner, T_MODULE)) {
3477 if (!clone) {
3478 // if we didn't previously clone the method entry, then we need to clone it now
3479 // because this branch manipulates it in rb_method_entry_complement_defined_class
3480 me = rb_method_entry_clone(me);
3481 }
3482 VALUE ic = rb_class_search_ancestor(klass, me->owner);
3483 if (ic) {
3484 klass = ic;
3485 iclass = ic;
3486 }
3487 else {
3488 klass = rb_include_class_new(methclass, klass);
3489 }
3490 me = (const rb_method_entry_t *) rb_method_entry_complement_defined_class(me, me->called_id, klass);
3491 }
3492
3493 *methclass_out = methclass;
3494 *klass_out = klass;
3495 *iclass_out = iclass;
3496 *me_out = me;
3497}
3498
3499/*
3500 * call-seq:
3501 * umeth.bind(obj) -> method
3502 *
3503 * Bind <i>umeth</i> to <i>obj</i>. If Klass was the class from which
3504 * <i>umeth</i> was obtained, <code>obj.kind_of?(Klass)</code> must
3505 * be true.
3506 *
3507 * class A
3508 * def test
3509 * puts "In test, class = #{self.class}"
3510 * end
3511 * end
3512 * class B < A
3513 * end
3514 * class C < B
3515 * end
3516 *
3517 *
3518 * um = B.instance_method(:test)
3519 * bm = um.bind(C.new)
3520 * bm.call
3521 * bm = um.bind(B.new)
3522 * bm.call
3523 * bm = um.bind(A.new)
3524 * bm.call
3525 *
3526 * <em>produces:</em>
3527 *
3528 * In test, class = C
3529 * In test, class = B
3530 * prog.rb:16:in `bind': bind argument must be an instance of B (TypeError)
3531 * from prog.rb:16
3532 */
3533
3534static VALUE
3535umethod_bind(VALUE method, VALUE recv)
3536{
3537 VALUE methclass, klass, iclass;
3538 const rb_method_entry_t *me;
3539 const struct METHOD *data;
3540 TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
3541 convert_umethod_to_method_components(data, recv, &methclass, &klass, &iclass, &me, true);
3542
3543 struct METHOD *bound;
3544 method = TypedData_Make_Struct(rb_cMethod, struct METHOD, &method_data_type, bound);
3545 RB_OBJ_WRITE(method, &bound->recv, recv);
3546 RB_OBJ_WRITE(method, &bound->klass, klass);
3547 RB_OBJ_WRITE(method, &bound->iclass, iclass);
3548 RB_OBJ_WRITE(method, &bound->owner, methclass);
3549 RB_OBJ_WRITE(method, &bound->me, me);
3550
3551 return method;
3552}
3553
3554/*
3555 * call-seq:
3556 * umeth.bind_call(recv, args, ...) -> obj
3557 *
3558 * Bind <i>umeth</i> to <i>recv</i> and then invokes the method with the
3559 * specified arguments.
3560 * This is semantically equivalent to <code>umeth.bind(recv).call(args, ...)</code>.
3561 */
3562static VALUE
3563umethod_bind_call(int argc, VALUE *argv, VALUE method)
3564{
3566 VALUE recv = argv[0];
3567 argc--;
3568 argv++;
3569
3570 VALUE passed_procval = rb_block_given_p() ? rb_block_proc() : Qnil;
3571 rb_execution_context_t *ec = GET_EC();
3572
3573 const struct METHOD *data;
3574 TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
3575
3576 const rb_callable_method_entry_t *cme = rb_callable_method_entry(CLASS_OF(recv), data->me->called_id);
3577 if (data->me == (const rb_method_entry_t *)cme) {
3578 vm_passed_block_handler_set(ec, proc_to_block_handler(passed_procval));
3579 return rb_vm_call_kw(ec, recv, cme->called_id, argc, argv, cme, RB_PASS_CALLED_KEYWORDS);
3580 }
3581 else {
3582 VALUE methclass, klass, iclass;
3583 const rb_method_entry_t *me;
3584 convert_umethod_to_method_components(data, recv, &methclass, &klass, &iclass, &me, false);
3585 struct METHOD bound = { recv, klass, 0, methclass, me };
3586
3587 return call_method_data(ec, &bound, argc, argv, passed_procval, RB_PASS_CALLED_KEYWORDS);
3588 }
3589}
3590
3591/*
3592 * Returns the number of required parameters and stores the maximum
3593 * number of parameters in max, or UNLIMITED_ARGUMENTS
3594 * if there is no maximum.
3595 */
3596static int
3597method_def_min_max_arity(const rb_method_definition_t *def, int *max)
3598{
3599 again:
3600 if (!def) return *max = 0;
3601 switch (def->type) {
3602 case VM_METHOD_TYPE_CFUNC:
3603 if (def->body.cfunc.argc < 0) {
3604 *max = UNLIMITED_ARGUMENTS;
3605 return 0;
3606 }
3607 return *max = check_argc(def->body.cfunc.argc);
3608 case VM_METHOD_TYPE_ZSUPER:
3609 *max = UNLIMITED_ARGUMENTS;
3610 return 0;
3611 case VM_METHOD_TYPE_ATTRSET:
3612 return *max = 1;
3613 case VM_METHOD_TYPE_IVAR:
3614 return *max = 0;
3615 case VM_METHOD_TYPE_ALIAS:
3616 def = def->body.alias.original_me->def;
3617 goto again;
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:
3624 return *max = 0;
3625 case VM_METHOD_TYPE_MISSING:
3626 *max = UNLIMITED_ARGUMENTS;
3627 return 0;
3628 case VM_METHOD_TYPE_OPTIMIZED: {
3629 switch (def->body.optimized.type) {
3630 case OPTIMIZED_METHOD_TYPE_SEND:
3631 *max = UNLIMITED_ARGUMENTS;
3632 return 0;
3633 case OPTIMIZED_METHOD_TYPE_CALL:
3634 *max = UNLIMITED_ARGUMENTS;
3635 return 0;
3636 case OPTIMIZED_METHOD_TYPE_BLOCK_CALL:
3637 *max = UNLIMITED_ARGUMENTS;
3638 return 0;
3639 case OPTIMIZED_METHOD_TYPE_STRUCT_AREF:
3640 *max = 0;
3641 return 0;
3642 case OPTIMIZED_METHOD_TYPE_STRUCT_ASET:
3643 *max = 1;
3644 return 1;
3645 default:
3646 break;
3647 }
3648 break;
3649 }
3650 case VM_METHOD_TYPE_REFINED:
3651 *max = UNLIMITED_ARGUMENTS;
3652 return 0;
3653 }
3654 rb_bug("method_def_min_max_arity: invalid method entry type (%d)", def->type);
3656}
3657
3658static int
3659method_def_arity(const rb_method_definition_t *def)
3660{
3661 int max, min = method_def_min_max_arity(def, &max);
3662 return min == max ? min : -min-1;
3663}
3664
3665int
3666rb_method_entry_arity(const rb_method_entry_t *me)
3667{
3668 return method_def_arity(me->def);
3669}
3670
3671/*
3672 * call-seq:
3673 * meth.arity -> integer
3674 *
3675 * Returns an indication of the number of arguments accepted by a
3676 * method. Returns a nonnegative integer for methods that take a fixed
3677 * number of arguments. For Ruby methods that take a variable number of
3678 * arguments, returns -n-1, where n is the number of required arguments.
3679 * Keyword arguments will be considered as a single additional argument,
3680 * that argument being mandatory if any keyword argument is mandatory.
3681 * For methods written in C, returns -1 if the call takes a
3682 * variable number of arguments.
3683 *
3684 * class C
3685 * def one; end
3686 * def two(a); end
3687 * def three(*a); end
3688 * def four(a, b); end
3689 * def five(a, b, *c); end
3690 * def six(a, b, *c, &d); end
3691 * def seven(a, b, x:0); end
3692 * def eight(x:, y:); end
3693 * def nine(x:, y:, **z); end
3694 * def ten(*a, x:, y:); end
3695 * end
3696 * c = C.new
3697 * c.method(:one).arity #=> 0
3698 * c.method(:two).arity #=> 1
3699 * c.method(:three).arity #=> -1
3700 * c.method(:four).arity #=> 2
3701 * c.method(:five).arity #=> -3
3702 * c.method(:six).arity #=> -3
3703 * c.method(:seven).arity #=> -3
3704 * c.method(:eight).arity #=> 1
3705 * c.method(:nine).arity #=> 1
3706 * c.method(:ten).arity #=> -2
3707 *
3708 * "cat".method(:size).arity #=> 0
3709 * "cat".method(:replace).arity #=> 1
3710 * "cat".method(:squeeze).arity #=> -1
3711 * "cat".method(:count).arity #=> -1
3712 */
3713
3714static VALUE
3715method_arity_m(VALUE method)
3716{
3717 int n = method_arity(method);
3718 return INT2FIX(n);
3719}
3720
3721static int
3722method_arity(VALUE method)
3723{
3724 struct METHOD *data;
3725
3726 TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
3727 return rb_method_entry_arity(data->me);
3728}
3729
3730static const rb_method_entry_t *
3731original_method_entry(VALUE mod, ID id)
3732{
3733 const rb_method_entry_t *me;
3734
3735 while ((me = rb_method_entry(mod, id)) != 0) {
3736 const rb_method_definition_t *def = me->def;
3737
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;
3741
3742 mod = RCLASS_SUPER(me->owner);
3743 id = def->original_id;
3744 }
3745 return me;
3746}
3747
3748static int
3749method_min_max_arity(VALUE method, int *max)
3750{
3751 const struct METHOD *data;
3752
3753 TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
3754 return method_def_min_max_arity(data->me->def, max);
3755}
3756
3757int
3759{
3760 const rb_method_entry_t *me = original_method_entry(mod, id);
3761 if (!me) return 0; /* should raise? */
3762 return rb_method_entry_arity(me);
3763}
3764
3765int
3767{
3768 return rb_mod_method_arity(CLASS_OF(obj), id);
3769}
3770
3771VALUE
3772rb_callable_receiver(VALUE callable)
3773{
3774 if (rb_obj_is_proc(callable)) {
3775 VALUE binding = proc_binding(callable);
3776 return rb_funcall(binding, rb_intern("receiver"), 0);
3777 }
3778 else if (rb_obj_is_method(callable)) {
3779 return method_receiver(callable);
3780 }
3781 else {
3782 return Qundef;
3783 }
3784}
3785
3787rb_method_def(VALUE method)
3788{
3789 const struct METHOD *data;
3790
3791 TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
3792 return data->me->def;
3793}
3794
3795static const rb_iseq_t *
3796method_def_iseq(const rb_method_definition_t *def)
3797{
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:
3814 break;
3815 }
3816 return NULL;
3817}
3818
3819const rb_iseq_t *
3820rb_method_iseq(VALUE method)
3821{
3822 return method_def_iseq(rb_method_def(method));
3823}
3824
3825static const rb_cref_t *
3826method_cref(VALUE method)
3827{
3828 const rb_method_definition_t *def = rb_method_def(method);
3829
3830 again:
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;
3836 goto again;
3837 default:
3838 return NULL;
3839 }
3840}
3841
3842static VALUE
3843method_def_location(const rb_method_definition_t *def)
3844{
3845 if (def->type == VM_METHOD_TYPE_ATTRSET || def->type == VM_METHOD_TYPE_IVAR) {
3846 if (!def->body.attr.location)
3847 return Qnil;
3848 return rb_ary_dup(def->body.attr.location);
3849 }
3850 return iseq_location(method_def_iseq(def));
3851}
3852
3853VALUE
3854rb_method_entry_location(const rb_method_entry_t *me)
3855{
3856 if (!me) return Qnil;
3857 return method_def_location(me->def);
3858}
3859
3860/*
3861 * call-seq:
3862 * source_location -> location
3863 *
3864 * Returns a two-element array containing the Ruby source filename
3865 * as a string and the line number integer where +self+ is defined:
3866 *
3867 * def greeting = "hello"
3868 * method(:greeting).source_location # => ["test.rb", 1]
3869 *
3870 * Returns nil if +self+ is not a method defined in Ruby (i.e. defined
3871 * using native code):
3872 *
3873 * Kernel.method(:puts).source_location # => nil
3874 */
3875
3876VALUE
3877rb_method_location(VALUE method)
3878{
3879 return method_def_location(rb_method_def(method));
3880}
3881
3882static VALUE
3883method_def_source_range(const rb_method_definition_t *def)
3884{
3885 return source_range_new(method_def_iseq(def));
3886}
3887
3888/*
3889 * call-seq:
3890 * meth.source_range -> Ruby::SourceRange or nil
3891 *
3892 * Returns a Ruby::SourceRange for this method, or +nil+ if this method
3893 * was not defined in Ruby (i.e. native) or has no source path.
3894 *
3895 * The returned Ruby::SourceRange includes the source path, absolute path when
3896 * available, and the start and end line and byte-column coordinates.
3897 *
3898 * See https://github.com/ruby/spec/blob/master/core/method/shared/source_range.rb
3899 * for the location of start/end line/column in various cases.
3900 */
3901static VALUE
3902rb_method_source_range(VALUE method)
3903{
3904 return method_def_source_range(rb_method_def(method));
3905}
3906
3907static const rb_method_definition_t *
3908vm_proc_method_def(VALUE procval)
3909{
3910 const rb_proc_t *proc;
3911 const struct rb_block *block;
3912 const struct vm_ifunc *ifunc;
3913
3914 GetProcPtr(procval, proc);
3915 block = &proc->block;
3916
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);
3920 }
3921 else {
3922 return NULL;
3923 }
3924}
3925
3926static VALUE
3927method_def_parameters(const rb_method_definition_t *def)
3928{
3929 const rb_iseq_t *iseq;
3930 const rb_method_definition_t *bmethod_def;
3931
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);
3939 }
3940 else if ((bmethod_def = vm_proc_method_def(def->body.bmethod.proc)) != NULL) {
3941 return method_def_parameters(bmethod_def);
3942 }
3943 break;
3944
3945 case VM_METHOD_TYPE_ALIAS:
3946 return method_def_parameters(def->body.alias.original_me->def);
3947
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);
3952 }
3953 break;
3954
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:
3963 break;
3964 }
3965
3966 return rb_unnamed_parameters(method_def_arity(def));
3967
3968}
3969
3970/*
3971 * call-seq:
3972 * meth.parameters -> array
3973 *
3974 * Returns the parameter information of this method.
3975 *
3976 * def foo(bar); end
3977 * method(:foo).parameters #=> [[:req, :bar]]
3978 *
3979 * def foo(bar, baz, bat, &blk); end
3980 * method(:foo).parameters #=> [[:req, :bar], [:req, :baz], [:req, :bat], [:block, :blk]]
3981 *
3982 * def foo(bar, *args); end
3983 * method(:foo).parameters #=> [[:req, :bar], [:rest, :args]]
3984 *
3985 * def foo(bar, baz, *args, &blk); end
3986 * method(:foo).parameters #=> [[:req, :bar], [:req, :baz], [:rest, :args], [:block, :blk]]
3987 */
3988
3989static VALUE
3990rb_method_parameters(VALUE method)
3991{
3992 return method_def_parameters(rb_method_def(method));
3993}
3994
3995static inline VALUE
3996append_param_name(VALUE str, VALUE name, const char *unnamed)
3997{
3998 if (!NIL_P(name)) {
3999 rb_str_append(str, rb_sym2str(name));
4000 }
4001 else if (unnamed) {
4002 rb_str_cat_cstr(str, unnamed);
4003 }
4004 return str;
4005}
4006
4007/*
4008 * call-seq:
4009 * meth.to_s -> string
4010 * meth.inspect -> string
4011 *
4012 * Returns a human-readable description of the underlying method.
4013 *
4014 * "cat".method(:count).inspect #=> "#<Method: String#count(*)>"
4015 * (1..3).method(:map).inspect #=> "#<Method: Range(Enumerable)#map()>"
4016 *
4017 * In the latter case, the method description includes the "owner" of the
4018 * original method (+Enumerable+ module, which is included into +Range+).
4019 *
4020 * +inspect+ also provides, when possible, method argument names (call
4021 * sequence) and source location.
4022 *
4023 * require 'net/http'
4024 * Net::HTTP.method(:get).inspect
4025 * #=> "#<Method: Net::HTTP.get(uri_or_host, path=..., port=...) <skip>/lib/ruby/2.7.0/net/http.rb:457>"
4026 *
4027 * <code>...</code> in argument definition means argument is optional (has
4028 * some default value).
4029 *
4030 * For methods defined in C (language core and extensions), location and
4031 * argument names can't be extracted, and only generic information is provided
4032 * in form of <code>*</code> (any number of arguments) or <code>_</code> (some
4033 * positional argument).
4034 *
4035 * "cat".method(:count).inspect #=> "#<Method: String#count(*)>"
4036 * "cat".method(:+).inspect #=> "#<Method: String#+(_)>""
4037
4038 */
4039
4040static VALUE
4041method_inspect(VALUE method)
4042{
4043 struct METHOD *data;
4044 VALUE str;
4045 const char *sharp = "#";
4046 VALUE mklass;
4047 VALUE defined_class;
4048
4049 TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
4050 str = rb_sprintf("#<% "PRIsVALUE": ", rb_obj_class(method));
4051
4052 mklass = data->iclass;
4053 if (!mklass) mklass = data->klass;
4054
4055 if (RB_TYPE_P(mklass, T_ICLASS)) {
4056 /* TODO: I'm not sure why mklass is T_ICLASS.
4057 * UnboundMethod#bind() can set it as T_ICLASS at convert_umethod_to_method_components()
4058 * but not sure it is needed.
4059 */
4060 mklass = RBASIC_CLASS(mklass);
4061 }
4062
4063 if (data->me->def->type == VM_METHOD_TYPE_ALIAS) {
4064 defined_class = data->me->def->body.alias.original_me->owner;
4065 }
4066 else {
4067 defined_class = method_entry_defined_class(data->me);
4068 }
4069
4070 if (RB_TYPE_P(defined_class, T_ICLASS)) {
4071 defined_class = RBASIC_CLASS(defined_class);
4072 }
4073
4074 if (UNDEF_P(data->recv)) {
4075 // UnboundMethod
4076 rb_str_buf_append(str, rb_inspect(defined_class));
4077 }
4078 else if (RCLASS_SINGLETON_P(mklass)) {
4079 VALUE v = RCLASS_ATTACHED_OBJECT(mklass);
4080
4081 if (UNDEF_P(data->recv)) {
4082 rb_str_buf_append(str, rb_inspect(mklass));
4083 }
4084 else if (data->recv == v) {
4086 sharp = ".";
4087 }
4088 else {
4089 rb_str_buf_append(str, rb_inspect(data->recv));
4090 rb_str_buf_cat2(str, "(");
4092 rb_str_buf_cat2(str, ")");
4093 sharp = ".";
4094 }
4095 }
4096 else {
4097 mklass = data->klass;
4098 if (RB_TYPE_P(mklass, T_ICLASS)) {
4099 mklass = RBASIC_CLASS(mklass);
4100 }
4101 if (RCLASS_SINGLETON_P(mklass)) {
4102 VALUE v = RCLASS_ATTACHED_OBJECT(mklass);
4103 if (!(RB_TYPE_P(v, T_CLASS) || RB_TYPE_P(v, T_MODULE))) {
4104 do {
4105 mklass = RCLASS_SUPER(mklass);
4106 } while (RB_TYPE_P(mklass, T_ICLASS));
4107 }
4108 }
4109 rb_str_buf_append(str, rb_inspect(mklass));
4110 if (defined_class != mklass) {
4111 rb_str_catf(str, "(% "PRIsVALUE")", defined_class);
4112 }
4113 }
4114 rb_str_buf_cat2(str, sharp);
4115 rb_str_append(str, rb_id2str(data->me->called_id));
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));
4119 }
4120 if (data->me->def->type == VM_METHOD_TYPE_NOTIMPLEMENTED) {
4121 rb_str_buf_cat2(str, " (not-implemented)");
4122 }
4123
4124 // parameter information
4125 {
4126 VALUE params = rb_method_parameters(method);
4127 VALUE pair, name, kind;
4128 const VALUE req = ID2SYM(rb_intern("req"));
4129 const VALUE opt = ID2SYM(rb_intern("opt"));
4130 const VALUE keyreq = ID2SYM(rb_intern("keyreq"));
4131 const VALUE key = ID2SYM(rb_intern("key"));
4132 const VALUE rest = ID2SYM(rb_intern("rest"));
4133 const VALUE keyrest = ID2SYM(rb_intern("keyrest"));
4134 const VALUE block = ID2SYM(rb_intern("block"));
4135 const VALUE nokey = ID2SYM(rb_intern("nokey"));
4136 const VALUE noblock = ID2SYM(rb_intern("noblock"));
4137 int forwarding = 0;
4138
4139 rb_str_buf_cat2(str, "(");
4140
4141 if (RARRAY_LEN(params) == 3 &&
4142 RARRAY_AREF(RARRAY_AREF(params, 0), 0) == rest &&
4143 RARRAY_AREF(RARRAY_AREF(params, 0), 1) == ID2SYM('*') &&
4144 RARRAY_AREF(RARRAY_AREF(params, 1), 0) == keyrest &&
4145 RARRAY_AREF(RARRAY_AREF(params, 1), 1) == ID2SYM(idPow) &&
4146 RARRAY_AREF(RARRAY_AREF(params, 2), 0) == block &&
4147 RARRAY_AREF(RARRAY_AREF(params, 2), 1) == ID2SYM('&')) {
4148 forwarding = 1;
4149 }
4150
4151 for (int i = 0; i < RARRAY_LEN(params); i++) {
4152 pair = RARRAY_AREF(params, i);
4153 kind = RARRAY_AREF(pair, 0);
4154 if (RARRAY_LEN(pair) > 1) {
4155 name = RARRAY_AREF(pair, 1);
4156 }
4157 else {
4158 name = Qnil;
4159 }
4160
4161 if (kind == req) {
4162 append_param_name(str, name, "_");
4163 }
4164 else if (kind == opt) {
4165 rb_str_cat_cstr(append_param_name(str, name, "_"), "=...");
4166 }
4167 else if (kind == keyreq) {
4168 rb_str_cat_cstr(append_param_name(str, name, NULL), ":");
4169 }
4170 else if (kind == key) {
4171 rb_str_cat_cstr(append_param_name(str, name, NULL), ": ...");
4172 }
4173 else if (kind == rest) {
4174 rb_str_cat_cstr(str, forwarding ? "..." : "*");
4175 if (name != ID2SYM('*')) {
4176 append_param_name(str, name, NULL);
4177 }
4178 }
4179 else if (kind == keyrest) {
4180 if (name != ID2SYM(idPow)) {
4181 append_param_name(rb_str_cat_cstr(str, "**"), name, NULL);
4182 }
4183 else if (i > 0) {
4184 rb_str_set_len(str, RSTRING_LEN(str) - 2);
4185 }
4186 else {
4187 rb_str_cat_cstr(str, "**");
4188 }
4189 }
4190 else if (kind == block) {
4191 if (name == ID2SYM('&')) {
4192 if (forwarding) {
4193 rb_str_set_len(str, RSTRING_LEN(str) - 2);
4194 }
4195 else {
4196 rb_str_cat_cstr(str, "...");
4197 }
4198 }
4199 else {
4200 append_param_name(rb_str_cat_cstr(str, "&"), name, NULL);
4201 }
4202 }
4203 else if (kind == nokey) {
4204 rb_str_buf_cat2(str, "**nil");
4205 }
4206 else if (kind == noblock) {
4207 rb_str_buf_cat2(str, "&nil");
4208 }
4209
4210 if (i < RARRAY_LEN(params) - 1) {
4211 rb_str_buf_cat2(str, ", ");
4212 }
4213 }
4214 rb_str_buf_cat2(str, ")");
4215 }
4216
4217 { // source location
4218 VALUE loc = rb_method_location(method);
4219 if (!NIL_P(loc)) {
4220 rb_str_catf(str, " %"PRIsVALUE":%"PRIsVALUE,
4221 RARRAY_AREF(loc, 0), RARRAY_AREF(loc, 1));
4222 }
4223 }
4224
4225 rb_str_buf_cat2(str, ">");
4226
4227 return str;
4228}
4229
4230static VALUE
4231bmcall(RB_BLOCK_CALL_FUNC_ARGLIST(args, method))
4232{
4233 return rb_method_call_with_block_kw(argc, argv, method, blockarg, RB_PASS_CALLED_KEYWORDS);
4234}
4235
4236VALUE
4239 VALUE val)
4240{
4241 VALUE procval = rb_block_call(rb_mRubyVMFrozenCore, idProc, 0, 0, func, val);
4242 return procval;
4243}
4244
4245/*
4246 * call-seq:
4247 * meth.to_proc -> proc
4248 *
4249 * Returns a Proc object corresponding to this method.
4250 */
4251
4252static VALUE
4253method_to_proc(VALUE method)
4254{
4255 VALUE procval;
4256 rb_proc_t *proc;
4257
4258 /*
4259 * class Method
4260 * def to_proc
4261 * lambda{|*args|
4262 * self.call(*args)
4263 * }
4264 * end
4265 * end
4266 */
4267 procval = rb_block_call(rb_mRubyVMFrozenCore, idLambda, 0, 0, bmcall, method);
4268 GetProcPtr(procval, proc);
4269 proc->header.is_from_method = 1;
4270 return procval;
4271}
4272
4273extern VALUE rb_find_defined_class_by_owner(VALUE current_class, VALUE target_owner);
4274extern int rb_method_definition_eq(const rb_method_definition_t *d1, const rb_method_definition_t *d2);
4275rb_cref_t * rb_vm_get_cref(const VALUE *ep);
4276
4277/*
4278 * call-seq:
4279 * meth.super_method -> method
4280 *
4281 * Returns a +Method+ of superclass which would be called when super is used
4282 * or nil if there is no method on superclass.
4283 */
4284
4285static VALUE
4286method_super_method(VALUE method)
4287{
4288 const struct METHOD *data;
4289 VALUE super_class, iclass;
4290 ID mid;
4291 const rb_method_entry_t *me;
4292
4293 TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
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;
4300 }
4301 else {
4302 VALUE klass = iclass;
4303 if (RICLASS_FOR_REFINEMENT_P(klass)) {
4304 // Refined methods need this check before superclass determination
4305 klass = RBASIC(klass)->klass;
4306 }
4307 super_class = RCLASS_SUPER(RCLASS_ORIGIN(klass));
4308 mid = data->me->def->original_id;
4309 }
4310 if (!super_class) return Qnil;
4311
4312 // For refined methods, skip refinements for the same definition, but consider
4313 // refinements for superclass methods
4314 const rb_method_definition_t *skip_def = RICLASS_FOR_REFINEMENT_P(iclass) ? data->me->def : NULL;
4315
4316 // Use the CREF of the Method/UnboundMethod, not the CREF of the caller of super_method.
4317 // We must avoid the use of rb_callable_method_entry_with_refinements, as that will
4318 // implicitly use the refinements activated in of the caller of super_method.
4319 const rb_cref_t *cref = NULL;
4320 switch (data->me->def->type) {
4321 case VM_METHOD_TYPE_ISEQ:
4322 cref = data->me->def->body.iseq.cref;
4323 break;
4324 case VM_METHOD_TYPE_BMETHOD: {
4325 const rb_proc_t *proc;
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);
4330 break;
4331 }
4332 default:
4333 break;
4334 }
4335 VALUE klass = super_class;
4336 me = NULL;
4337 while (klass) {
4338 const rb_callable_method_entry_t *cme = rb_callable_method_entry(klass, mid);
4339 if (!cme) break;
4340 if (cme->def->type != VM_METHOD_TYPE_REFINED) {
4341 me = (rb_method_entry_t *)cme;
4342 iclass = cme->defined_class;
4343 break;
4344 }
4345 // Look through all CREF scopes for a refinement for cme->owner, mirroring
4346 // the loop in search_refined_method.
4347 const rb_cref_t *c;
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;
4353 const rb_callable_method_entry_t *ref_cme = rb_callable_method_entry(r, mid);
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;
4357 me = (rb_method_entry_t *)ref_cme;
4358 iclass = ref_cme->defined_class;
4359 break;
4360 }
4361 if (me) break;
4362 // No refined method found. Use orig_me if available, or normal method lookup
4363 // in superclass otherwise.
4364 const rb_method_entry_t *orig_me = cme->def->body.refined.orig_me;
4365 if (orig_me) {
4366 me = (rb_method_entry_t *)orig_me;
4367 iclass = orig_me->defined_class ? orig_me->defined_class : cme->defined_class;
4368 break;
4369 }
4370 klass = RCLASS_SUPER(cme->defined_class);
4371 }
4372 if (!me) return Qnil;
4373 return mnew_internal(me, me->owner, iclass, data->recv, mid, rb_obj_class(method), FALSE, FALSE);
4374}
4375
4376/*
4377 * call-seq:
4378 * local_jump_error.exit_value -> obj
4379 *
4380 * Returns the exit value associated with this +LocalJumpError+.
4381 */
4382static VALUE
4383localjump_xvalue(VALUE exc)
4384{
4385 return rb_iv_get(exc, "@exit_value");
4386}
4387
4388/*
4389 * call-seq:
4390 * local_jump_error.reason -> symbol
4391 *
4392 * The reason this block was terminated:
4393 * :break, :redo, :retry, :next, :return, or :noreason.
4394 */
4395
4396static VALUE
4397localjump_reason(VALUE exc)
4398{
4399 return rb_iv_get(exc, "@reason");
4400}
4401
4402rb_cref_t *rb_vm_cref_new_toplevel(void); /* vm.c */
4403
4404static const rb_env_t *
4405env_clone(const rb_env_t *env, const rb_cref_t *cref)
4406{
4407 VALUE *new_ep;
4408 VALUE *new_body;
4409 const rb_env_t *new_env;
4410
4411 VM_ASSERT(env->ep > env->env);
4412 VM_ASSERT(VM_ENV_ESCAPED_P(env->ep));
4413
4414 if (cref == NULL) {
4415 cref = rb_vm_cref_new_toplevel();
4416 }
4417
4418 new_body = ALLOC_N(VALUE, env->env_size);
4419 new_ep = &new_body[env->ep - env->env];
4420 new_env = vm_env_new(new_ep, new_body, env->env_size, env->iseq);
4421
4422 /* The memcpy has to happen after the vm_env_new because it can trigger a
4423 * GC compaction which can move the objects in the env. */
4424 MEMCPY(new_body, env->env, VALUE, env->env_size);
4425 /* VM_ENV_DATA_INDEX_ENV is set in vm_env_new but will get overwritten
4426 * by the memcpy above. */
4427 new_ep[VM_ENV_DATA_INDEX_ENV] = (VALUE)new_env;
4428 RB_OBJ_WRITE(new_env, &new_ep[VM_ENV_DATA_INDEX_ME_CREF], (VALUE)cref);
4429 VM_ASSERT(VM_ENV_ESCAPED_P(new_ep));
4430 return new_env;
4431}
4432
4433/*
4434 * call-seq:
4435 * prc.binding -> binding
4436 *
4437 * Returns the binding associated with <i>prc</i>.
4438 *
4439 * def fred(param)
4440 * proc {}
4441 * end
4442 *
4443 * b = fred(99)
4444 * eval("param", b.binding) #=> 99
4445 */
4446static VALUE
4447proc_binding(VALUE self)
4448{
4449 VALUE bindval, binding_self = Qundef;
4450 rb_binding_t *bind;
4451 const rb_proc_t *proc;
4452 const rb_iseq_t *iseq = NULL;
4453 const struct rb_block *block;
4454 const rb_env_t *env = NULL;
4455
4456 GetProcPtr(self, proc);
4457 block = &proc->block;
4458
4459 if (proc->header.is_isolated) rb_raise(rb_eArgError, "Can't create Binding from isolated Proc");
4460
4461 again:
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);
4467 break;
4468 case block_type_proc:
4469 GetProcPtr(block->as.proc, proc);
4470 block = &proc->block;
4471 goto again;
4472 case block_type_ifunc:
4473 {
4474 const struct vm_ifunc *ifunc = block->as.captured.code.ifunc;
4475 if (IS_METHOD_PROC_IFUNC(ifunc)) {
4476 VALUE method = (VALUE)ifunc->data;
4477 VALUE name = rb_fstring_lit("<empty_iseq>");
4478 rb_iseq_t *empty;
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));
4483 /* set empty iseq */
4484 empty = rb_iseq_new(Qnil, name, name, Qnil, 0, ISEQ_TYPE_TOP);
4485 RB_OBJ_WRITE(env, &env->iseq, empty);
4486 break;
4487 }
4488 }
4489 /* FALLTHROUGH */
4490 case block_type_symbol:
4491 rb_raise(rb_eArgError, "Can't create Binding from C level Proc");
4493 }
4494
4495 bindval = rb_binding_alloc(rb_cBinding);
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);
4500 RB_OBJ_WRITTEN(bindval, Qundef, VM_ENV_ENVVAL(env->ep));
4501
4502 if (iseq) {
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;
4506 }
4507 else {
4508 RB_OBJ_WRITE(bindval, &bind->pathobj,
4509 rb_iseq_pathobj_new(rb_fstring_lit("(binding)"), Qnil));
4510 bind->first_lineno = 1;
4511 }
4512
4513 return bindval;
4514}
4515
4516static rb_block_call_func curry;
4517
4518static VALUE
4519make_curry_proc(VALUE proc, VALUE passed, VALUE arity)
4520{
4521 VALUE args = rb_ary_new3(3, proc, passed, arity);
4522 rb_proc_t *procp;
4523 int is_lambda;
4524
4525 GetProcPtr(proc, procp);
4526 is_lambda = procp->header.is_lambda;
4527 rb_ary_freeze(passed);
4528 rb_ary_freeze(args);
4529 proc = rb_proc_new(curry, args);
4530 GetProcPtr(proc, procp);
4531 procp->header.is_lambda = is_lambda;
4532 return proc;
4533}
4534
4535static VALUE
4536curry(RB_BLOCK_CALL_FUNC_ARGLIST(_, args))
4537{
4538 VALUE proc, passed, arity;
4539 proc = RARRAY_AREF(args, 0);
4540 passed = RARRAY_AREF(args, 1);
4541 arity = RARRAY_AREF(args, 2);
4542
4543 passed = rb_ary_plus(passed, rb_ary_new4(argc, argv));
4544 rb_ary_freeze(passed);
4545
4546 if (RARRAY_LEN(passed) < FIX2INT(arity)) {
4547 if (!NIL_P(blockarg)) {
4548 rb_warn("given block not used");
4549 }
4550 arity = make_curry_proc(proc, passed, arity);
4551 return arity;
4552 }
4553 else {
4554 // `passed` is the only reference keeping this array (and thus the
4555 // buffer that RARRAY_CONST_PTR points into) alive, but it is otherwise
4556 // unused after this point. Without RB_GC_GUARD the compiler may drop it
4557 // before the call returns, so conservative stack marking misses it and
4558 // GC can reclaim the array while it is still being read as argv,
4559 // crashing with "try to mark T_NONE object".
4560 VALUE result = rb_proc_call_with_block(proc, check_argc(RARRAY_LEN(passed)), RARRAY_CONST_PTR(passed), blockarg);
4561 RB_GC_GUARD(passed);
4562 return result;
4563 }
4564}
4565
4566 /*
4567 * call-seq:
4568 * prc.curry -> a_proc
4569 * prc.curry(arity) -> a_proc
4570 *
4571 * Returns a curried proc. If the optional <i>arity</i> argument is given,
4572 * it determines the number of arguments.
4573 * A curried proc receives some arguments. If a sufficient number of
4574 * arguments are supplied, it passes the supplied arguments to the original
4575 * proc and returns the result. Otherwise, returns another curried proc that
4576 * takes the rest of arguments.
4577 *
4578 * The optional <i>arity</i> argument should be supplied when currying procs with
4579 * variable arguments to determine how many arguments are needed before the proc is
4580 * called.
4581 *
4582 * b = proc {|x, y, z| (x||0) + (y||0) + (z||0) }
4583 * p b.curry[1][2][3] #=> 6
4584 * p b.curry[1, 2][3, 4] #=> 6
4585 * p b.curry(5)[1][2][3][4][5] #=> 6
4586 * p b.curry(5)[1, 2][3, 4][5] #=> 6
4587 * p b.curry(1)[1] #=> 1
4588 *
4589 * b = proc {|x, y, z, *w| (x||0) + (y||0) + (z||0) + w.inject(0, &:+) }
4590 * p b.curry[1][2][3] #=> 6
4591 * p b.curry[1, 2][3, 4] #=> 10
4592 * p b.curry(5)[1][2][3][4][5] #=> 15
4593 * p b.curry(5)[1, 2][3, 4][5] #=> 15
4594 * p b.curry(1)[1] #=> 1
4595 *
4596 * b = lambda {|x, y, z| (x||0) + (y||0) + (z||0) }
4597 * p b.curry[1][2][3] #=> 6
4598 * p b.curry[1, 2][3, 4] #=> wrong number of arguments (given 4, expected 3)
4599 * p b.curry(5) #=> wrong number of arguments (given 5, expected 3)
4600 * p b.curry(1) #=> wrong number of arguments (given 1, expected 3)
4601 *
4602 * b = lambda {|x, y, z, *w| (x||0) + (y||0) + (z||0) + w.inject(0, &:+) }
4603 * p b.curry[1][2][3] #=> 6
4604 * p b.curry[1, 2][3, 4] #=> 10
4605 * p b.curry(5)[1][2][3][4][5] #=> 15
4606 * p b.curry(5)[1, 2][3, 4][5] #=> 15
4607 * p b.curry(1) #=> wrong number of arguments (given 1, expected 3)
4608 *
4609 * b = proc { :foo }
4610 * p b.curry[] #=> :foo
4611 */
4612static VALUE
4613proc_curry(int argc, const VALUE *argv, VALUE self)
4614{
4615 int sarity, max_arity, min_arity = rb_proc_min_max_arity(self, &max_arity);
4616 VALUE arity;
4617
4618 if (rb_check_arity(argc, 0, 1) == 0 || NIL_P(arity = argv[0])) {
4619 arity = INT2FIX(min_arity);
4620 }
4621 else {
4622 sarity = NUM2INT(arity);
4623 if (rb_proc_lambda_p(self)) {
4624 rb_check_arity(sarity, min_arity, max_arity);
4625 }
4626 arity = INT2FIX(sarity);
4627 }
4628
4629 return make_curry_proc(self, rb_ary_new(), arity);
4630}
4631
4632/*
4633 * call-seq:
4634 * meth.curry -> proc
4635 * meth.curry(arity) -> proc
4636 *
4637 * Returns a curried proc based on the method. When the proc is called with a number of
4638 * arguments that is lower than the method's arity, then another curried proc is returned.
4639 * Only when enough arguments have been supplied to satisfy the method signature, will the
4640 * method actually be called.
4641 *
4642 * The optional <i>arity</i> argument should be supplied when currying methods with
4643 * variable arguments to determine how many arguments are needed before the method is
4644 * called.
4645 *
4646 * def foo(a,b,c)
4647 * [a, b, c]
4648 * end
4649 *
4650 * proc = self.method(:foo).curry
4651 * proc2 = proc.call(1, 2) #=> #<Proc>
4652 * proc2.call(3) #=> [1,2,3]
4653 *
4654 * def vararg(*args)
4655 * args
4656 * end
4657 *
4658 * proc = self.method(:vararg).curry(4)
4659 * proc2 = proc.call(:x) #=> #<Proc>
4660 * proc3 = proc2.call(:y, :z) #=> #<Proc>
4661 * proc3.call(:a) #=> [:x, :y, :z, :a]
4662 */
4663
4664static VALUE
4665rb_method_curry(int argc, const VALUE *argv, VALUE self)
4666{
4667 VALUE proc = method_to_proc(self);
4668 return proc_curry(argc, argv, proc);
4669}
4670
4671static VALUE
4672compose(RB_BLOCK_CALL_FUNC_ARGLIST(_, args))
4673{
4674 VALUE f, g, fargs;
4675 f = RARRAY_AREF(args, 0);
4676 g = RARRAY_AREF(args, 1);
4677
4678 if (rb_obj_is_proc(g))
4679 fargs = rb_proc_call_with_block_kw(g, argc, argv, blockarg, RB_PASS_CALLED_KEYWORDS);
4680 else
4681 fargs = rb_funcall_with_block_kw(g, idCall, argc, argv, blockarg, RB_PASS_CALLED_KEYWORDS);
4682
4683 if (rb_obj_is_proc(f))
4684 return rb_proc_call(f, rb_ary_new3(1, fargs));
4685 else
4686 return rb_funcallv(f, idCall, 1, &fargs);
4687}
4688
4689static VALUE
4690to_callable(VALUE f)
4691{
4692 VALUE mesg;
4693
4694 if (rb_obj_is_proc(f)) return f;
4695 if (rb_obj_is_method(f)) return f;
4696 if (rb_obj_respond_to(f, idCall, TRUE)) return f;
4697 mesg = rb_fstring_lit("callable object is expected");
4699}
4700
4701static VALUE rb_proc_compose_to_left(VALUE self, VALUE g);
4702static VALUE rb_proc_compose_to_right(VALUE self, VALUE g);
4703
4704/*
4705 * call-seq:
4706 * prc << g -> a_proc
4707 *
4708 * Returns a proc that is the composition of this proc and the given <i>g</i>.
4709 * The returned proc takes a variable number of arguments, calls <i>g</i> with them
4710 * then calls this proc with the result.
4711 *
4712 * f = proc {|x| x * x }
4713 * g = proc {|x| x + x }
4714 * p (f << g).call(2) #=> 16
4715 *
4716 * See Proc#>> for detailed explanations.
4717 */
4718static VALUE
4719proc_compose_to_left(VALUE self, VALUE g)
4720{
4721 return rb_proc_compose_to_left(self, to_callable(g));
4722}
4723
4724static VALUE
4725rb_proc_compose_to_left(VALUE self, VALUE g)
4726{
4727 VALUE proc, args, procs[2];
4728 rb_proc_t *procp;
4729 int is_lambda;
4730
4731 procs[0] = self;
4732 procs[1] = g;
4733 args = rb_ary_tmp_new_from_values(0, 2, procs);
4734
4735 if (rb_obj_is_proc(g)) {
4736 GetProcPtr(g, procp);
4737 is_lambda = procp->header.is_lambda;
4738 }
4739 else {
4740 VM_ASSERT(rb_obj_is_method(g) || rb_obj_respond_to(g, idCall, TRUE));
4741 is_lambda = 1;
4742 }
4743
4744 proc = rb_proc_new(compose, args);
4745 GetProcPtr(proc, procp);
4746 procp->header.is_lambda = is_lambda;
4747
4748 return proc;
4749}
4750
4751/*
4752 * call-seq:
4753 * prc >> g -> a_proc
4754 *
4755 * Returns a proc that is the composition of this proc and the given <i>g</i>.
4756 * The returned proc takes a variable number of arguments, calls this proc with them
4757 * then calls <i>g</i> with the result.
4758 *
4759 * f = proc {|x| x * x }
4760 * g = proc {|x| x + x }
4761 * p (f >> g).call(2) #=> 8
4762 *
4763 * <i>g</i> could be other Proc, or Method, or any other object responding to
4764 * +call+ method:
4765 *
4766 * class Parser
4767 * def self.call(text)
4768 * # ...some complicated parsing logic...
4769 * end
4770 * end
4771 *
4772 * pipeline = File.method(:read) >> Parser >> proc { |data| puts "data size: #{data.count}" }
4773 * pipeline.call('data.json')
4774 *
4775 * See also Method#>> and Method#<<.
4776 */
4777static VALUE
4778proc_compose_to_right(VALUE self, VALUE g)
4779{
4780 return rb_proc_compose_to_right(self, to_callable(g));
4781}
4782
4783static VALUE
4784rb_proc_compose_to_right(VALUE self, VALUE g)
4785{
4786 VALUE proc, args, procs[2];
4787 rb_proc_t *procp;
4788 int is_lambda;
4789
4790 procs[0] = g;
4791 procs[1] = self;
4792 args = rb_ary_tmp_new_from_values(0, 2, procs);
4793
4794 GetProcPtr(self, procp);
4795 is_lambda = procp->header.is_lambda;
4796
4797 proc = rb_proc_new(compose, args);
4798 GetProcPtr(proc, procp);
4799 procp->header.is_lambda = is_lambda;
4800
4801 return proc;
4802}
4803
4804/*
4805 * call-seq:
4806 * self << g -> a_proc
4807 *
4808 * Returns a proc that is the composition of the given +g+ and this method.
4809 *
4810 * The returned proc takes a variable number of arguments. It first calls +g+
4811 * with the arguments, then calls +self+ with the return value of +g+.
4812 *
4813 * def f(ary) = ary << 'in f'
4814 *
4815 * f = self.method(:f)
4816 * g = proc { |ary| ary << 'in proc' }
4817 * (f << g).call([]) # => ["in proc", "in f"]
4818 */
4819static VALUE
4820rb_method_compose_to_left(VALUE self, VALUE g)
4821{
4822 g = to_callable(g);
4823 self = method_to_proc(self);
4824 return proc_compose_to_left(self, g);
4825}
4826
4827/*
4828 * call-seq:
4829 * self >> g -> a_proc
4830 *
4831 * Returns a proc that is the composition of this method and the given +g+.
4832 *
4833 * The returned proc takes a variable number of arguments. It first calls +self+
4834 * with the arguments, then calls +g+ with the return value of +self+.
4835 *
4836 * def f(ary) = ary << 'in f'
4837 *
4838 * f = self.method(:f)
4839 * g = proc { |ary| ary << 'in proc' }
4840 * (f >> g).call([]) # => ["in f", "in proc"]
4841 */
4842static VALUE
4843rb_method_compose_to_right(VALUE self, VALUE g)
4844{
4845 g = to_callable(g);
4846 self = method_to_proc(self);
4847 return proc_compose_to_right(self, g);
4848}
4849
4850/*
4851 * call-seq:
4852 * proc.ruby2_keywords -> proc
4853 *
4854 * Deprecated: will be removed in Ruby 4.4. Use explicit delegation
4855 * (<tt>*args, **kwargs</tt>) instead; it works correctly on Ruby 3.0
4856 * and later. See https://bugs.ruby-lang.org/issues/22205 for the
4857 * schedule.
4858 *
4859 * Marks the proc as passing keywords through a normal argument splat.
4860 * This should only be called on procs that accept an argument splat
4861 * (<tt>*args</tt>) but not explicit keywords or a keyword splat. It
4862 * marks the proc such that if the proc is called with keyword arguments,
4863 * the final hash argument is marked with a special flag such that if it
4864 * is the final element of a normal argument splat to another method call,
4865 * and that method call does not include explicit keywords or a keyword
4866 * splat, the final element is interpreted as keywords. In other words,
4867 * keywords will be passed through the proc to other methods.
4868 *
4869 * This should only be used for procs that delegate keywords to another
4870 * method, and only for backwards compatibility with Ruby versions before
4871 * 2.7.
4872 */
4873
4874static VALUE
4875proc_ruby2_keywords(VALUE procval)
4876{
4877 rb_proc_t *proc;
4878 GetProcPtr(procval, proc);
4879
4880 rb_check_frozen(procval);
4881
4882 if (proc->header.is_from_method) {
4883 rb_warn("Skipping set of ruby2_keywords flag for proc (proc created from method)");
4884 return procval;
4885 }
4886
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) {
4894 /* on a copy of this Proc's own: the block is shared with the
4895 * source Proc until the first call, and the copy installed by
4896 * it may be memoized and shared with sibling Procs */
4897 const rb_iseq_t *copy =
4898 rb_iseq_dup_with_independent_caches(proc->block.as.captured.code.iseq);
4899 ISEQ_BODY(copy)->param.flags.ruby2_keywords = 1;
4900 RB_VM_LOCKING() {
4901 RB_OBJ_WRITE(procval, &proc->block.as.captured.code.val, (VALUE)copy);
4902 }
4903 }
4904 else {
4905 ISEQ_BODY(proc->block.as.captured.code.iseq)->param.flags.ruby2_keywords = 1;
4906 }
4907 }
4908 else {
4909 rb_warn("Skipping set of ruby2_keywords flag for proc (proc accepts keywords or post arguments or proc does not accept argument splat)");
4910 }
4911 break;
4912 default:
4913 rb_warn("Skipping set of ruby2_keywords flag for proc (proc not defined in Ruby)");
4914 break;
4915 }
4916
4917 return procval;
4918}
4919
4920/*
4921 * Document-class: LocalJumpError
4922 *
4923 * Raised when Ruby can't yield as requested.
4924 *
4925 * A typical scenario is attempting to yield when no block is given:
4926 *
4927 * def call_block
4928 * yield 42
4929 * end
4930 * call_block
4931 *
4932 * <em>raises the exception:</em>
4933 *
4934 * LocalJumpError: no block given (yield)
4935 *
4936 * A more subtle example:
4937 *
4938 * def get_me_a_return
4939 * Proc.new { return 42 }
4940 * end
4941 * get_me_a_return.call
4942 *
4943 * <em>raises the exception:</em>
4944 *
4945 * LocalJumpError: unexpected return
4946 */
4947
4948/*
4949 * Document-class: SystemStackError
4950 *
4951 * Raised in case of a stack overflow.
4952 *
4953 * def me_myself_and_i
4954 * me_myself_and_i
4955 * end
4956 * me_myself_and_i
4957 *
4958 * <em>raises the exception:</em>
4959 *
4960 * SystemStackError: stack level too deep
4961 */
4962
4963/*
4964 * Document-class: Ruby::SourceRange
4965 *
4966 * An object representing a range of Ruby source code.
4967 *
4968 * Source ranges are returned by Proc#source_range, Method#source_range, and
4969 * UnboundMethod#source_range, as well as Thread::Backtrace::Location#source_range.
4970 * They include the source path, absolute path when available,
4971 * start line, start byte column, end line, and end byte column.
4972 *
4973 * The primary purpose of this class is to implement `Prism.find` precisely and cleanly on all Ruby implementations,
4974 * in a way which does not depend on implementation details like `node_id`.
4975 * For that we need the start/end line/column and the absolute_path, which is exactly what this class provides.
4976 *
4977 * The user of `Prism.find` can then tweak the result as desired to, for example,
4978 * include heredocs as mentioned in Ruby::SourceRange#end_line.
4979 * Or for Proc#source_range to include the method to which the block is passed.
4980 *
4981 * Note that the returned source range is not always an evaluable fragment by itself,
4982 * notably because heredocs can go beyond the `end` of the method and
4983 * for blocks because the range starts at `{`/`do`.
4984 */
4985
4986/*
4987 * Document-class: Proc
4988 *
4989 * A +Proc+ object is an encapsulation of a block of code, which can be stored
4990 * in a local variable, passed to a method or another Proc, and can be called.
4991 * Proc is an essential concept in Ruby and a core of its functional
4992 * programming features.
4993 *
4994 * square = Proc.new {|x| x**2 }
4995 *
4996 * square.call(3) #=> 9
4997 * # shorthands:
4998 * square.(3) #=> 9
4999 * square[3] #=> 9
5000 *
5001 * Proc objects are _closures_, meaning they remember and can use the entire
5002 * context in which they were created.
5003 *
5004 * def gen_times(factor)
5005 * Proc.new {|n| n*factor } # remembers the value of factor at the moment of creation
5006 * end
5007 *
5008 * times3 = gen_times(3)
5009 * times5 = gen_times(5)
5010 *
5011 * times3.call(12) #=> 36
5012 * times5.call(5) #=> 25
5013 * times3.call(times5.call(4)) #=> 60
5014 *
5015 * == Creation
5016 *
5017 * There are several methods to create a Proc
5018 *
5019 * * Use the Proc class constructor:
5020 *
5021 * proc1 = Proc.new {|x| x**2 }
5022 *
5023 * * Use the Kernel#proc method as a shorthand of Proc.new:
5024 *
5025 * proc2 = proc {|x| x**2 }
5026 *
5027 * * Receiving a block of code into proc argument (note the <code>&</code>):
5028 *
5029 * def make_proc(&block)
5030 * block
5031 * end
5032 *
5033 * proc3 = make_proc {|x| x**2 }
5034 *
5035 * * Construct a proc with lambda semantics using the Kernel#lambda method
5036 * (see below for explanations about lambdas):
5037 *
5038 * lambda1 = lambda {|x| x**2 }
5039 *
5040 * * Use the {Lambda proc literal}[rdoc-ref:syntax/literals.rdoc@Lambda+Proc+Literals] syntax
5041 * (also constructs a proc with lambda semantics):
5042 *
5043 * lambda2 = ->(x) { x**2 }
5044 *
5045 * == Lambda and non-lambda semantics
5046 *
5047 * Procs are coming in two flavors: lambda and non-lambda (regular procs).
5048 * Differences are:
5049 *
5050 * * In lambdas, +return+ and +break+ means exit from this lambda;
5051 * * In non-lambda procs, +return+ means exit from embracing method
5052 * (and will throw +LocalJumpError+ if invoked outside the method);
5053 * * In non-lambda procs, +break+ means exit from the method which the block given for.
5054 * (and will throw +LocalJumpError+ if invoked after the method returns);
5055 * * In lambdas, arguments are treated in the same way as in methods: strict,
5056 * with +ArgumentError+ for mismatching argument number,
5057 * and no additional argument processing;
5058 * * Regular procs accept arguments more generously: missing arguments
5059 * are filled with +nil+, single Array arguments are deconstructed if the
5060 * proc has multiple arguments, and there is no error raised on extra
5061 * arguments.
5062 *
5063 * Examples:
5064 *
5065 * # +return+ in non-lambda proc, +b+, exits +m2+.
5066 * # (The block +{ return }+ is given for +m1+ and embraced by +m2+.)
5067 * $a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1 { return }; $a << :m2 end; m2; p $a
5068 * #=> []
5069 *
5070 * # +break+ in non-lambda proc, +b+, exits +m1+.
5071 * # (The block +{ break }+ is given for +m1+ and embraced by +m2+.)
5072 * $a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1 { break }; $a << :m2 end; m2; p $a
5073 * #=> [:m2]
5074 *
5075 * # +next+ in non-lambda proc, +b+, exits the block.
5076 * # (The block +{ next }+ is given for +m1+ and embraced by +m2+.)
5077 * $a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1 { next }; $a << :m2 end; m2; p $a
5078 * #=> [:m1, :m2]
5079 *
5080 * # Using +proc+ method changes the behavior as follows because
5081 * # The block is given for +proc+ method and embraced by +m2+.
5082 * $a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1(&proc { return }); $a << :m2 end; m2; p $a
5083 * #=> []
5084 * $a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1(&proc { break }); $a << :m2 end; m2; p $a
5085 * # break from proc-closure (LocalJumpError)
5086 * $a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1(&proc { next }); $a << :m2 end; m2; p $a
5087 * #=> [:m1, :m2]
5088 *
5089 * # +return+, +break+ and +next+ in the stubby lambda exits the block.
5090 * # (+lambda+ method behaves same.)
5091 * # (The block is given for stubby lambda syntax and embraced by +m2+.)
5092 * $a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1(&-> { return }); $a << :m2 end; m2; p $a
5093 * #=> [:m1, :m2]
5094 * $a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1(&-> { break }); $a << :m2 end; m2; p $a
5095 * #=> [:m1, :m2]
5096 * $a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1(&-> { next }); $a << :m2 end; m2; p $a
5097 * #=> [:m1, :m2]
5098 *
5099 * p = proc {|x, y| "x=#{x}, y=#{y}" }
5100 * p.call(1, 2) #=> "x=1, y=2"
5101 * p.call([1, 2]) #=> "x=1, y=2", array deconstructed
5102 * p.call(1, 2, 8) #=> "x=1, y=2", extra argument discarded
5103 * p.call(1) #=> "x=1, y=", nil substituted instead of error
5104 *
5105 * l = lambda {|x, y| "x=#{x}, y=#{y}" }
5106 * l.call(1, 2) #=> "x=1, y=2"
5107 * l.call([1, 2]) # ArgumentError: wrong number of arguments (given 1, expected 2)
5108 * l.call(1, 2, 8) # ArgumentError: wrong number of arguments (given 3, expected 2)
5109 * l.call(1) # ArgumentError: wrong number of arguments (given 1, expected 2)
5110 *
5111 * def test_return
5112 * -> { return 3 }.call # just returns from lambda into method body
5113 * proc { return 4 }.call # returns from method
5114 * return 5
5115 * end
5116 *
5117 * test_return # => 4, return from proc
5118 *
5119 * Lambdas are useful as self-sufficient functions, in particular useful as
5120 * arguments to higher-order functions, behaving exactly like Ruby methods.
5121 *
5122 * Procs are useful for implementing iterators:
5123 *
5124 * def test
5125 * [[1, 2], [3, 4], [5, 6]].map {|a, b| return a if a + b > 10 }
5126 * # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5127 * end
5128 *
5129 * Inside +map+, the block of code is treated as a regular (non-lambda) proc,
5130 * which means that the internal arrays will be deconstructed to pairs of
5131 * arguments, and +return+ will exit from the method +test+. That would
5132 * not be possible with a stricter lambda.
5133 *
5134 * You can tell a lambda from a regular proc by using the #lambda? instance method.
5135 *
5136 * Lambda semantics is typically preserved during the proc lifetime, including
5137 * <code>&</code>-deconstruction to a block of code:
5138 *
5139 * p = proc {|x, y| x }
5140 * l = lambda {|x, y| x }
5141 * [[1, 2], [3, 4]].map(&p) #=> [1, 3]
5142 * [[1, 2], [3, 4]].map(&l) # ArgumentError: wrong number of arguments (given 1, expected 2)
5143 *
5144 * The only exception is dynamic method definition: even if defined by
5145 * passing a non-lambda proc, methods still have normal semantics of argument
5146 * checking.
5147 *
5148 * class C
5149 * define_method(:e, &proc {})
5150 * end
5151 * C.new.e(1,2) #=> ArgumentError
5152 * C.new.method(:e).to_proc.lambda? #=> true
5153 *
5154 * This exception ensures that methods never have unusual argument passing
5155 * conventions, and makes it easy to have wrappers defining methods that
5156 * behave as usual.
5157 *
5158 * class C
5159 * def self.def2(name, &body)
5160 * define_method(name, &body)
5161 * end
5162 *
5163 * def2(:f) {}
5164 * end
5165 * C.new.f(1,2) #=> ArgumentError
5166 *
5167 * The wrapper <code>def2</code> receives _body_ as a non-lambda proc,
5168 * yet defines a method which has normal semantics.
5169 *
5170 * == Conversion of other objects to procs
5171 *
5172 * Any object that implements the +to_proc+ method can be converted into
5173 * a proc by the <code>&</code> operator, and therefore can be
5174 * consumed by iterators.
5175 *
5176 * class Greeter
5177 * def initialize(greeting)
5178 * @greeting = greeting
5179 * end
5180 *
5181 * def to_proc
5182 * proc {|name| "#{@greeting}, #{name}!" }
5183 * end
5184 * end
5185 *
5186 * hi = Greeter.new("Hi")
5187 * hey = Greeter.new("Hey")
5188 * ["Bob", "Jane"].map(&hi) #=> ["Hi, Bob!", "Hi, Jane!"]
5189 * ["Bob", "Jane"].map(&hey) #=> ["Hey, Bob!", "Hey, Jane!"]
5190 *
5191 * Of the Ruby core classes, this method is implemented by +Symbol+,
5192 * +Method+, and +Hash+.
5193 *
5194 * :to_s.to_proc.call(1) #=> "1"
5195 * [1, 2].map(&:to_s) #=> ["1", "2"]
5196 *
5197 * method(:puts).to_proc.call(1) # prints 1
5198 * [1, 2].each(&method(:puts)) # prints 1, 2
5199 *
5200 * {test: 1}.to_proc.call(:test) #=> 1
5201 * %i[test many keys].map(&{test: 1}) #=> [1, nil, nil]
5202 *
5203 * == Orphaned Proc
5204 *
5205 * +return+ and +break+ in a block exit a method.
5206 * If a Proc object is generated from the block and the Proc object
5207 * survives until the method is returned, +return+ and +break+ cannot work.
5208 * In such case, +return+ and +break+ raises LocalJumpError.
5209 * A Proc object in such situation is called as orphaned Proc object.
5210 *
5211 * Note that the method to exit is different for +return+ and +break+.
5212 * There is a situation that orphaned for +break+ but not orphaned for +return+.
5213 *
5214 * def m1(&b) b.call end; def m2(); m1 { return } end; m2 # ok
5215 * def m1(&b) b.call end; def m2(); m1 { break } end; m2 # ok
5216 *
5217 * def m1(&b) b end; def m2(); m1 { return }.call end; m2 # ok
5218 * def m1(&b) b end; def m2(); m1 { break }.call end; m2 # LocalJumpError
5219 *
5220 * def m1(&b) b end; def m2(); m1 { return } end; m2.call # LocalJumpError
5221 * def m1(&b) b end; def m2(); m1 { break } end; m2.call # LocalJumpError
5222 *
5223 * Since +return+ and +break+ exits the block itself in lambdas,
5224 * lambdas cannot be orphaned.
5225 *
5226 * == Anonymous block parameters
5227 *
5228 * To simplify writing short blocks, Ruby provides two different types of
5229 * anonymous parameters: +it+ (single parameter) and numbered ones: <tt>_1</tt>,
5230 * <tt>_2</tt> and so on.
5231 *
5232 * # Explicit parameter:
5233 * %w[test me please].each { |str| puts str.upcase } # prints TEST, ME, PLEASE
5234 * (1..5).map { |i| i**2 } # => [1, 4, 9, 16, 25]
5235 *
5236 * # it:
5237 * %w[test me please].each { puts it.upcase } # prints TEST, ME, PLEASE
5238 * (1..5).map { it**2 } # => [1, 4, 9, 16, 25]
5239 *
5240 * # Numbered parameter:
5241 * %w[test me please].each { puts _1.upcase } # prints TEST, ME, PLEASE
5242 * (1..5).map { _1**2 } # => [1, 4, 9, 16, 25]
5243 *
5244 * === +it+
5245 *
5246 * +it+ is a name that is available inside a block when no explicit parameters
5247 * defined, as shown above.
5248 *
5249 * %w[test me please].each { puts it.upcase } # prints TEST, ME, PLEASE
5250 * (1..5).map { it**2 } # => [1, 4, 9, 16, 25]
5251 *
5252 * +it+ is a "soft keyword": it is not a reserved name, and can be used as
5253 * a name for methods and local variables:
5254 *
5255 * it = 5 # no warnings
5256 * def it(&block) # RSpec-like API, no warnings
5257 * # ...
5258 * end
5259 *
5260 * +it+ can be used as a local variable even in blocks that use it as an
5261 * implicit parameter (though this style is obviously confusing):
5262 *
5263 * [1, 2, 3].each {
5264 * # takes a value of implicit parameter "it" and uses it to
5265 * # define a local variable with the same name
5266 * it = it**2
5267 * p it
5268 * }
5269 *
5270 * In a block with explicit parameters defined +it+ usage raises an exception:
5271 *
5272 * [1, 2, 3].each { |x| p it }
5273 * # syntax error found (SyntaxError)
5274 * # [1, 2, 3].each { |x| p it }
5275 * # ^~ 'it' is not allowed when an ordinary parameter is defined
5276 *
5277 * But if a local name (variable or method) is available, it would be used:
5278 *
5279 * it = 5
5280 * [1, 2, 3].each { |x| p it }
5281 * # Prints 5, 5, 5
5282 *
5283 * Blocks using +it+ can be nested:
5284 *
5285 * %w[test me].each { it.each_char { p it } }
5286 * # Prints "t", "e", "s", "t", "m", "e"
5287 *
5288 * Blocks using +it+ are considered to have one parameter:
5289 *
5290 * p = proc { it**2 }
5291 * l = lambda { it**2 }
5292 * p.parameters # => [[:opt]]
5293 * p.arity # => 1
5294 * l.parameters # => [[:req]]
5295 * l.arity # => 1
5296 *
5297 * === Numbered parameters
5298 *
5299 * Numbered parameters are another way to name block parameters implicitly.
5300 * Unlike +it+, numbered parameters allow to refer to several parameters
5301 * in one block.
5302 *
5303 * %w[test me please].each { puts _1.upcase } # prints TEST, ME, PLEASE
5304 * {a: 100, b: 200}.map { "#{_1} = #{_2}" } # => "a = 100", "b = 200"
5305 *
5306 * Parameter names from +_1+ to +_9+ are supported:
5307 *
5308 * [10, 20, 30].zip([40, 50, 60], [70, 80, 90]).map { _1 + _2 + _3 }
5309 * # => [120, 150, 180]
5310 *
5311 * Though, it is advised to resort to them wisely, probably limiting
5312 * yourself to +_1+ and +_2+, and to one-line blocks.
5313 *
5314 * Numbered parameters can't be used together with explicitly named
5315 * ones:
5316 *
5317 * [10, 20, 30].map { |x| _1**2 }
5318 * # SyntaxError (ordinary parameter is defined)
5319 *
5320 * Numbered parameters can't be mixed with +it+ either:
5321 *
5322 * [10, 20, 30].map { _1 + it }
5323 * # SyntaxError: 'it' is not allowed when a numbered parameter is already used
5324 *
5325 * To avoid conflicts, naming local variables or method
5326 * arguments +_1+, +_2+ and so on, causes an error.
5327 *
5328 * _1 = 'test'
5329 * # ^~ _1 is reserved for numbered parameters (SyntaxError)
5330 *
5331 * Using implicit numbered parameters affects block's arity:
5332 *
5333 * p = proc { _1 + _2 }
5334 * l = lambda { _1 + _2 }
5335 * p.parameters # => [[:opt, :_1], [:opt, :_2]]
5336 * p.arity # => 2
5337 * l.parameters # => [[:req, :_1], [:req, :_2]]
5338 * l.arity # => 2
5339 *
5340 * Blocks with numbered parameters can't be nested:
5341 *
5342 * %w[test me].each { _1.each_char { p _1 } }
5343 * # numbered parameter is already used in outer block (SyntaxError)
5344 * # %w[test me].each { _1.each_char { p _1 } }
5345 * # ^~
5346 *
5347 */
5348
5349void
5350Init_Proc(void)
5351{
5352#undef rb_intern
5353 id_refinements_recipe = rb_make_internal_id();
5354
5355 VALUE mRuby = rb_define_module("Ruby");
5356
5357 /* Ruby::SourceRange */
5358 rb_cSourceRange = rb_define_class_under(mRuby, "SourceRange", rb_cObject);
5359 rb_undef_alloc_func(rb_cSourceRange);
5360 rb_undef_method(CLASS_OF(rb_cSourceRange), "new");
5361 rb_define_method(rb_cSourceRange, "path", source_range_path, 0);
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);
5365 rb_define_method(rb_cSourceRange, "end_line", source_range_end_line, 0);
5366 rb_define_method(rb_cSourceRange, "end_column", source_range_end_column, 0);
5367 rb_define_method(rb_cSourceRange, "inspect", source_range_inspect, 0);
5368
5369 /* Proc */
5370 rb_cProc = rb_define_class("Proc", rb_cObject);
5372 rb_define_singleton_method(rb_cProc, "new", rb_proc_s_new, -1);
5373
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);
5378
5379#if 0 /* for RDoc */
5380 rb_define_method(rb_cProc, "call", proc_call, -1);
5381 rb_define_method(rb_cProc, "[]", proc_call, -1);
5382 rb_define_method(rb_cProc, "===", proc_call, -1);
5383 rb_define_method(rb_cProc, "yield", proc_call, -1);
5384#endif
5385
5386 rb_define_method(rb_cProc, "to_proc", proc_to_proc, 0);
5387 rb_define_method(rb_cProc, "arity", proc_arity, 0);
5388 rb_define_method(rb_cProc, "clone", proc_clone, 0);
5389 rb_define_method(rb_cProc, "dup", proc_dup, 0);
5390 rb_define_method(rb_cProc, "refined", proc_refined, -1);
5391 rb_define_method(rb_cProc, "hash", proc_hash, 0);
5392 rb_define_method(rb_cProc, "to_s", proc_to_s, 0);
5393 rb_define_alias(rb_cProc, "inspect", "to_s");
5395 rb_define_method(rb_cProc, "binding", proc_binding, 0);
5396 rb_define_method(rb_cProc, "curry", proc_curry, -1);
5397 rb_define_method(rb_cProc, "<<", proc_compose_to_left, 1);
5398 rb_define_method(rb_cProc, ">>", proc_compose_to_right, 1);
5399 rb_define_method(rb_cProc, "==", rb_proc_eq, 1);
5400 rb_define_method(rb_cProc, "eql?", rb_proc_eq, 1);
5401 rb_define_method(rb_cProc, "source_location", rb_proc_location, 0);
5402 rb_define_method(rb_cProc, "source_range", rb_proc_source_range, 0);
5403 rb_define_method(rb_cProc, "parameters", rb_proc_parameters, -1);
5404 rb_define_method(rb_cProc, "ruby2_keywords", proc_ruby2_keywords, 0);
5405 // rb_define_method(rb_cProc, "isolate", rb_proc_isolate, 0); is not accepted.
5406
5407 /* Exceptions */
5408 rb_eLocalJumpError = rb_define_class("LocalJumpError", rb_eStandardError);
5409 rb_define_method(rb_eLocalJumpError, "exit_value", localjump_xvalue, 0);
5410 rb_define_method(rb_eLocalJumpError, "reason", localjump_reason, 0);
5411
5412 rb_eSysStackError = rb_define_class("SystemStackError", rb_eException);
5413 rb_vm_register_special_exception(ruby_error_sysstack, rb_eSysStackError, "stack level too deep");
5414
5415 /* utility functions */
5416 rb_define_global_function("proc", f_proc, 0);
5417 rb_define_global_function("lambda", f_lambda, 0);
5418
5419 /* Method */
5420 rb_cMethod = rb_define_class("Method", rb_cObject);
5423 rb_define_method(rb_cMethod, "==", method_eq, 1);
5424 rb_define_method(rb_cMethod, "eql?", method_eq, 1);
5425 rb_define_method(rb_cMethod, "hash", method_hash, 0);
5426 rb_define_method(rb_cMethod, "clone", method_clone, 0);
5427 rb_define_method(rb_cMethod, "dup", method_dup, 0);
5428 rb_define_method(rb_cMethod, "call", rb_method_call_pass_called_kw, -1);
5429 rb_define_method(rb_cMethod, "===", rb_method_call_pass_called_kw, -1);
5430 rb_define_method(rb_cMethod, "curry", rb_method_curry, -1);
5431 rb_define_method(rb_cMethod, "<<", rb_method_compose_to_left, 1);
5432 rb_define_method(rb_cMethod, ">>", rb_method_compose_to_right, 1);
5433 rb_define_method(rb_cMethod, "[]", rb_method_call_pass_called_kw, -1);
5434 rb_define_method(rb_cMethod, "arity", method_arity_m, 0);
5435 rb_define_method(rb_cMethod, "inspect", method_inspect, 0);
5436 rb_define_method(rb_cMethod, "to_s", method_inspect, 0);
5437 rb_define_method(rb_cMethod, "to_proc", method_to_proc, 0);
5438 rb_define_method(rb_cMethod, "receiver", method_receiver, 0);
5439 rb_define_method(rb_cMethod, "name", method_name, 0);
5440 rb_define_method(rb_cMethod, "original_name", method_original_name, 0);
5441 rb_define_method(rb_cMethod, "owner", method_owner, 0);
5442 rb_define_method(rb_cMethod, "unbind", method_unbind, 0);
5443 rb_define_method(rb_cMethod, "source_location", rb_method_location, 0);
5444 rb_define_method(rb_cMethod, "source_range", rb_method_source_range, 0);
5445 rb_define_method(rb_cMethod, "parameters", rb_method_parameters, 0);
5446 rb_define_method(rb_cMethod, "super_method", method_super_method, 0);
5448 rb_define_method(rb_mKernel, "public_method", rb_obj_public_method, 1);
5449 rb_define_method(rb_mKernel, "singleton_method", rb_obj_singleton_method, 1);
5450
5451 rb_define_method(rb_cMethod, "box", method_box, 0);
5452
5453 /* UnboundMethod */
5454 rb_cUnboundMethod = rb_define_class("UnboundMethod", rb_cObject);
5457 rb_define_method(rb_cUnboundMethod, "==", unbound_method_eq, 1);
5458 rb_define_method(rb_cUnboundMethod, "eql?", unbound_method_eq, 1);
5459 rb_define_method(rb_cUnboundMethod, "hash", method_hash, 0);
5460 rb_define_method(rb_cUnboundMethod, "clone", method_clone, 0);
5461 rb_define_method(rb_cUnboundMethod, "dup", method_dup, 0);
5462 rb_define_method(rb_cUnboundMethod, "arity", method_arity_m, 0);
5463 rb_define_method(rb_cUnboundMethod, "inspect", method_inspect, 0);
5464 rb_define_method(rb_cUnboundMethod, "to_s", method_inspect, 0);
5465 rb_define_method(rb_cUnboundMethod, "name", method_name, 0);
5466 rb_define_method(rb_cUnboundMethod, "original_name", method_original_name, 0);
5467 rb_define_method(rb_cUnboundMethod, "owner", method_owner, 0);
5468 rb_define_method(rb_cUnboundMethod, "bind", umethod_bind, 1);
5469 rb_define_method(rb_cUnboundMethod, "bind_call", umethod_bind_call, -1);
5470 rb_define_method(rb_cUnboundMethod, "source_location", rb_method_location, 0);
5471 rb_define_method(rb_cUnboundMethod, "source_range", rb_method_source_range, 0);
5472 rb_define_method(rb_cUnboundMethod, "parameters", rb_method_parameters, 0);
5473 rb_define_method(rb_cUnboundMethod, "super_method", method_super_method, 0);
5474
5475 /* Module#*_method */
5476 rb_define_method(rb_cModule, "instance_method", rb_mod_instance_method, 1);
5477 rb_define_method(rb_cModule, "public_instance_method", rb_mod_public_instance_method, 1);
5478 rb_define_method(rb_cModule, "define_method", rb_mod_define_method, -1);
5479
5480 /* Kernel */
5481 rb_define_method(rb_mKernel, "define_singleton_method", rb_obj_define_method, -1);
5482
5484 "define_method", top_define_method, -1);
5485}
5486
5487/*
5488 * Objects of class Binding encapsulate the execution context at some
5489 * particular place in the code and retain this context for future
5490 * use. The variables, methods, value of <code>self</code>, and
5491 * possibly an iterator block that can be accessed in this context
5492 * are all retained. Binding objects can be created using
5493 * Kernel#binding, and are made available to the callback of
5494 * Kernel#set_trace_func and instances of TracePoint.
5495 *
5496 * These binding objects can be passed as the second argument of the
5497 * Kernel#eval method, establishing an environment for the
5498 * evaluation.
5499 *
5500 * class Demo
5501 * def initialize(n)
5502 * @secret = n
5503 * end
5504 * def get_binding
5505 * binding
5506 * end
5507 * end
5508 *
5509 * k1 = Demo.new(99)
5510 * b1 = k1.get_binding
5511 * k2 = Demo.new(-3)
5512 * b2 = k2.get_binding
5513 *
5514 * eval("@secret", b1) #=> 99
5515 * eval("@secret", b2) #=> -3
5516 * eval("@secret") #=> nil
5517 *
5518 * Binding objects have no class-specific methods.
5519 *
5520 */
5521
5522void
5523Init_Binding(void)
5524{
5525 rb_gc_register_address(&sym_proc_cache);
5526
5527 rb_cBinding = rb_define_class("Binding", rb_cObject);
5530 rb_define_method(rb_cBinding, "clone", binding_clone, 0);
5531 rb_define_method(rb_cBinding, "dup", binding_dup, 0);
5532 rb_define_method(rb_cBinding, "eval", bind_eval, -1);
5533 rb_define_method(rb_cBinding, "local_variables", bind_local_variables, 0);
5534 rb_define_method(rb_cBinding, "local_variable_get", bind_local_variable_get, 1);
5535 rb_define_method(rb_cBinding, "local_variable_set", bind_local_variable_set, 2);
5536 rb_define_method(rb_cBinding, "local_variable_defined?", bind_local_variable_defined_p, 1);
5537 rb_define_method(rb_cBinding, "implicit_parameters", bind_implicit_parameters, 0);
5538 rb_define_method(rb_cBinding, "implicit_parameter_get", bind_implicit_parameter_get, 1);
5539 rb_define_method(rb_cBinding, "implicit_parameter_defined?", bind_implicit_parameter_defined_p, 1);
5540 rb_define_method(rb_cBinding, "receiver", bind_receiver, 0);
5541 rb_define_method(rb_cBinding, "source_location", bind_location, 0);
5542 rb_define_global_function("binding", rb_f_binding, 0);
5543}
#define RUBY_ASSERT(...)
Asserts that the given expression is truthy if and only if RUBY_DEBUG is truthy.
Definition assert.h:219
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
#define rb_define_private_method(klass, mid, func, arity)
Defines klass#mid and makes it private.
#define rb_define_global_function(mid, func, arity)
Defines rb_mKernel #mid.
VALUE rb_singleton_class(VALUE obj)
Finds or creates the singleton class of the passed object.
Definition class.c:3051
VALUE rb_singleton_class_get(VALUE obj)
Returns the singleton class of obj, or nil if obj is not a singleton object.
Definition class.c:3037
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition class.c:3094
void rb_undef_method(VALUE klass, const char *name)
Defines an undef of a method.
Definition class.c:2897
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Retrieves argument from argc and argv to given VALUE references according to the format string.
Definition class.c:3384
int rb_block_given_p(void)
Determines if the current method is given a block.
Definition eval.c:1035
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
Keyword argument deconstructor.
Definition class.c:3173
#define rb_str_buf_cat2
Old name of rb_usascii_str_new_cstr.
Definition string.h:1707
#define Qundef
Old name of RUBY_Qundef.
#define INT2FIX
Old name of RB_INT2FIX.
Definition long.h:48
#define ID2SYM
Old name of RB_ID2SYM.
Definition symbol.h:44
#define OBJ_FREEZE
Old name of RB_OBJ_FREEZE.
Definition fl_type.h:131
#define UNREACHABLE_RETURN
Old name of RBIMPL_UNREACHABLE_RETURN.
Definition assume.h:29
#define SYM2ID
Old name of RB_SYM2ID.
Definition symbol.h:45
#define ZALLOC
Old name of RB_ZALLOC.
Definition memory.h:402
#define CLASS_OF
Old name of rb_class_of.
Definition globals.h:205
#define rb_ary_new4
Old name of rb_ary_new_from_values.
Definition array.h:659
#define FIX2INT
Old name of RB_FIX2INT.
Definition int.h:41
#define T_MODULE
Old name of RUBY_T_MODULE.
Definition value_type.h:70
#define ASSUME
Old name of RBIMPL_ASSUME.
Definition assume.h:27
#define T_ICLASS
Old name of RUBY_T_ICLASS.
Definition value_type.h:66
#define ALLOC_N
Old name of RB_ALLOC_N.
Definition memory.h:399
#define FL_TEST_RAW
Old name of RB_FL_TEST_RAW.
Definition fl_type.h:128
#define rb_ary_new3
Old name of rb_ary_new_from_args.
Definition array.h:658
#define Qtrue
Old name of RUBY_Qtrue.
#define ST2FIX
Old name of RB_ST2FIX.
Definition st_data_t.h:33
#define NUM2INT
Old name of RB_NUM2INT.
Definition int.h:44
#define INT2NUM
Old name of RB_INT2NUM.
Definition int.h:43
#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.
Definition value_type.h:58
#define BUILTIN_TYPE
Old name of RB_BUILTIN_TYPE.
Definition value_type.h:85
#define Check_TypedStruct(v, t)
Old name of rb_check_typeddata.
Definition rtypeddata.h:109
#define CONST_ID
Old name of RUBY_CONST_ID.
Definition symbol.h:47
#define rb_ary_new2
Old name of rb_ary_new_capa.
Definition array.h:657
VALUE rb_eLocalJumpError
LocalJumpError exception.
Definition eval.c:50
void rb_category_warn(rb_warning_category_t category, const char *fmt,...)
Identical to rb_category_warning(), except it reports unless $VERBOSE is nil.
Definition error.c:474
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
Definition eval.c:678
VALUE rb_eStandardError
StandardError exception.
Definition error.c:1454
VALUE rb_eRangeError
RangeError exception.
Definition error.c:1461
VALUE rb_eTypeError
TypeError exception.
Definition error.c:1457
void rb_warn(const char *fmt,...)
Identical to rb_warning(), except it reports unless $VERBOSE is nil.
Definition error.c:464
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.
Definition error.c:1508
VALUE rb_eException
Mother of all exceptions.
Definition error.c:1449
VALUE rb_eSysStackError
SystemStackError exception.
Definition eval.c:51
@ RB_WARN_CATEGORY_PERFORMANCE
Warning is for performance issues (not enabled by -w).
Definition error.h:54
VALUE rb_class_superclass(VALUE klass)
Queries the parent of the given class.
Definition object.c:2309
VALUE rb_cUnboundMethod
UnboundMethod class.
Definition proc.c:43
VALUE rb_mKernel
Kernel module.
Definition object.c:59
VALUE rb_cObject
Object class.
Definition object.c:60
VALUE rb_obj_hide(VALUE obj)
Make the object invisible from Ruby code.
Definition object.c:94
VALUE rb_cBinding
Binding class.
Definition proc.c:45
VALUE rb_obj_class(VALUE obj)
Queries the class of an object.
Definition object.c:234
VALUE rb_inspect(VALUE obj)
Generates a human-readable textual representation of the given object.
Definition object.c:669
VALUE rb_cModule
Module class.
Definition object.c:61
VALUE rb_class_inherited_p(VALUE scion, VALUE ascendant)
Determines if the given two modules are relatives.
Definition object.c:1843
VALUE rb_obj_is_kind_of(VALUE obj, VALUE klass)
Queries if the given object is an instance (of possibly descendants) of the given class.
Definition object.c:906
VALUE rb_cProc
Proc class.
Definition proc.c:46
VALUE rb_cMethod
Method class.
Definition proc.c:44
#define RB_OBJ_WRITTEN(old, oldv, young)
Identical to RB_OBJ_WRITE(), except it doesn't write any values, but only a WB declaration.
Definition gc.h:504
#define RB_OBJ_WRITE(old, slot, young)
Declaration of a "back" pointer.
Definition gc.h:492
VALUE rb_funcall(VALUE recv, ID mid, int n,...)
Calls a method.
Definition vm_eval.c:1123
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.
Definition vm_eval.c:1081
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...
Definition vm_eval.c:1210
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().
Definition error.h:35
static int rb_check_arity(int argc, int min, int max)
Ensures that the passed integer is in the passed range.
Definition error.h:284
int rb_is_local_id(ID id)
Classifies the given ID, then sees if it is a local variable.
Definition symbol.c:1265
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.
Definition proc.c:3386
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...
Definition proc.c:3766
VALUE rb_proc_call(VALUE recv, VALUE args)
Evaluates the passed proc with the passed arguments.
Definition proc.c:1743
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 ...
Definition proc.c:1755
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...
Definition proc.c:3343
VALUE rb_obj_method(VALUE recv, VALUE mid)
Creates a method object.
Definition proc.c:2921
VALUE rb_proc_lambda_p(VALUE recv)
Queries if the given object is a lambda.
Definition proc.c:822
VALUE rb_block_proc(void)
Constructs a Proc object from implicitly passed components.
Definition proc.c:1580
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,...
Definition proc.c:1768
int rb_mod_method_arity(VALUE mod, ID mid)
Queries the number of mandatory arguments of the method defined in the given module.
Definition proc.c:3758
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...
Definition proc.c:3373
VALUE rb_obj_is_method(VALUE recv)
Queries if the given object is a method.
Definition proc.c:2459
VALUE rb_block_lambda(void)
Identical to rb_proc_new(), except it returns a lambda.
Definition proc.c:1599
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...
Definition proc.c:1722
VALUE rb_binding_new(void)
Snapshots the current execution context and turn it into an instance of rb_cBinding.
Definition proc.c:906
int rb_proc_arity(VALUE recv)
Queries the number of mandatory arguments of the given Proc.
Definition proc.c:1875
VALUE rb_method_call(int argc, const VALUE *argv, VALUE recv)
Evaluates the passed method with the passed arguments.
Definition proc.c:3350
VALUE rb_obj_is_proc(VALUE recv)
Queries if the given object is a proc.
Definition proc.c:386
#define rb_hash_uint(h, i)
Just another name of st_hash_uint.
Definition string.h:967
#define rb_hash_end(h)
Just another name of st_hash_end.
Definition string.h:970
VALUE rb_str_append(VALUE dst, VALUE src)
Identical to rb_str_buf_append(), except it converts the right hand side before concatenating.
Definition string.c:3913
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.
Definition string.c:3879
void rb_str_set_len(VALUE str, long len)
Overwrites the length of the string.
Definition string.c:3500
st_index_t rb_hash_start(st_index_t i)
Starts a series of hashing.
Definition random.c:1714
#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.
Definition string.h:1681
#define rb_str_new_cstr(str)
Identical to rb_str_new, except it assumes the passed pointer is a pointer to a C string.
Definition string.h:1539
VALUE rb_str_intern(VALUE str)
Identical to rb_to_symbol(), except it assumes the receiver being an instance of RString.
Definition symbol.c:1085
VALUE rb_ivar_set(VALUE obj, ID name, VALUE val)
Identical to rb_iv_set(), except it accepts the name as an ID instead of a C string.
Definition variable.c:2141
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.
Definition variable.c:1641
void rb_undef_alloc_func(VALUE klass)
Deletes the allocator function of a class.
Definition vm_method.c:1846
int rb_method_basic_definition_p(VALUE klass, ID mid)
Well... Let us hesitate from describing what a "basic definition" is.
Definition vm_method.c:3571
int rb_obj_respond_to(VALUE obj, ID mid, int private_p)
Identical to rb_respond_to(), except it additionally takes the visibility parameter.
Definition vm_method.c:3677
ID rb_check_id(volatile VALUE *namep)
Detects if the given name is already interned or not.
Definition symbol.c:1289
VALUE rb_sym2str(VALUE symbol)
Obtain a frozen string representation of a symbol (not including the leading colon).
Definition symbol.c:1148
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...
Definition string.c:14136
VALUE rb_iv_get(VALUE obj, const char *name)
Obtains an instance variable.
Definition variable.c:4562
int len
Length of the buffer.
Definition io.h:8
#define RB_OBJ_SET_SHAREABLE(obj)
Wrapper of rb_obj_set_shareable().
Definition ractor.h:290
#define RB_INT2NUM
Just another name of rb_int2num_inline.
Definition int.h:37
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)
Shim for block function parameters.
Definition iterator.h:58
rb_block_call_func * rb_block_call_func_t
Shorthand type that represents an iterator-written-in-C function pointer.
Definition iterator.h:88
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.
Definition iterator.h:83
#define MEMCPY(p1, p2, type, n)
Handy macro to call memcpy.
Definition memory.h:372
#define RB_GC_GUARD(v)
Prevents premature destruction of local objects.
Definition memory.h:167
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.
Definition rarray.h:50
static void RARRAY_ASET(VALUE ary, long i, VALUE v)
Assigns an object in an array.
Definition rarray.h:385
static VALUE * RARRAY_PTR(VALUE ary)
Wild use of a C pointer.
Definition rarray.h:365
#define RARRAY_AREF(a, i)
Definition rarray.h:402
#define RARRAY_CONST_PTR
Just another name of rb_array_const_ptr.
Definition rarray.h:51
static VALUE RBASIC_CLASS(VALUE obj)
Queries the class of an object.
Definition rbasic.h:166
#define RBASIC(obj)
Convenient casting macro.
Definition rbasic.h:40
#define RCLASS_SUPER
Just another name of rb_class_get_superclass.
Definition rclass.h:44
#define RUBY_TYPED_DEFAULT_FREE
This is a value you can set to rb_data_type_struct::dfree.
Definition rtypeddata.h:81
#define RUBY_TYPED_FREE_IMMEDIATELY
Macros to see if each corresponding flag is defined.
Definition rtypeddata.h:122
#define TypedData_Get_Struct(obj, type, data_type, sval)
Obtains a C struct from inside of a wrapper Ruby object.
Definition rtypeddata.h:773
#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...
Definition rtypeddata.h:604
const char * rb_obj_classname(VALUE obj)
Queries the name of the class of the passed object.
Definition variable.c:533
#define RB_PASS_CALLED_KEYWORDS
Pass keywords if current method is called with keywords, useful for argument delegation.
Definition scan_args.h:78
#define RB_NO_KEYWORDS
Do not pass keywords.
Definition scan_args.h:69
#define RTEST
This is an old name of RB_TEST.
#define _(args)
This was a transition path from K&R to ANSI.
Definition stdarg.h:35
Definition proc.c:31
Internal header for Ruby Box.
Definition box.h:14
Definition method.h:63
CREF (Class REFerence)
Definition method.h:45
This is the struct that holds necessary info for a struct.
Definition rtypeddata.h:242
Definition method.h:55
rb_cref_t * cref
class reference, should be marked
Definition method.h:144
const rb_iseq_t * iseqptr
iseq pointer, should be separated from iseqval
Definition method.h:143
IFUNC (Internal FUNCtion)
Definition imemo.h:89
uintptr_t ID
Type that represents a Ruby identifier such as a variable name.
Definition value.h:52
#define SIZEOF_VALUE
Identical to sizeof(VALUE), except it is a macro that can also be used inside of preprocessor directi...
Definition value.h:69
uintptr_t VALUE
Type that represents a Ruby object.
Definition value.h:40
static void Check_Type(VALUE v, enum ruby_value_type t)
Identical to RB_TYPE_P(), except it raises exceptions on predication failure.
Definition value_type.h:425
static bool RB_TYPE_P(VALUE obj, enum ruby_value_type t)
Queries if the given object is of given type.
Definition value_type.h:376