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