Ruby: proc.c Source File

Ruby 3.0.5p211 (2022-11-24 revision ba5cf0f7c52d4d35cc6a173c89eda98ceffa2dcf)

proc.c
Go to the documentation of this file.
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 "gc.h"
14#include "internal.h"
15#include "internal/class.h"
16#include "internal/error.h"
17#include "internal/eval.h"
18#include "internal/object.h"
19#include "internal/proc.h"
20#include "internal/symbol.h"
21#include "iseq.h"
22#include "vm_core.h"
23
24#if !defined(__GNUC__) || __GNUC__ < 5 || defined(__MINGW32__)
25# define NO_CLOBBERED(v) (*(volatile VALUE *)&(v))
26#else
27# define NO_CLOBBERED(v) (v)
28#endif
29
30#define UPDATE_TYPED_REFERENCE(_type, _ref) *(_type*)&_ref = (_type)rb_gc_location((VALUE)_ref)
31#define UPDATE_REFERENCE(_ref) UPDATE_TYPED_REFERENCE(VALUE, _ref)
32
33const rb_cref_t *rb_vm_cref_in_context(VALUE self, VALUE cbase);
34
35 struct METHOD {
36 const VALUE recv;
37 const VALUE klass;
38 const VALUE iclass;
39 const rb_method_entry_t * const me;
40 /* for bound methods, `me' should be rb_callable_method_entry_t * */
41};
42
43 VALUE rb_cUnboundMethod;
44 VALUE rb_cMethod;
45 VALUE rb_cBinding;
46 VALUE rb_cProc;
47
48static rb_block_call_func bmcall;
49static int method_arity(VALUE);
50static int method_min_max_arity(VALUE, int *max);
51static VALUE proc_binding(VALUE self);
52
53#define attached id__attached__
54
55/* Proc */
56
57#define IS_METHOD_PROC_IFUNC(ifunc) ((ifunc)->func == bmcall)
58
59static void
60block_mark(const struct rb_block *block)
61{
62 switch (vm_block_type(block)) {
63 case block_type_iseq:
64 case block_type_ifunc:
65 {
66 const struct rb_captured_block *captured = &block->as.captured;
67 RUBY_MARK_MOVABLE_UNLESS_NULL(captured->self);
68 RUBY_MARK_MOVABLE_UNLESS_NULL((VALUE)captured->code.val);
69 if (captured->ep && captured->ep[VM_ENV_DATA_INDEX_ENV] != Qundef /* cfunc_proc_t */) {
70 rb_gc_mark(VM_ENV_ENVVAL(captured->ep));
71 }
72 }
73 break;
74 case block_type_symbol:
75 RUBY_MARK_MOVABLE_UNLESS_NULL(block->as.symbol);
76 break;
77 case block_type_proc:
78 RUBY_MARK_MOVABLE_UNLESS_NULL(block->as.proc);
79 break;
80 }
81}
82
83static void
84block_compact(struct rb_block *block)
85{
86 switch (block->type) {
87 case block_type_iseq:
88 case block_type_ifunc:
89 {
90 struct rb_captured_block *captured = &block->as.captured;
91 captured->self = rb_gc_location(captured->self);
92 captured->code.val = rb_gc_location(captured->code.val);
93 }
94 break;
95 case block_type_symbol:
96 block->as.symbol = rb_gc_location(block->as.symbol);
97 break;
98 case block_type_proc:
99 block->as.proc = rb_gc_location(block->as.proc);
100 break;
101 }
102}
103
104static void
105proc_compact(void *ptr)
106{
107 rb_proc_t *proc = ptr;
108 block_compact((struct rb_block *)&proc->block);
109}
110
111static void
112proc_mark(void *ptr)
113{
114 rb_proc_t *proc = ptr;
115 block_mark(&proc->block);
116 RUBY_MARK_LEAVE("proc");
117}
118
119 typedef struct {
120 rb_proc_t basic;
121 VALUE env[VM_ENV_DATA_SIZE + 1]; /* ..., envval */
122} cfunc_proc_t;
123
124static size_t
125proc_memsize(const void *ptr)
126{
127 const rb_proc_t *proc = ptr;
128 if (proc->block.as.captured.ep == ((const cfunc_proc_t *)ptr)->env+1)
129 return sizeof(cfunc_proc_t);
130 return sizeof(rb_proc_t);
131}
132
133static const rb_data_type_t proc_data_type = {
134 "proc",
135 {
136 proc_mark,
137 RUBY_TYPED_DEFAULT_FREE,
138 proc_memsize,
139 proc_compact,
140 },
141 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
142};
143
144 VALUE
145rb_proc_alloc(VALUE klass)
146{
147 rb_proc_t *proc;
148 return TypedData_Make_Struct(klass, rb_proc_t, &proc_data_type, proc);
149}
150
151 VALUE
152 rb_obj_is_proc(VALUE proc)
153{
154 if (rb_typeddata_is_kind_of(proc, &proc_data_type)) {
155 return Qtrue;
156 }
157 else {
158 return Qfalse;
159 }
160}
161
162/* :nodoc: */
163static VALUE
164proc_clone(VALUE self)
165{
166 VALUE procval = rb_proc_dup(self);
167 CLONESETUP(procval, self);
168 return procval;
169}
170
171/*
172 * call-seq:
173 * prc.lambda? -> true or false
174 *
175 * Returns +true+ if a Proc object is lambda.
176 * +false+ if non-lambda.
177 *
178 * The lambda-ness affects argument handling and the behavior of +return+ and +break+.
179 *
180 * A Proc object generated by +proc+ ignores extra arguments.
181 *
182 * proc {|a,b| [a,b] }.call(1,2,3) #=> [1,2]
183 *
184 * It provides +nil+ for missing arguments.
185 *
186 * proc {|a,b| [a,b] }.call(1) #=> [1,nil]
187 *
188 * It expands a single array argument.
189 *
190 * proc {|a,b| [a,b] }.call([1,2]) #=> [1,2]
191 *
192 * A Proc object generated by +lambda+ doesn't have such tricks.
193 *
194 * lambda {|a,b| [a,b] }.call(1,2,3) #=> ArgumentError
195 * lambda {|a,b| [a,b] }.call(1) #=> ArgumentError
196 * lambda {|a,b| [a,b] }.call([1,2]) #=> ArgumentError
197 *
198 * Proc#lambda? is a predicate for the tricks.
199 * It returns +true+ if no tricks apply.
200 *
201 * lambda {}.lambda? #=> true
202 * proc {}.lambda? #=> false
203 *
204 * Proc.new is the same as +proc+.
205 *
206 * Proc.new {}.lambda? #=> false
207 *
208 * +lambda+, +proc+ and Proc.new preserve the tricks of
209 * a Proc object given by <code>&</code> argument.
210 *
211 * lambda(&lambda {}).lambda? #=> true
212 * proc(&lambda {}).lambda? #=> true
213 * Proc.new(&lambda {}).lambda? #=> true
214 *
215 * lambda(&proc {}).lambda? #=> false
216 * proc(&proc {}).lambda? #=> false
217 * Proc.new(&proc {}).lambda? #=> false
218 *
219 * A Proc object generated by <code>&</code> argument has the tricks
220 *
221 * def n(&b) b.lambda? end
222 * n {} #=> false
223 *
224 * The <code>&</code> argument preserves the tricks if a Proc object
225 * is given by <code>&</code> argument.
226 *
227 * n(&lambda {}) #=> true
228 * n(&proc {}) #=> false
229 * n(&Proc.new {}) #=> false
230 *
231 * A Proc object converted from a method has no tricks.
232 *
233 * def m() end
234 * method(:m).to_proc.lambda? #=> true
235 *
236 * n(&method(:m)) #=> true
237 * n(&method(:m).to_proc) #=> true
238 *
239 * +define_method+ is treated the same as method definition.
240 * The defined method has no tricks.
241 *
242 * class C
243 * define_method(:d) {}
244 * end
245 * C.new.d(1,2) #=> ArgumentError
246 * C.new.method(:d).to_proc.lambda? #=> true
247 *
248 * +define_method+ always defines a method without the tricks,
249 * even if a non-lambda Proc object is given.
250 * This is the only exception for which the tricks are not preserved.
251 *
252 * class C
253 * define_method(:e, &proc {})
254 * end
255 * C.new.e(1,2) #=> ArgumentError
256 * C.new.method(:e).to_proc.lambda? #=> true
257 *
258 * This exception ensures that methods never have tricks
259 * and makes it easy to have wrappers to define methods that behave as usual.
260 *
261 * class C
262 * def self.def2(name, &body)
263 * define_method(name, &body)
264 * end
265 *
266 * def2(:f) {}
267 * end
268 * C.new.f(1,2) #=> ArgumentError
269 *
270 * The wrapper <i>def2</i> defines a method which has no tricks.
271 *
272 */
273
274 VALUE
275 rb_proc_lambda_p(VALUE procval)
276{
277 rb_proc_t *proc;
278 GetProcPtr(procval, proc);
279
280 return proc->is_lambda ? Qtrue : Qfalse;
281}
282
283/* Binding */
284
285static void
286binding_free(void *ptr)
287{
288 RUBY_FREE_ENTER("binding");
289 ruby_xfree(ptr);
290 RUBY_FREE_LEAVE("binding");
291}
292
293static void
294binding_mark(void *ptr)
295{
296 rb_binding_t *bind = ptr;
297
298 RUBY_MARK_ENTER("binding");
299 block_mark(&bind->block);
300 rb_gc_mark_movable(bind->pathobj);
301 RUBY_MARK_LEAVE("binding");
302}
303
304static void
305binding_compact(void *ptr)
306{
307 rb_binding_t *bind = ptr;
308
309 block_compact((struct rb_block *)&bind->block);
310 UPDATE_REFERENCE(bind->pathobj);
311}
312
313static size_t
314binding_memsize(const void *ptr)
315{
316 return sizeof(rb_binding_t);
317}
318
319 const rb_data_type_t ruby_binding_data_type = {
320 "binding",
321 {
322 binding_mark,
323 binding_free,
324 binding_memsize,
325 binding_compact,
326 },
327 0, 0, RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY
328};
329
330 VALUE
331rb_binding_alloc(VALUE klass)
332{
333 VALUE obj;
334 rb_binding_t *bind;
335 obj = TypedData_Make_Struct(klass, rb_binding_t, &ruby_binding_data_type, bind);
336 return obj;
337}
338
339
340/* :nodoc: */
341static VALUE
342binding_dup(VALUE self)
343{
344 VALUE bindval = rb_binding_alloc(rb_cBinding);
345 rb_binding_t *src, *dst;
346 GetBindingPtr(self, src);
347 GetBindingPtr(bindval, dst);
348 rb_vm_block_copy(bindval, &dst->block, &src->block);
349 RB_OBJ_WRITE(bindval, &dst->pathobj, src->pathobj);
350 dst->first_lineno = src->first_lineno;
351 return bindval;
352}
353
354/* :nodoc: */
355static VALUE
356binding_clone(VALUE self)
357{
358 VALUE bindval = binding_dup(self);
359 CLONESETUP(bindval, self);
360 return bindval;
361}
362
363 VALUE
364 rb_binding_new(void)
365{
366 rb_execution_context_t *ec = GET_EC();
367 return rb_vm_make_binding(ec, ec->cfp);
368}
369
370/*
371 * call-seq:
372 * binding -> a_binding
373 *
374 * Returns a +Binding+ object, describing the variable and
375 * method bindings at the point of call. This object can be used when
376 * calling +eval+ to execute the evaluated command in this
377 * environment. See also the description of class +Binding+.
378 *
379 * def get_binding(param)
380 * binding
381 * end
382 * b = get_binding("hello")
383 * eval("param", b) #=> "hello"
384 */
385
386static VALUE
387rb_f_binding(VALUE self)
388{
389 return rb_binding_new();
390}
391
392/*
393 * call-seq:
394 * binding.eval(string [, filename [,lineno]]) -> obj
395 *
396 * Evaluates the Ruby expression(s) in <em>string</em>, in the
397 * <em>binding</em>'s context. If the optional <em>filename</em> and
398 * <em>lineno</em> parameters are present, they will be used when
399 * reporting syntax errors.
400 *
401 * def get_binding(param)
402 * binding
403 * end
404 * b = get_binding("hello")
405 * b.eval("param") #=> "hello"
406 */
407
408static VALUE
409bind_eval(int argc, VALUE *argv, VALUE bindval)
410{
411 VALUE args[4];
412
413 rb_scan_args(argc, argv, "12", &args[0], &args[2], &args[3]);
414 args[1] = bindval;
415 return rb_f_eval(argc+1, args, Qnil /* self will be searched in eval */);
416}
417
418static const VALUE *
419get_local_variable_ptr(const rb_env_t **envp, ID lid)
420{
421 const rb_env_t *env = *envp;
422 do {
423 if (!VM_ENV_FLAGS(env->ep, VM_FRAME_FLAG_CFRAME)) {
424 if (VM_ENV_FLAGS(env->ep, VM_ENV_FLAG_ISOLATED)) {
425 return NULL;
426 }
427
428 const rb_iseq_t *iseq = env->iseq;
429 unsigned int i;
430
431 VM_ASSERT(rb_obj_is_iseq((VALUE)iseq));
432
433 for (i=0; i<iseq->body->local_table_size; i++) {
434 if (iseq->body->local_table[i] == lid) {
435 if (iseq->body->local_iseq == iseq &&
436 iseq->body->param.flags.has_block &&
437 (unsigned int)iseq->body->param.block_start == i) {
438 const VALUE *ep = env->ep;
439 if (!VM_ENV_FLAGS(ep, VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM)) {
440 RB_OBJ_WRITE(env, &env->env[i], rb_vm_bh_to_procval(GET_EC(), VM_ENV_BLOCK_HANDLER(ep)));
441 VM_ENV_FLAGS_SET(ep, VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM);
442 }
443 }
444
445 *envp = env;
446 return &env->env[i];
447 }
448 }
449 }
450 else {
451 *envp = NULL;
452 return NULL;
453 }
454 } while ((env = rb_vm_env_prev_env(env)) != NULL);
455
456 *envp = NULL;
457 return NULL;
458}
459
460/*
461 * check local variable name.
462 * returns ID if it's an already interned symbol, or 0 with setting
463 * local name in String to *namep.
464 */
465static ID
466check_local_id(VALUE bindval, volatile VALUE *pname)
467{
468 ID lid = rb_check_id(pname);
469 VALUE name = *pname;
470
471 if (lid) {
472 if (!rb_is_local_id(lid)) {
473 rb_name_err_raise("wrong local variable name `%1$s' for %2$s",
474 bindval, ID2SYM(lid));
475 }
476 }
477 else {
478 if (!rb_is_local_name(name)) {
479 rb_name_err_raise("wrong local variable name `%1$s' for %2$s",
480 bindval, name);
481 }
482 return 0;
483 }
484 return lid;
485}
486
487/*
488 * call-seq:
489 * binding.local_variables -> Array
490 *
491 * Returns the names of the binding's local variables as symbols.
492 *
493 * def foo
494 * a = 1
495 * 2.times do |n|
496 * binding.local_variables #=> [:a, :n]
497 * end
498 * end
499 *
500 * This method is the short version of the following code:
501 *
502 * binding.eval("local_variables")
503 *
504 */
505static VALUE
506bind_local_variables(VALUE bindval)
507{
508 const rb_binding_t *bind;
509 const rb_env_t *env;
510
511 GetBindingPtr(bindval, bind);
512 env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
513 return rb_vm_env_local_variables(env);
514}
515
516/*
517 * call-seq:
518 * binding.local_variable_get(symbol) -> obj
519 *
520 * Returns the value of the local variable +symbol+.
521 *
522 * def foo
523 * a = 1
524 * binding.local_variable_get(:a) #=> 1
525 * binding.local_variable_get(:b) #=> NameError
526 * end
527 *
528 * This method is the short version of the following code:
529 *
530 * binding.eval("#{symbol}")
531 *
532 */
533static VALUE
534bind_local_variable_get(VALUE bindval, VALUE sym)
535{
536 ID lid = check_local_id(bindval, &sym);
537 const rb_binding_t *bind;
538 const VALUE *ptr;
539 const rb_env_t *env;
540
541 if (!lid) goto undefined;
542
543 GetBindingPtr(bindval, bind);
544
545 env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
546 if ((ptr = get_local_variable_ptr(&env, lid)) != NULL) {
547 return *ptr;
548 }
549
550 sym = ID2SYM(lid);
551 undefined:
552 rb_name_err_raise("local variable `%1$s' is not defined for %2$s",
553 bindval, sym);
554 UNREACHABLE_RETURN(Qundef);
555}
556
557/*
558 * call-seq:
559 * binding.local_variable_set(symbol, obj) -> obj
560 *
561 * Set local variable named +symbol+ as +obj+.
562 *
563 * def foo
564 * a = 1
565 * bind = binding
566 * bind.local_variable_set(:a, 2) # set existing local variable `a'
567 * bind.local_variable_set(:b, 3) # create new local variable `b'
568 * # `b' exists only in binding
569 *
570 * p bind.local_variable_get(:a) #=> 2
571 * p bind.local_variable_get(:b) #=> 3
572 * p a #=> 2
573 * p b #=> NameError
574 * end
575 *
576 * This method behaves similarly to the following code:
577 *
578 * binding.eval("#{symbol} = #{obj}")
579 *
580 * if +obj+ can be dumped in Ruby code.
581 */
582static VALUE
583bind_local_variable_set(VALUE bindval, VALUE sym, VALUE val)
584{
585 ID lid = check_local_id(bindval, &sym);
586 rb_binding_t *bind;
587 const VALUE *ptr;
588 const rb_env_t *env;
589
590 if (!lid) lid = rb_intern_str(sym);
591
592 GetBindingPtr(bindval, bind);
593 env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
594 if ((ptr = get_local_variable_ptr(&env, lid)) == NULL) {
595 /* not found. create new env */
596 ptr = rb_binding_add_dynavars(bindval, bind, 1, &lid);
597 env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
598 }
599
600 RB_OBJ_WRITE(env, ptr, val);
601
602 return val;
603}
604
605/*
606 * call-seq:
607 * binding.local_variable_defined?(symbol) -> obj
608 *
609 * Returns +true+ if a local variable +symbol+ exists.
610 *
611 * def foo
612 * a = 1
613 * binding.local_variable_defined?(:a) #=> true
614 * binding.local_variable_defined?(:b) #=> false
615 * end
616 *
617 * This method is the short version of the following code:
618 *
619 * binding.eval("defined?(#{symbol}) == 'local-variable'")
620 *
621 */
622static VALUE
623bind_local_variable_defined_p(VALUE bindval, VALUE sym)
624{
625 ID lid = check_local_id(bindval, &sym);
626 const rb_binding_t *bind;
627 const rb_env_t *env;
628
629 if (!lid) return Qfalse;
630
631 GetBindingPtr(bindval, bind);
632 env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
633 return get_local_variable_ptr(&env, lid) ? Qtrue : Qfalse;
634}
635
636/*
637 * call-seq:
638 * binding.receiver -> object
639 *
640 * Returns the bound receiver of the binding object.
641 */
642static VALUE
643bind_receiver(VALUE bindval)
644{
645 const rb_binding_t *bind;
646 GetBindingPtr(bindval, bind);
647 return vm_block_self(&bind->block);
648}
649
650/*
651 * call-seq:
652 * binding.source_location -> [String, Integer]
653 *
654 * Returns the Ruby source filename and line number of the binding object.
655 */
656static VALUE
657bind_location(VALUE bindval)
658{
659 VALUE loc[2];
660 const rb_binding_t *bind;
661 GetBindingPtr(bindval, bind);
662 loc[0] = pathobj_path(bind->pathobj);
663 loc[1] = INT2FIX(bind->first_lineno);
664
665 return rb_ary_new4(2, loc);
666}
667
668static VALUE
669cfunc_proc_new(VALUE klass, VALUE ifunc)
670{
671 rb_proc_t *proc;
672 cfunc_proc_t *sproc;
673 VALUE procval = TypedData_Make_Struct(klass, cfunc_proc_t, &proc_data_type, sproc);
674 VALUE *ep;
675
676 proc = &sproc->basic;
677 vm_block_type_set(&proc->block, block_type_ifunc);
678
679 *(VALUE **)&proc->block.as.captured.ep = ep = sproc->env + VM_ENV_DATA_SIZE-1;
680 ep[VM_ENV_DATA_INDEX_FLAGS] = VM_FRAME_MAGIC_IFUNC | VM_FRAME_FLAG_CFRAME | VM_ENV_FLAG_LOCAL | VM_ENV_FLAG_ESCAPED;
681 ep[VM_ENV_DATA_INDEX_ME_CREF] = Qfalse;
682 ep[VM_ENV_DATA_INDEX_SPECVAL] = VM_BLOCK_HANDLER_NONE;
683 ep[VM_ENV_DATA_INDEX_ENV] = Qundef; /* envval */
684
685 /* self? */
686 RB_OBJ_WRITE(procval, &proc->block.as.captured.code.ifunc, ifunc);
687 proc->is_lambda = TRUE;
688 return procval;
689}
690
691static VALUE
692sym_proc_new(VALUE klass, VALUE sym)
693{
694 VALUE procval = rb_proc_alloc(klass);
695 rb_proc_t *proc;
696 GetProcPtr(procval, proc);
697
698 vm_block_type_set(&proc->block, block_type_symbol);
699 proc->is_lambda = TRUE;
700 RB_OBJ_WRITE(procval, &proc->block.as.symbol, sym);
701 return procval;
702}
703
704struct vm_ifunc *
705 rb_vm_ifunc_new(rb_block_call_func_t func, const void *data, int min_argc, int max_argc)
706{
707 union {
708 struct vm_ifunc_argc argc;
709 VALUE packed;
710 } arity;
711
712 if (min_argc < UNLIMITED_ARGUMENTS ||
713#if SIZEOF_INT * 2 > SIZEOF_VALUE
714 min_argc >= (int)(1U << (SIZEOF_VALUE * CHAR_BIT) / 2) ||
715#endif
716 0) {
717 rb_raise(rb_eRangeError, "minimum argument number out of range: %d",
718 min_argc);
719 }
720 if (max_argc < UNLIMITED_ARGUMENTS ||
721#if SIZEOF_INT * 2 > SIZEOF_VALUE
722 max_argc >= (int)(1U << (SIZEOF_VALUE * CHAR_BIT) / 2) ||
723#endif
724 0) {
725 rb_raise(rb_eRangeError, "maximum argument number out of range: %d",
726 max_argc);
727 }
728 arity.argc.min = min_argc;
729 arity.argc.max = max_argc;
730 VALUE ret = rb_imemo_new(imemo_ifunc, (VALUE)func, (VALUE)data, arity.packed, 0);
731 return (struct vm_ifunc *)ret;
732}
733
734 MJIT_FUNC_EXPORTED VALUE
735 rb_func_proc_new(rb_block_call_func_t func, VALUE val)
736{
737 struct vm_ifunc *ifunc = rb_vm_ifunc_proc_new(func, (void *)val);
738 return cfunc_proc_new(rb_cProc, (VALUE)ifunc);
739}
740
741 MJIT_FUNC_EXPORTED VALUE
742 rb_func_lambda_new(rb_block_call_func_t func, VALUE val, int min_argc, int max_argc)
743{
744 struct vm_ifunc *ifunc = rb_vm_ifunc_new(func, (void *)val, min_argc, max_argc);
745 return cfunc_proc_new(rb_cProc, (VALUE)ifunc);
746}
747
748static const char proc_without_block[] = "tried to create Proc object without a block";
749
750static VALUE
751proc_new(VALUE klass, int8_t is_lambda, int8_t kernel)
752{
753 VALUE procval;
754 const rb_execution_context_t *ec = GET_EC();
755 rb_control_frame_t *cfp = ec->cfp;
756 VALUE block_handler;
757
758 if ((block_handler = rb_vm_frame_block_handler(cfp)) == VM_BLOCK_HANDLER_NONE) {
759 rb_raise(rb_eArgError, proc_without_block);
760 }
761
762 /* block is in cf */
763 switch (vm_block_handler_type(block_handler)) {
764 case block_handler_type_proc:
765 procval = VM_BH_TO_PROC(block_handler);
766
767 if (RBASIC_CLASS(procval) == klass) {
768 return procval;
769 }
770 else {
771 VALUE newprocval = rb_proc_dup(procval);
772 RBASIC_SET_CLASS(newprocval, klass);
773 return newprocval;
774 }
775 break;
776
777 case block_handler_type_symbol:
778 return (klass != rb_cProc) ?
779 sym_proc_new(klass, VM_BH_TO_SYMBOL(block_handler)) :
780 rb_sym_to_proc(VM_BH_TO_SYMBOL(block_handler));
781 break;
782
783 case block_handler_type_ifunc:
784 return rb_vm_make_proc_lambda(ec, VM_BH_TO_CAPT_BLOCK(block_handler), klass, is_lambda);
785 case block_handler_type_iseq:
786 {
787 const struct rb_captured_block *captured = VM_BH_TO_CAPT_BLOCK(block_handler);
788 rb_control_frame_t *last_ruby_cfp = rb_vm_get_ruby_level_next_cfp(ec, cfp);
789 if (is_lambda && last_ruby_cfp && vm_cfp_forwarded_bh_p(last_ruby_cfp, block_handler)) {
790 is_lambda = false;
791 }
792 return rb_vm_make_proc_lambda(ec, captured, klass, is_lambda);
793 }
794 }
795 VM_UNREACHABLE(proc_new);
796 return Qnil;
797}
798
799/*
800 * call-seq:
801 * Proc.new {|...| block } -> a_proc
802 * Proc.new -> a_proc
803 *
804 * Creates a new Proc object, bound to the current context. Proc::new
805 * may be called without a block only within a method with an
806 * attached block, in which case that block is converted to the Proc
807 * object.
808 *
809 * def proc_from
810 * Proc.new
811 * end
812 * proc = proc_from { "hello" }
813 * proc.call #=> "hello"
814 */
815
816static VALUE
817rb_proc_s_new(int argc, VALUE *argv, VALUE klass)
818{
819 VALUE block = proc_new(klass, FALSE, FALSE);
820
821 rb_obj_call_init_kw(block, argc, argv, RB_PASS_CALLED_KEYWORDS);
822 return block;
823}
824
825 VALUE
826 rb_block_proc(void)
827{
828 return proc_new(rb_cProc, FALSE, FALSE);
829}
830
831/*
832 * call-seq:
833 * proc { |...| block } -> a_proc
834 *
835 * Equivalent to Proc.new.
836 */
837
838static VALUE
839f_proc(VALUE _)
840{
841 return proc_new(rb_cProc, FALSE, TRUE);
842}
843
844 VALUE
845 rb_block_lambda(void)
846{
847 return proc_new(rb_cProc, TRUE, FALSE);
848}
849
850static void
851f_lambda_warn(void)
852{
853 rb_control_frame_t *cfp = GET_EC()->cfp;
854 VALUE block_handler = rb_vm_frame_block_handler(cfp);
855
856 if (block_handler != VM_BLOCK_HANDLER_NONE) {
857 switch (vm_block_handler_type(block_handler)) {
858 case block_handler_type_iseq:
859 if (RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp)->ep == VM_BH_TO_ISEQ_BLOCK(block_handler)->ep) {
860 return;
861 }
862 break;
863 case block_handler_type_symbol:
864 return;
865 case block_handler_type_proc:
866 if (rb_proc_lambda_p(VM_BH_TO_PROC(block_handler))) {
867 return;
868 }
869 break;
870 case block_handler_type_ifunc:
871 break;
872 }
873 }
874
875 rb_warn_deprecated("lambda without a literal block", "the proc without lambda");
876}
877
878/*
879 * call-seq:
880 * lambda { |...| block } -> a_proc
881 *
882 * Equivalent to Proc.new, except the resulting Proc objects check the
883 * number of parameters passed when called.
884 */
885
886static VALUE
887f_lambda(VALUE _)
888{
889 f_lambda_warn();
890 return rb_block_lambda();
891}
892
893/* Document-method: Proc#===
894 *
895 * call-seq:
896 * proc === obj -> result_of_proc
897 *
898 * Invokes the block with +obj+ as the proc's parameter like Proc#call.
899 * This allows a proc object to be the target of a +when+ clause
900 * in a case statement.
901 */
902
903/* CHECKME: are the argument checking semantics correct? */
904
905/*
906 * Document-method: Proc#[]
907 * Document-method: Proc#call
908 * Document-method: Proc#yield
909 *
910 * call-seq:
911 * prc.call(params,...) -> obj
912 * prc[params,...] -> obj
913 * prc.(params,...) -> obj
914 * prc.yield(params,...) -> obj
915 *
916 * Invokes the block, setting the block's parameters to the values in
917 * <i>params</i> using something close to method calling semantics.
918 * Returns the value of the last expression evaluated in the block.
919 *
920 * a_proc = Proc.new {|scalar, *values| values.map {|value| value*scalar } }
921 * a_proc.call(9, 1, 2, 3) #=> [9, 18, 27]
922 * a_proc[9, 1, 2, 3] #=> [9, 18, 27]
923 * a_proc.(9, 1, 2, 3) #=> [9, 18, 27]
924 * a_proc.yield(9, 1, 2, 3) #=> [9, 18, 27]
925 *
926 * Note that <code>prc.()</code> invokes <code>prc.call()</code> with
927 * the parameters given. It's syntactic sugar to hide "call".
928 *
929 * For procs created using #lambda or <code>->()</code> an error is
930 * generated if the wrong number of parameters are passed to the
931 * proc. For procs created using Proc.new or Kernel.proc, extra
932 * parameters are silently discarded and missing parameters are set
933 * to +nil+.
934 *
935 * a_proc = proc {|a,b| [a,b] }
936 * a_proc.call(1) #=> [1, nil]
937 *
938 * a_proc = lambda {|a,b| [a,b] }
939 * a_proc.call(1) # ArgumentError: wrong number of arguments (given 1, expected 2)
940 *
941 * See also Proc#lambda?.
942 */
943#if 0
944static VALUE
945proc_call(int argc, VALUE *argv, VALUE procval)
946{
947 /* removed */
948}
949#endif
950
951#if SIZEOF_LONG > SIZEOF_INT
952static inline int
953 check_argc(long argc)
954{
955 if (argc > INT_MAX || argc < 0) {
956 rb_raise(rb_eArgError, "too many arguments (%lu)",
957 (unsigned long)argc);
958 }
959 return (int)argc;
960}
961#else
962#define check_argc(argc) (argc)
963#endif
964
965 VALUE
966 rb_proc_call_kw(VALUE self, VALUE args, int kw_splat)
967{
968 VALUE vret;
969 rb_proc_t *proc;
970 int argc = check_argc(RARRAY_LEN(args));
971 const VALUE *argv = RARRAY_CONST_PTR(args);
972 GetProcPtr(self, proc);
973 vret = rb_vm_invoke_proc(GET_EC(), proc, argc, argv,
974 kw_splat, VM_BLOCK_HANDLER_NONE);
975 RB_GC_GUARD(self);
976 RB_GC_GUARD(args);
977 return vret;
978}
979
980 VALUE
981 rb_proc_call(VALUE self, VALUE args)
982{
983 VALUE vret;
984 rb_proc_t *proc;
985 GetProcPtr(self, proc);
986 vret = rb_vm_invoke_proc(GET_EC(), proc,
987 check_argc(RARRAY_LEN(args)), RARRAY_CONST_PTR(args),
988 RB_NO_KEYWORDS, VM_BLOCK_HANDLER_NONE);
989 RB_GC_GUARD(self);
990 RB_GC_GUARD(args);
991 return vret;
992}
993
994static VALUE
995proc_to_block_handler(VALUE procval)
996{
997 return NIL_P(procval) ? VM_BLOCK_HANDLER_NONE : procval;
998}
999
1000 VALUE
1001 rb_proc_call_with_block_kw(VALUE self, int argc, const VALUE *argv, VALUE passed_procval, int kw_splat)
1002{
1003 rb_execution_context_t *ec = GET_EC();
1004 VALUE vret;
1005 rb_proc_t *proc;
1006 GetProcPtr(self, proc);
1007 vret = rb_vm_invoke_proc(ec, proc, argc, argv, kw_splat, proc_to_block_handler(passed_procval));
1008 RB_GC_GUARD(self);
1009 return vret;
1010}
1011
1012 VALUE
1013 rb_proc_call_with_block(VALUE self, int argc, const VALUE *argv, VALUE passed_procval)
1014{
1015 rb_execution_context_t *ec = GET_EC();
1016 VALUE vret;
1017 rb_proc_t *proc;
1018 GetProcPtr(self, proc);
1019 vret = rb_vm_invoke_proc(ec, proc, argc, argv, RB_NO_KEYWORDS, proc_to_block_handler(passed_procval));
1020 RB_GC_GUARD(self);
1021 return vret;
1022}
1023
1024
1025/*
1026 * call-seq:
1027 * prc.arity -> integer
1028 *
1029 * Returns the number of mandatory arguments. If the block
1030 * is declared to take no arguments, returns 0. If the block is known
1031 * to take exactly n arguments, returns n.
1032 * If the block has optional arguments, returns -n-1, where n is the
1033 * number of mandatory arguments, with the exception for blocks that
1034 * are not lambdas and have only a finite number of optional arguments;
1035 * in this latter case, returns n.
1036 * Keyword arguments will be considered as a single additional argument,
1037 * that argument being mandatory if any keyword argument is mandatory.
1038 * A #proc with no argument declarations is the same as a block
1039 * declaring <code>||</code> as its arguments.
1040 *
1041 * proc {}.arity #=> 0
1042 * proc { || }.arity #=> 0
1043 * proc { |a| }.arity #=> 1
1044 * proc { |a, b| }.arity #=> 2
1045 * proc { |a, b, c| }.arity #=> 3
1046 * proc { |*a| }.arity #=> -1
1047 * proc { |a, *b| }.arity #=> -2
1048 * proc { |a, *b, c| }.arity #=> -3
1049 * proc { |x:, y:, z:0| }.arity #=> 1
1050 * proc { |*a, x:, y:0| }.arity #=> -2
1051 *
1052 * proc { |a=0| }.arity #=> 0
1053 * lambda { |a=0| }.arity #=> -1
1054 * proc { |a=0, b| }.arity #=> 1
1055 * lambda { |a=0, b| }.arity #=> -2
1056 * proc { |a=0, b=0| }.arity #=> 0
1057 * lambda { |a=0, b=0| }.arity #=> -1
1058 * proc { |a, b=0| }.arity #=> 1
1059 * lambda { |a, b=0| }.arity #=> -2
1060 * proc { |(a, b), c=0| }.arity #=> 1
1061 * lambda { |(a, b), c=0| }.arity #=> -2
1062 * proc { |a, x:0, y:0| }.arity #=> 1
1063 * lambda { |a, x:0, y:0| }.arity #=> -2
1064 */
1065
1066static VALUE
1067proc_arity(VALUE self)
1068{
1069 int arity = rb_proc_arity(self);
1070 return INT2FIX(arity);
1071}
1072
1073static inline int
1074rb_iseq_min_max_arity(const rb_iseq_t *iseq, int *max)
1075{
1076 *max = iseq->body->param.flags.has_rest == FALSE ?
1077 iseq->body->param.lead_num + iseq->body->param.opt_num + iseq->body->param.post_num +
1078 (iseq->body->param.flags.has_kw == TRUE || iseq->body->param.flags.has_kwrest == TRUE)
1079 : UNLIMITED_ARGUMENTS;
1080 return iseq->body->param.lead_num + iseq->body->param.post_num + (iseq->body->param.flags.has_kw && iseq->body->param.keyword->required_num > 0);
1081}
1082
1083static int
1084rb_vm_block_min_max_arity(const struct rb_block *block, int *max)
1085{
1086 again:
1087 switch (vm_block_type(block)) {
1088 case block_type_iseq:
1089 return rb_iseq_min_max_arity(rb_iseq_check(block->as.captured.code.iseq), max);
1090 case block_type_proc:
1091 block = vm_proc_block(block->as.proc);
1092 goto again;
1093 case block_type_ifunc:
1094 {
1095 const struct vm_ifunc *ifunc = block->as.captured.code.ifunc;
1096 if (IS_METHOD_PROC_IFUNC(ifunc)) {
1097 /* e.g. method(:foo).to_proc.arity */
1098 return method_min_max_arity((VALUE)ifunc->data, max);
1099 }
1100 *max = ifunc->argc.max;
1101 return ifunc->argc.min;
1102 }
1103 case block_type_symbol:
1104 *max = UNLIMITED_ARGUMENTS;
1105 return 1;
1106 }
1107 *max = UNLIMITED_ARGUMENTS;
1108 return 0;
1109}
1110
1111/*
1112 * Returns the number of required parameters and stores the maximum
1113 * number of parameters in max, or UNLIMITED_ARGUMENTS if no max.
1114 * For non-lambda procs, the maximum is the number of non-ignored
1115 * parameters even though there is no actual limit to the number of parameters
1116 */
1117static int
1118rb_proc_min_max_arity(VALUE self, int *max)
1119{
1120 rb_proc_t *proc;
1121 GetProcPtr(self, proc);
1122 return rb_vm_block_min_max_arity(&proc->block, max);
1123}
1124
1125int
1126 rb_proc_arity(VALUE self)
1127{
1128 rb_proc_t *proc;
1129 int max, min;
1130 GetProcPtr(self, proc);
1131 min = rb_vm_block_min_max_arity(&proc->block, &max);
1132 return (proc->is_lambda ? min == max : max != UNLIMITED_ARGUMENTS) ? min : -min-1;
1133}
1134
1135static void
1136block_setup(struct rb_block *block, VALUE block_handler)
1137{
1138 switch (vm_block_handler_type(block_handler)) {
1139 case block_handler_type_iseq:
1140 block->type = block_type_iseq;
1141 block->as.captured = *VM_BH_TO_ISEQ_BLOCK(block_handler);
1142 break;
1143 case block_handler_type_ifunc:
1144 block->type = block_type_ifunc;
1145 block->as.captured = *VM_BH_TO_IFUNC_BLOCK(block_handler);
1146 break;
1147 case block_handler_type_symbol:
1148 block->type = block_type_symbol;
1149 block->as.symbol = VM_BH_TO_SYMBOL(block_handler);
1150 break;
1151 case block_handler_type_proc:
1152 block->type = block_type_proc;
1153 block->as.proc = VM_BH_TO_PROC(block_handler);
1154 }
1155}
1156
1157int
1158 rb_block_pair_yield_optimizable(void)
1159{
1160 int min, max;
1161 const rb_execution_context_t *ec = GET_EC();
1162 rb_control_frame_t *cfp = ec->cfp;
1163 VALUE block_handler = rb_vm_frame_block_handler(cfp);
1164 struct rb_block block;
1165
1166 if (block_handler == VM_BLOCK_HANDLER_NONE) {
1167 rb_raise(rb_eArgError, "no block given");
1168 }
1169
1170 block_setup(&block, block_handler);
1171 min = rb_vm_block_min_max_arity(&block, &max);
1172
1173 switch (vm_block_type(&block)) {
1174 case block_handler_type_symbol:
1175 return 0;
1176
1177 case block_handler_type_proc:
1178 {
1179 VALUE procval = block_handler;
1180 rb_proc_t *proc;
1181 GetProcPtr(procval, proc);
1182 if (proc->is_lambda) return 0;
1183 if (min != max) return 0;
1184 return min > 1;
1185 }
1186
1187 default:
1188 return min > 1;
1189 }
1190}
1191
1192int
1193 rb_block_arity(void)
1194{
1195 int min, max;
1196 const rb_execution_context_t *ec = GET_EC();
1197 rb_control_frame_t *cfp = ec->cfp;
1198 VALUE block_handler = rb_vm_frame_block_handler(cfp);
1199 struct rb_block block;
1200
1201 if (block_handler == VM_BLOCK_HANDLER_NONE) {
1202 rb_raise(rb_eArgError, "no block given");
1203 }
1204
1205 block_setup(&block, block_handler);
1206 min = rb_vm_block_min_max_arity(&block, &max);
1207
1208 switch (vm_block_type(&block)) {
1209 case block_handler_type_symbol:
1210 return -1;
1211
1212 case block_handler_type_proc:
1213 {
1214 VALUE procval = block_handler;
1215 rb_proc_t *proc;
1216 GetProcPtr(procval, proc);
1217 return (proc->is_lambda ? min == max : max != UNLIMITED_ARGUMENTS) ? min : -min-1;
1218 }
1219
1220 default:
1221 return max != UNLIMITED_ARGUMENTS ? min : -min-1;
1222 }
1223}
1224
1225int
1226 rb_block_min_max_arity(int *max)
1227{
1228 const rb_execution_context_t *ec = GET_EC();
1229 rb_control_frame_t *cfp = ec->cfp;
1230 VALUE block_handler = rb_vm_frame_block_handler(cfp);
1231 struct rb_block block;
1232
1233 if (block_handler == VM_BLOCK_HANDLER_NONE) {
1234 rb_raise(rb_eArgError, "no block given");
1235 }
1236
1237 block_setup(&block, block_handler);
1238 return rb_vm_block_min_max_arity(&block, max);
1239}
1240
1241const rb_iseq_t *
1242 rb_proc_get_iseq(VALUE self, int *is_proc)
1243{
1244 const rb_proc_t *proc;
1245 const struct rb_block *block;
1246
1247 GetProcPtr(self, proc);
1248 block = &proc->block;
1249 if (is_proc) *is_proc = !proc->is_lambda;
1250
1251 switch (vm_block_type(block)) {
1252 case block_type_iseq:
1253 return rb_iseq_check(block->as.captured.code.iseq);
1254 case block_type_proc:
1255 return rb_proc_get_iseq(block->as.proc, is_proc);
1256 case block_type_ifunc:
1257 {
1258 const struct vm_ifunc *ifunc = block->as.captured.code.ifunc;
1259 if (IS_METHOD_PROC_IFUNC(ifunc)) {
1260 /* method(:foo).to_proc */
1261 if (is_proc) *is_proc = 0;
1262 return rb_method_iseq((VALUE)ifunc->data);
1263 }
1264 else {
1265 return NULL;
1266 }
1267 }
1268 case block_type_symbol:
1269 return NULL;
1270 }
1271
1272 VM_UNREACHABLE(rb_proc_get_iseq);
1273 return NULL;
1274}
1275
1276/* call-seq:
1277 * prc == other -> true or false
1278 * prc.eql?(other) -> true or false
1279 *
1280 * Two proc are the same if, and only if, they were created from the same code block.
1281 *
1282 * def return_block(&block)
1283 * block
1284 * end
1285 *
1286 * def pass_block_twice(&block)
1287 * [return_block(&block), return_block(&block)]
1288 * end
1289 *
1290 * block1, block2 = pass_block_twice { puts 'test' }
1291 * # Blocks might be instantiated into Proc's lazily, so they may, or may not,
1292 * # be the same object.
1293 * # But they are produced from the same code block, so they are equal
1294 * block1 == block2
1295 * #=> true
1296 *
1297 * # Another Proc will never be equal, even if the code is the "same"
1298 * block1 == proc { puts 'test' }
1299 * #=> false
1300 *
1301 */
1302static VALUE
1303proc_eq(VALUE self, VALUE other)
1304{
1305 const rb_proc_t *self_proc, *other_proc;
1306 const struct rb_block *self_block, *other_block;
1307
1308 if (rb_obj_class(self) != rb_obj_class(other)) {
1309 return Qfalse;
1310 }
1311
1312 GetProcPtr(self, self_proc);
1313 GetProcPtr(other, other_proc);
1314
1315 if (self_proc->is_from_method != other_proc->is_from_method ||
1316 self_proc->is_lambda != other_proc->is_lambda) {
1317 return Qfalse;
1318 }
1319
1320 self_block = &self_proc->block;
1321 other_block = &other_proc->block;
1322
1323 if (vm_block_type(self_block) != vm_block_type(other_block)) {
1324 return Qfalse;
1325 }
1326
1327 switch (vm_block_type(self_block)) {
1328 case block_type_iseq:
1329 if (self_block->as.captured.ep != \
1330 other_block->as.captured.ep ||
1331 self_block->as.captured.code.iseq != \
1332 other_block->as.captured.code.iseq) {
1333 return Qfalse;
1334 }
1335 break;
1336 case block_type_ifunc:
1337 if (self_block->as.captured.ep != \
1338 other_block->as.captured.ep ||
1339 self_block->as.captured.code.ifunc != \
1340 other_block->as.captured.code.ifunc) {
1341 return Qfalse;
1342 }
1343 break;
1344 case block_type_proc:
1345 if (self_block->as.proc != other_block->as.proc) {
1346 return Qfalse;
1347 }
1348 break;
1349 case block_type_symbol:
1350 if (self_block->as.symbol != other_block->as.symbol) {
1351 return Qfalse;
1352 }
1353 break;
1354 }
1355
1356 return Qtrue;
1357}
1358
1359static VALUE
1360iseq_location(const rb_iseq_t *iseq)
1361{
1362 VALUE loc[2];
1363
1364 if (!iseq) return Qnil;
1365 rb_iseq_check(iseq);
1366 loc[0] = rb_iseq_path(iseq);
1367 loc[1] = iseq->body->location.first_lineno;
1368
1369 return rb_ary_new4(2, loc);
1370}
1371
1372 MJIT_FUNC_EXPORTED VALUE
1373rb_iseq_location(const rb_iseq_t *iseq)
1374{
1375 return iseq_location(iseq);
1376}
1377
1378/*
1379 * call-seq:
1380 * prc.source_location -> [String, Integer]
1381 *
1382 * Returns the Ruby source filename and line number containing this proc
1383 * or +nil+ if this proc was not defined in Ruby (i.e. native).
1384 */
1385
1386 VALUE
1387 rb_proc_location(VALUE self)
1388{
1389 return iseq_location(rb_proc_get_iseq(self, 0));
1390}
1391
1392 VALUE
1393 rb_unnamed_parameters(int arity)
1394{
1395 VALUE a, param = rb_ary_new2((arity < 0) ? -arity : arity);
1396 int n = (arity < 0) ? ~arity : arity;
1397 ID req, rest;
1398 CONST_ID(req, "req");
1399 a = rb_ary_new3(1, ID2SYM(req));
1400 OBJ_FREEZE(a);
1401 for (; n; --n) {
1402 rb_ary_push(param, a);
1403 }
1404 if (arity < 0) {
1405 CONST_ID(rest, "rest");
1406 rb_ary_store(param, ~arity, rb_ary_new3(1, ID2SYM(rest)));
1407 }
1408 return param;
1409}
1410
1411/*
1412 * call-seq:
1413 * prc.parameters -> array
1414 *
1415 * Returns the parameter information of this proc.
1416 *
1417 * prc = lambda{|x, y=42, *other|}
1418 * prc.parameters #=> [[:req, :x], [:opt, :y], [:rest, :other]]
1419 */
1420
1421static VALUE
1422rb_proc_parameters(VALUE self)
1423{
1424 int is_proc;
1425 const rb_iseq_t *iseq = rb_proc_get_iseq(self, &is_proc);
1426 if (!iseq) {
1427 return rb_unnamed_parameters(rb_proc_arity(self));
1428 }
1429 return rb_iseq_parameters(iseq, is_proc);
1430}
1431
1432 st_index_t
1433 rb_hash_proc(st_index_t hash, VALUE prc)
1434{
1435 rb_proc_t *proc;
1436 GetProcPtr(prc, proc);
1437 hash = rb_hash_uint(hash, (st_index_t)proc->block.as.captured.code.val);
1438 hash = rb_hash_uint(hash, (st_index_t)proc->block.as.captured.self);
1439 return rb_hash_uint(hash, (st_index_t)proc->block.as.captured.ep >> 16);
1440}
1441
1442 MJIT_FUNC_EXPORTED VALUE
1443 rb_sym_to_proc(VALUE sym)
1444{
1445 static VALUE sym_proc_cache = Qfalse;
1446 enum {SYM_PROC_CACHE_SIZE = 67};
1447 VALUE proc;
1448 long index;
1449 ID id;
1450
1451 if (!sym_proc_cache) {
1452 sym_proc_cache = rb_ary_tmp_new(SYM_PROC_CACHE_SIZE * 2);
1453 rb_gc_register_mark_object(sym_proc_cache);
1454 rb_ary_store(sym_proc_cache, SYM_PROC_CACHE_SIZE*2 - 1, Qnil);
1455 }
1456
1457 id = SYM2ID(sym);
1458 index = (id % SYM_PROC_CACHE_SIZE) << 1;
1459
1460 if (RARRAY_AREF(sym_proc_cache, index) == sym) {
1461 return RARRAY_AREF(sym_proc_cache, index + 1);
1462 }
1463 else {
1464 proc = sym_proc_new(rb_cProc, ID2SYM(id));
1465 RARRAY_ASET(sym_proc_cache, index, sym);
1466 RARRAY_ASET(sym_proc_cache, index + 1, proc);
1467 return proc;
1468 }
1469}
1470
1471/*
1472 * call-seq:
1473 * prc.hash -> integer
1474 *
1475 * Returns a hash value corresponding to proc body.
1476 *
1477 * See also Object#hash.
1478 */
1479
1480static VALUE
1481proc_hash(VALUE self)
1482{
1483 st_index_t hash;
1484 hash = rb_hash_start(0);
1485 hash = rb_hash_proc(hash, self);
1486 hash = rb_hash_end(hash);
1487 return ST2FIX(hash);
1488}
1489
1490 VALUE
1491 rb_block_to_s(VALUE self, const struct rb_block *block, const char *additional_info)
1492{
1493 VALUE cname = rb_obj_class(self);
1494 VALUE str = rb_sprintf("#<%"PRIsVALUE":", cname);
1495
1496 again:
1497 switch (vm_block_type(block)) {
1498 case block_type_proc:
1499 block = vm_proc_block(block->as.proc);
1500 goto again;
1501 case block_type_iseq:
1502 {
1503 const rb_iseq_t *iseq = rb_iseq_check(block->as.captured.code.iseq);
1504 rb_str_catf(str, "%p %"PRIsVALUE":%d", (void *)self,
1505 rb_iseq_path(iseq),
1506 FIX2INT(iseq->body->location.first_lineno));
1507 }
1508 break;
1509 case block_type_symbol:
1510 rb_str_catf(str, "%p(&%+"PRIsVALUE")", (void *)self, block->as.symbol);
1511 break;
1512 case block_type_ifunc:
1513 rb_str_catf(str, "%p", (void *)block->as.captured.code.ifunc);
1514 break;
1515 }
1516
1517 if (additional_info) rb_str_cat_cstr(str, additional_info);
1518 rb_str_cat_cstr(str, ">");
1519 return str;
1520}
1521
1522/*
1523 * call-seq:
1524 * prc.to_s -> string
1525 *
1526 * Returns the unique identifier for this proc, along with
1527 * an indication of where the proc was defined.
1528 */
1529
1530static VALUE
1531proc_to_s(VALUE self)
1532{
1533 const rb_proc_t *proc;
1534 GetProcPtr(self, proc);
1535 return rb_block_to_s(self, &proc->block, proc->is_lambda ? " (lambda)" : NULL);
1536}
1537
1538/*
1539 * call-seq:
1540 * prc.to_proc -> proc
1541 *
1542 * Part of the protocol for converting objects to Proc objects.
1543 * Instances of class Proc simply return themselves.
1544 */
1545
1546static VALUE
1547proc_to_proc(VALUE self)
1548{
1549 return self;
1550}
1551
1552static void
1553bm_mark(void *ptr)
1554{
1555 struct METHOD *data = ptr;
1556 rb_gc_mark_movable(data->recv);
1557 rb_gc_mark_movable(data->klass);
1558 rb_gc_mark_movable(data->iclass);
1559 rb_gc_mark_movable((VALUE)data->me);
1560}
1561
1562static void
1563bm_compact(void *ptr)
1564{
1565 struct METHOD *data = ptr;
1566 UPDATE_REFERENCE(data->recv);
1567 UPDATE_REFERENCE(data->klass);
1568 UPDATE_REFERENCE(data->iclass);
1569 UPDATE_TYPED_REFERENCE(rb_method_entry_t *, data->me);
1570}
1571
1572static size_t
1573bm_memsize(const void *ptr)
1574{
1575 return sizeof(struct METHOD);
1576}
1577
1578static const rb_data_type_t method_data_type = {
1579 "method",
1580 {
1581 bm_mark,
1582 RUBY_TYPED_DEFAULT_FREE,
1583 bm_memsize,
1584 bm_compact,
1585 },
1586 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
1587};
1588
1589 VALUE
1590 rb_obj_is_method(VALUE m)
1591{
1592 if (rb_typeddata_is_kind_of(m, &method_data_type)) {
1593 return Qtrue;
1594 }
1595 else {
1596 return Qfalse;
1597 }
1598}
1599
1600static int
1601respond_to_missing_p(VALUE klass, VALUE obj, VALUE sym, int scope)
1602{
1603 /* TODO: merge with obj_respond_to() */
1604 ID rmiss = idRespond_to_missing;
1605
1606 if (obj == Qundef) return 0;
1607 if (rb_method_basic_definition_p(klass, rmiss)) return 0;
1608 return RTEST(rb_funcall(obj, rmiss, 2, sym, scope ? Qfalse : Qtrue));
1609}
1610
1611
1612static VALUE
1613mnew_missing(VALUE klass, VALUE obj, ID id, VALUE mclass)
1614{
1615 struct METHOD *data;
1616 VALUE method = TypedData_Make_Struct(mclass, struct METHOD, &method_data_type, data);
1617 rb_method_entry_t *me;
1618 rb_method_definition_t *def;
1619
1620 RB_OBJ_WRITE(method, &data->recv, obj);
1621 RB_OBJ_WRITE(method, &data->klass, klass);
1622
1623 def = ZALLOC(rb_method_definition_t);
1624 def->type = VM_METHOD_TYPE_MISSING;
1625 def->original_id = id;
1626
1627 me = rb_method_entry_create(id, klass, METHOD_VISI_UNDEF, def);
1628
1629 RB_OBJ_WRITE(method, &data->me, me);
1630
1631 return method;
1632}
1633
1634static VALUE
1635mnew_missing_by_name(VALUE klass, VALUE obj, VALUE *name, int scope, VALUE mclass)
1636{
1637 VALUE vid = rb_str_intern(*name);
1638 *name = vid;
1639 if (!respond_to_missing_p(klass, obj, vid, scope)) return Qfalse;
1640 return mnew_missing(klass, obj, SYM2ID(vid), mclass);
1641}
1642
1643static VALUE
1644mnew_internal(const rb_method_entry_t *me, VALUE klass, VALUE iclass,
1645 VALUE obj, ID id, VALUE mclass, int scope, int error)
1646{
1647 struct METHOD *data;
1648 VALUE method;
1649 rb_method_visibility_t visi = METHOD_VISI_UNDEF;
1650
1651 again:
1652 if (UNDEFINED_METHOD_ENTRY_P(me)) {
1653 if (respond_to_missing_p(klass, obj, ID2SYM(id), scope)) {
1654 return mnew_missing(klass, obj, id, mclass);
1655 }
1656 if (!error) return Qnil;
1657 rb_print_undef(klass, id, METHOD_VISI_UNDEF);
1658 }
1659 if (visi == METHOD_VISI_UNDEF) {
1660 visi = METHOD_ENTRY_VISI(me);
1661 if (scope && (visi != METHOD_VISI_PUBLIC)) {
1662 if (!error) return Qnil;
1663 rb_print_inaccessible(klass, id, visi);
1664 }
1665 }
1666 if (me->def->type == VM_METHOD_TYPE_ZSUPER) {
1667 if (me->defined_class) {
1668 VALUE klass = RCLASS_SUPER(RCLASS_ORIGIN(me->defined_class));
1669 id = me->def->original_id;
1670 me = (rb_method_entry_t *)rb_callable_method_entry_with_refinements(klass, id, &iclass);
1671 }
1672 else {
1673 VALUE klass = RCLASS_SUPER(RCLASS_ORIGIN(me->owner));
1674 id = me->def->original_id;
1675 me = rb_method_entry_without_refinements(klass, id, &iclass);
1676 }
1677 goto again;
1678 }
1679
1680 method = TypedData_Make_Struct(mclass, struct METHOD, &method_data_type, data);
1681
1682 RB_OBJ_WRITE(method, &data->recv, obj);
1683 RB_OBJ_WRITE(method, &data->klass, klass);
1684 RB_OBJ_WRITE(method, &data->iclass, iclass);
1685 RB_OBJ_WRITE(method, &data->me, me);
1686
1687 return method;
1688}
1689
1690static VALUE
1691mnew_from_me(const rb_method_entry_t *me, VALUE klass, VALUE iclass,
1692 VALUE obj, ID id, VALUE mclass, int scope)
1693{
1694 return mnew_internal(me, klass, iclass, obj, id, mclass, scope, TRUE);
1695}
1696
1697static VALUE
1698mnew(VALUE klass, VALUE obj, ID id, VALUE mclass, int scope)
1699{
1700 const rb_method_entry_t *me;
1701 VALUE iclass = Qnil;
1702
1703 if (obj == Qundef) { /* UnboundMethod */
1704 me = rb_method_entry_with_refinements(klass, id, &iclass);
1705 }
1706 else {
1707 me = (rb_method_entry_t *)rb_callable_method_entry_with_refinements(klass, id, &iclass);
1708 }
1709 return mnew_from_me(me, klass, iclass, obj, id, mclass, scope);
1710}
1711
1712static inline VALUE
1713method_entry_defined_class(const rb_method_entry_t *me)
1714{
1715 VALUE defined_class = me->defined_class;
1716 return defined_class ? defined_class : me->owner;
1717}
1718
1719/**********************************************************************
1720 *
1721 * Document-class: Method
1722 *
1723 * Method objects are created by Object#method, and are associated
1724 * with a particular object (not just with a class). They may be
1725 * used to invoke the method within the object, and as a block
1726 * associated with an iterator. They may also be unbound from one
1727 * object (creating an UnboundMethod) and bound to another.
1728 *
1729 * class Thing
1730 * def square(n)
1731 * n*n
1732 * end
1733 * end
1734 * thing = Thing.new
1735 * meth = thing.method(:square)
1736 *
1737 * meth.call(9) #=> 81
1738 * [ 1, 2, 3 ].collect(&meth) #=> [1, 4, 9]
1739 *
1740 * [ 1, 2, 3 ].each(&method(:puts)) #=> prints 1, 2, 3
1741 *
1742 * require 'date'
1743 * %w[2017-03-01 2017-03-02].collect(&Date.method(:parse))
1744 * #=> [#<Date: 2017-03-01 ((2457814j,0s,0n),+0s,2299161j)>, #<Date: 2017-03-02 ((2457815j,0s,0n),+0s,2299161j)>]
1745 */
1746
1747/*
1748 * call-seq:
1749 * meth.eql?(other_meth) -> true or false
1750 * meth == other_meth -> true or false
1751 *
1752 * Two method objects are equal if they are bound to the same
1753 * object and refer to the same method definition and the classes
1754 * defining the methods are the same class or module.
1755 */
1756
1757static VALUE
1758method_eq(VALUE method, VALUE other)
1759{
1760 struct METHOD *m1, *m2;
1761 VALUE klass1, klass2;
1762
1763 if (!rb_obj_is_method(other))
1764 return Qfalse;
1765 if (CLASS_OF(method) != CLASS_OF(other))
1766 return Qfalse;
1767
1768 Check_TypedStruct(method, &method_data_type);
1769 m1 = (struct METHOD *)DATA_PTR(method);
1770 m2 = (struct METHOD *)DATA_PTR(other);
1771
1772 klass1 = method_entry_defined_class(m1->me);
1773 klass2 = method_entry_defined_class(m2->me);
1774
1775 if (!rb_method_entry_eq(m1->me, m2->me) ||
1776 klass1 != klass2 ||
1777 m1->klass != m2->klass ||
1778 m1->recv != m2->recv) {
1779 return Qfalse;
1780 }
1781
1782 return Qtrue;
1783}
1784
1785/*
1786 * call-seq:
1787 * meth.hash -> integer
1788 *
1789 * Returns a hash value corresponding to the method object.
1790 *
1791 * See also Object#hash.
1792 */
1793
1794static VALUE
1795method_hash(VALUE method)
1796{
1797 struct METHOD *m;
1798 st_index_t hash;
1799
1800 TypedData_Get_Struct(method, struct METHOD, &method_data_type, m);
1801 hash = rb_hash_start((st_index_t)m->recv);
1802 hash = rb_hash_method_entry(hash, m->me);
1803 hash = rb_hash_end(hash);
1804
1805 return ST2FIX(hash);
1806}
1807
1808/*
1809 * call-seq:
1810 * meth.unbind -> unbound_method
1811 *
1812 * Dissociates <i>meth</i> from its current receiver. The resulting
1813 * UnboundMethod can subsequently be bound to a new object of the
1814 * same class (see UnboundMethod).
1815 */
1816
1817static VALUE
1818method_unbind(VALUE obj)
1819{
1820 VALUE method;
1821 struct METHOD *orig, *data;
1822
1823 TypedData_Get_Struct(obj, struct METHOD, &method_data_type, orig);
1824 method = TypedData_Make_Struct(rb_cUnboundMethod, struct METHOD,
1825 &method_data_type, data);
1826 RB_OBJ_WRITE(method, &data->recv, Qundef);
1827 RB_OBJ_WRITE(method, &data->klass, orig->klass);
1828 RB_OBJ_WRITE(method, &data->iclass, orig->iclass);
1829 RB_OBJ_WRITE(method, &data->me, rb_method_entry_clone(orig->me));
1830
1831 return method;
1832}
1833
1834/*
1835 * call-seq:
1836 * meth.receiver -> object
1837 *
1838 * Returns the bound receiver of the method object.
1839 *
1840 * (1..3).method(:map).receiver # => 1..3
1841 */
1842
1843static VALUE
1844method_receiver(VALUE obj)
1845{
1846 struct METHOD *data;
1847
1848 TypedData_Get_Struct(obj, struct METHOD, &method_data_type, data);
1849 return data->recv;
1850}
1851
1852/*
1853 * call-seq:
1854 * meth.name -> symbol
1855 *
1856 * Returns the name of the method.
1857 */
1858
1859static VALUE
1860method_name(VALUE obj)
1861{
1862 struct METHOD *data;
1863
1864 TypedData_Get_Struct(obj, struct METHOD, &method_data_type, data);
1865 return ID2SYM(data->me->called_id);
1866}
1867
1868/*
1869 * call-seq:
1870 * meth.original_name -> symbol
1871 *
1872 * Returns the original name of the method.
1873 *
1874 * class C
1875 * def foo; end
1876 * alias bar foo
1877 * end
1878 * C.instance_method(:bar).original_name # => :foo
1879 */
1880
1881static VALUE
1882method_original_name(VALUE obj)
1883{
1884 struct METHOD *data;
1885
1886 TypedData_Get_Struct(obj, struct METHOD, &method_data_type, data);
1887 return ID2SYM(data->me->def->original_id);
1888}
1889
1890/*
1891 * call-seq:
1892 * meth.owner -> class_or_module
1893 *
1894 * Returns the class or module that defines the method.
1895 * See also Method#receiver.
1896 *
1897 * (1..3).method(:map).owner #=> Enumerable
1898 */
1899
1900static VALUE
1901method_owner(VALUE obj)
1902{
1903 struct METHOD *data;
1904 TypedData_Get_Struct(obj, struct METHOD, &method_data_type, data);
1905 return data->me->owner;
1906}
1907
1908void
1909 rb_method_name_error(VALUE klass, VALUE str)
1910{
1911#define MSG(s) rb_fstring_lit("undefined method `%1$s' for"s" `%2$s'")
1912 VALUE c = klass;
1913 VALUE s = Qundef;
1914
1915 if (FL_TEST(c, FL_SINGLETON)) {
1916 VALUE obj = rb_ivar_get(klass, attached);
1917
1918 switch (BUILTIN_TYPE(obj)) {
1919 case T_MODULE:
1920 case T_CLASS:
1921 c = obj;
1922 break;
1923 default:
1924 break;
1925 }
1926 }
1927 else if (RB_TYPE_P(c, T_MODULE)) {
1928 s = MSG(" module");
1929 }
1930 if (s == Qundef) {
1931 s = MSG(" class");
1932 }
1933 rb_name_err_raise_str(s, c, str);
1934#undef MSG
1935}
1936
1937static VALUE
1938obj_method(VALUE obj, VALUE vid, int scope)
1939{
1940 ID id = rb_check_id(&vid);
1941 const VALUE klass = CLASS_OF(obj);
1942 const VALUE mclass = rb_cMethod;
1943
1944 if (!id) {
1945 VALUE m = mnew_missing_by_name(klass, obj, &vid, scope, mclass);
1946 if (m) return m;
1947 rb_method_name_error(klass, vid);
1948 }
1949 return mnew(klass, obj, id, mclass, scope);
1950}
1951
1952/*
1953 * call-seq:
1954 * obj.method(sym) -> method
1955 *
1956 * Looks up the named method as a receiver in <i>obj</i>, returning a
1957 * Method object (or raising NameError). The Method object acts as a
1958 * closure in <i>obj</i>'s object instance, so instance variables and
1959 * the value of <code>self</code> remain available.
1960 *
1961 * class Demo
1962 * def initialize(n)
1963 * @iv = n
1964 * end
1965 * def hello()
1966 * "Hello, @iv = #{@iv}"
1967 * end
1968 * end
1969 *
1970 * k = Demo.new(99)
1971 * m = k.method(:hello)
1972 * m.call #=> "Hello, @iv = 99"
1973 *
1974 * l = Demo.new('Fred')
1975 * m = l.method("hello")
1976 * m.call #=> "Hello, @iv = Fred"
1977 *
1978 * Note that Method implements <code>to_proc</code> method, which
1979 * means it can be used with iterators.
1980 *
1981 * [ 1, 2, 3 ].each(&method(:puts)) # => prints 3 lines to stdout
1982 *
1983 * out = File.open('test.txt', 'w')
1984 * [ 1, 2, 3 ].each(&out.method(:puts)) # => prints 3 lines to file
1985 *
1986 * require 'date'
1987 * %w[2017-03-01 2017-03-02].collect(&Date.method(:parse))
1988 * #=> [#<Date: 2017-03-01 ((2457814j,0s,0n),+0s,2299161j)>, #<Date: 2017-03-02 ((2457815j,0s,0n),+0s,2299161j)>]
1989 */
1990
1991 VALUE
1992 rb_obj_method(VALUE obj, VALUE vid)
1993{
1994 return obj_method(obj, vid, FALSE);
1995}
1996
1997/*
1998 * call-seq:
1999 * obj.public_method(sym) -> method
2000 *
2001 * Similar to _method_, searches public method only.
2002 */
2003
2004 VALUE
2005rb_obj_public_method(VALUE obj, VALUE vid)
2006{
2007 return obj_method(obj, vid, TRUE);
2008}
2009
2010/*
2011 * call-seq:
2012 * obj.singleton_method(sym) -> method
2013 *
2014 * Similar to _method_, searches singleton method only.
2015 *
2016 * class Demo
2017 * def initialize(n)
2018 * @iv = n
2019 * end
2020 * def hello()
2021 * "Hello, @iv = #{@iv}"
2022 * end
2023 * end
2024 *
2025 * k = Demo.new(99)
2026 * def k.hi
2027 * "Hi, @iv = #{@iv}"
2028 * end
2029 * m = k.singleton_method(:hi)
2030 * m.call #=> "Hi, @iv = 99"
2031 * m = k.singleton_method(:hello) #=> NameError
2032 */
2033
2034 VALUE
2035rb_obj_singleton_method(VALUE obj, VALUE vid)
2036{
2037 VALUE klass = rb_singleton_class_get(obj);
2038 ID id = rb_check_id(&vid);
2039
2040 if (NIL_P(klass)) {
2041 /* goto undef; */
2042 }
2043 else if (NIL_P(klass = RCLASS_ORIGIN(klass))) {
2044 /* goto undef; */
2045 }
2046 else if (! id) {
2047 VALUE m = mnew_missing_by_name(klass, obj, &vid, FALSE, rb_cMethod);
2048 if (m) return m;
2049 /* else goto undef; */
2050 }
2051 else {
2052 const rb_method_entry_t *me = rb_method_entry_at(klass, id);
2053 vid = ID2SYM(id);
2054
2055 if (UNDEFINED_METHOD_ENTRY_P(me)) {
2056 /* goto undef; */
2057 }
2058 else if (UNDEFINED_REFINED_METHOD_P(me->def)) {
2059 /* goto undef; */
2060 }
2061 else {
2062 return mnew_from_me(me, klass, klass, obj, id, rb_cMethod, FALSE);
2063 }
2064 }
2065
2066 /* undef: */
2067 rb_name_err_raise("undefined singleton method `%1$s' for `%2$s'",
2068 obj, vid);
2069 UNREACHABLE_RETURN(Qundef);
2070}
2071
2072/*
2073 * call-seq:
2074 * mod.instance_method(symbol) -> unbound_method
2075 *
2076 * Returns an +UnboundMethod+ representing the given
2077 * instance method in _mod_.
2078 *
2079 * class Interpreter
2080 * def do_a() print "there, "; end
2081 * def do_d() print "Hello "; end
2082 * def do_e() print "!\n"; end
2083 * def do_v() print "Dave"; end
2084 * Dispatcher = {
2085 * "a" => instance_method(:do_a),
2086 * "d" => instance_method(:do_d),
2087 * "e" => instance_method(:do_e),
2088 * "v" => instance_method(:do_v)
2089 * }
2090 * def interpret(string)
2091 * string.each_char {|b| Dispatcher[b].bind(self).call }
2092 * end
2093 * end
2094 *
2095 * interpreter = Interpreter.new
2096 * interpreter.interpret('dave')
2097 *
2098 * <em>produces:</em>
2099 *
2100 * Hello there, Dave!
2101 */
2102
2103static VALUE
2104rb_mod_instance_method(VALUE mod, VALUE vid)
2105{
2106 ID id = rb_check_id(&vid);
2107 if (!id) {
2108 rb_method_name_error(mod, vid);
2109 }
2110 return mnew(mod, Qundef, id, rb_cUnboundMethod, FALSE);
2111}
2112
2113/*
2114 * call-seq:
2115 * mod.public_instance_method(symbol) -> unbound_method
2116 *
2117 * Similar to _instance_method_, searches public method only.
2118 */
2119
2120static VALUE
2121rb_mod_public_instance_method(VALUE mod, VALUE vid)
2122{
2123 ID id = rb_check_id(&vid);
2124 if (!id) {
2125 rb_method_name_error(mod, vid);
2126 }
2127 return mnew(mod, Qundef, id, rb_cUnboundMethod, TRUE);
2128}
2129
2130/*
2131 * call-seq:
2132 * define_method(symbol, method) -> symbol
2133 * define_method(symbol) { block } -> symbol
2134 *
2135 * Defines an instance method in the receiver. The _method_
2136 * parameter can be a +Proc+, a +Method+ or an +UnboundMethod+ object.
2137 * If a block is specified, it is used as the method body.
2138 * If a block or the _method_ parameter has parameters,
2139 * they're used as method parameters.
2140 * This block is evaluated using #instance_eval.
2141 *
2142 * class A
2143 * def fred
2144 * puts "In Fred"
2145 * end
2146 * def create_method(name, &block)
2147 * self.class.define_method(name, &block)
2148 * end
2149 * define_method(:wilma) { puts "Charge it!" }
2150 * define_method(:flint) {|name| puts "I'm #{name}!"}
2151 * end
2152 * class B < A
2153 * define_method(:barney, instance_method(:fred))
2154 * end
2155 * a = B.new
2156 * a.barney
2157 * a.wilma
2158 * a.flint('Dino')
2159 * a.create_method(:betty) { p self }
2160 * a.betty
2161 *
2162 * <em>produces:</em>
2163 *
2164 * In Fred
2165 * Charge it!
2166 * I'm Dino!
2167 * #<B:0x401b39e8>
2168 */
2169
2170static VALUE
2171rb_mod_define_method(int argc, VALUE *argv, VALUE mod)
2172{
2173 ID id;
2174 VALUE body;
2175 VALUE name;
2176 const rb_cref_t *cref = rb_vm_cref_in_context(mod, mod);
2177 const rb_scope_visibility_t default_scope_visi = {METHOD_VISI_PUBLIC, FALSE};
2178 const rb_scope_visibility_t *scope_visi = &default_scope_visi;
2179 int is_method = FALSE;
2180
2181 if (cref) {
2182 scope_visi = CREF_SCOPE_VISI(cref);
2183 }
2184
2185 rb_check_arity(argc, 1, 2);
2186 name = argv[0];
2187 id = rb_check_id(&name);
2188 if (argc == 1) {
2189 body = rb_block_lambda();
2190 }
2191 else {
2192 body = argv[1];
2193
2194 if (rb_obj_is_method(body)) {
2195 is_method = TRUE;
2196 }
2197 else if (rb_obj_is_proc(body)) {
2198 is_method = FALSE;
2199 }
2200 else {
2201 rb_raise(rb_eTypeError,
2202 "wrong argument type %s (expected Proc/Method/UnboundMethod)",
2203 rb_obj_classname(body));
2204 }
2205 }
2206 if (!id) id = rb_to_id(name);
2207
2208 if (is_method) {
2209 struct METHOD *method = (struct METHOD *)DATA_PTR(body);
2210 if (method->me->owner != mod && !RB_TYPE_P(method->me->owner, T_MODULE) &&
2211 !RTEST(rb_class_inherited_p(mod, method->me->owner))) {
2212 if (FL_TEST(method->me->owner, FL_SINGLETON)) {
2213 rb_raise(rb_eTypeError,
2214 "can't bind singleton method to a different class");
2215 }
2216 else {
2217 rb_raise(rb_eTypeError,
2218 "bind argument must be a subclass of % "PRIsVALUE,
2219 method->me->owner);
2220 }
2221 }
2222 rb_method_entry_set(mod, id, method->me, scope_visi->method_visi);
2223 if (scope_visi->module_func) {
2224 rb_method_entry_set(rb_singleton_class(mod), id, method->me, METHOD_VISI_PUBLIC);
2225 }
2226 RB_GC_GUARD(body);
2227 }
2228 else {
2229 VALUE procval = rb_proc_dup(body);
2230 if (vm_proc_iseq(procval) != NULL) {
2231 rb_proc_t *proc;
2232 GetProcPtr(procval, proc);
2233 proc->is_lambda = TRUE;
2234 proc->is_from_method = TRUE;
2235 }
2236 rb_add_method(mod, id, VM_METHOD_TYPE_BMETHOD, (void *)procval, scope_visi->method_visi);
2237 if (scope_visi->module_func) {
2238 rb_add_method(rb_singleton_class(mod), id, VM_METHOD_TYPE_BMETHOD, (void *)body, METHOD_VISI_PUBLIC);
2239 }
2240 }
2241
2242 return ID2SYM(id);
2243}
2244
2245/*
2246 * call-seq:
2247 * define_singleton_method(symbol, method) -> symbol
2248 * define_singleton_method(symbol) { block } -> symbol
2249 *
2250 * Defines a singleton method in the receiver. The _method_
2251 * parameter can be a +Proc+, a +Method+ or an +UnboundMethod+ object.
2252 * If a block is specified, it is used as the method body.
2253 * If a block or a method has parameters, they're used as method parameters.
2254 *
2255 * class A
2256 * class << self
2257 * def class_name
2258 * to_s
2259 * end
2260 * end
2261 * end
2262 * A.define_singleton_method(:who_am_i) do
2263 * "I am: #{class_name}"
2264 * end
2265 * A.who_am_i # ==> "I am: A"
2266 *
2267 * guy = "Bob"
2268 * guy.define_singleton_method(:hello) { "#{self}: Hello there!" }
2269 * guy.hello #=> "Bob: Hello there!"
2270 *
2271 * chris = "Chris"
2272 * chris.define_singleton_method(:greet) {|greeting| "#{greeting}, I'm Chris!" }
2273 * chris.greet("Hi") #=> "Hi, I'm Chris!"
2274 */
2275
2276static VALUE
2277rb_obj_define_method(int argc, VALUE *argv, VALUE obj)
2278{
2279 VALUE klass = rb_singleton_class(obj);
2280
2281 return rb_mod_define_method(argc, argv, klass);
2282}
2283
2284/*
2285 * define_method(symbol, method) -> symbol
2286 * define_method(symbol) { block } -> symbol
2287 *
2288 * Defines a global function by _method_ or the block.
2289 */
2290
2291static VALUE
2292top_define_method(int argc, VALUE *argv, VALUE obj)
2293{
2294 rb_thread_t *th = GET_THREAD();
2295 VALUE klass;
2296
2297 klass = th->top_wrapper;
2298 if (klass) {
2299 rb_warning("main.define_method in the wrapped load is effective only in wrapper module");
2300 }
2301 else {
2302 klass = rb_cObject;
2303 }
2304 return rb_mod_define_method(argc, argv, klass);
2305}
2306
2307/*
2308 * call-seq:
2309 * method.clone -> new_method
2310 *
2311 * Returns a clone of this method.
2312 *
2313 * class A
2314 * def foo
2315 * return "bar"
2316 * end
2317 * end
2318 *
2319 * m = A.new.method(:foo)
2320 * m.call # => "bar"
2321 * n = m.clone.call # => "bar"
2322 */
2323
2324static VALUE
2325method_clone(VALUE self)
2326{
2327 VALUE clone;
2328 struct METHOD *orig, *data;
2329
2330 TypedData_Get_Struct(self, struct METHOD, &method_data_type, orig);
2331 clone = TypedData_Make_Struct(CLASS_OF(self), struct METHOD, &method_data_type, data);
2332 CLONESETUP(clone, self);
2333 RB_OBJ_WRITE(clone, &data->recv, orig->recv);
2334 RB_OBJ_WRITE(clone, &data->klass, orig->klass);
2335 RB_OBJ_WRITE(clone, &data->iclass, orig->iclass);
2336 RB_OBJ_WRITE(clone, &data->me, rb_method_entry_clone(orig->me));
2337 return clone;
2338}
2339
2340/* Document-method: Method#===
2341 *
2342 * call-seq:
2343 * method === obj -> result_of_method
2344 *
2345 * Invokes the method with +obj+ as the parameter like #call.
2346 * This allows a method object to be the target of a +when+ clause
2347 * in a case statement.
2348 *
2349 * require 'prime'
2350 *
2351 * case 1373
2352 * when Prime.method(:prime?)
2353 * # ...
2354 * end
2355 */
2356
2357
2358/* Document-method: Method#[]
2359 *
2360 * call-seq:
2361 * meth[args, ...] -> obj
2362 *
2363 * Invokes the <i>meth</i> with the specified arguments, returning the
2364 * method's return value, like #call.
2365 *
2366 * m = 12.method("+")
2367 * m[3] #=> 15
2368 * m[20] #=> 32
2369 */
2370
2371/*
2372 * call-seq:
2373 * meth.call(args, ...) -> obj
2374 *
2375 * Invokes the <i>meth</i> with the specified arguments, returning the
2376 * method's return value.
2377 *
2378 * m = 12.method("+")
2379 * m.call(3) #=> 15
2380 * m.call(20) #=> 32
2381 */
2382
2383static VALUE
2384rb_method_call_pass_called_kw(int argc, const VALUE *argv, VALUE method)
2385{
2386 VALUE procval = rb_block_given_p() ? rb_block_proc() : Qnil;
2387 return rb_method_call_with_block_kw(argc, argv, method, procval, RB_PASS_CALLED_KEYWORDS);
2388}
2389
2390 VALUE
2391 rb_method_call_kw(int argc, const VALUE *argv, VALUE method, int kw_splat)
2392{
2393 VALUE procval = rb_block_given_p() ? rb_block_proc() : Qnil;
2394 return rb_method_call_with_block_kw(argc, argv, method, procval, kw_splat);
2395}
2396
2397 VALUE
2398 rb_method_call(int argc, const VALUE *argv, VALUE method)
2399{
2400 VALUE procval = rb_block_given_p() ? rb_block_proc() : Qnil;
2401 return rb_method_call_with_block(argc, argv, method, procval);
2402}
2403
2404static const rb_callable_method_entry_t *
2405method_callable_method_entry(const struct METHOD *data)
2406{
2407 if (data->me->defined_class == 0) rb_bug("method_callable_method_entry: not callable.");
2408 return (const rb_callable_method_entry_t *)data->me;
2409}
2410
2411static inline VALUE
2412call_method_data(rb_execution_context_t *ec, const struct METHOD *data,
2413 int argc, const VALUE *argv, VALUE passed_procval, int kw_splat)
2414{
2415 vm_passed_block_handler_set(ec, proc_to_block_handler(passed_procval));
2416 return rb_vm_call_kw(ec, data->recv, data->me->called_id, argc, argv,
2417 method_callable_method_entry(data), kw_splat);
2418}
2419
2420 VALUE
2421 rb_method_call_with_block_kw(int argc, const VALUE *argv, VALUE method, VALUE passed_procval, int kw_splat)
2422{
2423 const struct METHOD *data;
2424 rb_execution_context_t *ec = GET_EC();
2425
2426 TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
2427 if (data->recv == Qundef) {
2428 rb_raise(rb_eTypeError, "can't call unbound method; bind first");
2429 }
2430 return call_method_data(ec, data, argc, argv, passed_procval, kw_splat);
2431}
2432
2433 VALUE
2434 rb_method_call_with_block(int argc, const VALUE *argv, VALUE method, VALUE passed_procval)
2435{
2436 return rb_method_call_with_block_kw(argc, argv, method, passed_procval, RB_NO_KEYWORDS);
2437}
2438
2439/**********************************************************************
2440 *
2441 * Document-class: UnboundMethod
2442 *
2443 * Ruby supports two forms of objectified methods. Class Method is
2444 * used to represent methods that are associated with a particular
2445 * object: these method objects are bound to that object. Bound
2446 * method objects for an object can be created using Object#method.
2447 *
2448 * Ruby also supports unbound methods; methods objects that are not
2449 * associated with a particular object. These can be created either
2450 * by calling Module#instance_method or by calling #unbind on a bound
2451 * method object. The result of both of these is an UnboundMethod
2452 * object.
2453 *
2454 * Unbound methods can only be called after they are bound to an
2455 * object. That object must be a kind_of? the method's original
2456 * class.
2457 *
2458 * class Square
2459 * def area
2460 * @side * @side
2461 * end
2462 * def initialize(side)
2463 * @side = side
2464 * end
2465 * end
2466 *
2467 * area_un = Square.instance_method(:area)
2468 *
2469 * s = Square.new(12)
2470 * area = area_un.bind(s)
2471 * area.call #=> 144
2472 *
2473 * Unbound methods are a reference to the method at the time it was
2474 * objectified: subsequent changes to the underlying class will not
2475 * affect the unbound method.
2476 *
2477 * class Test
2478 * def test
2479 * :original
2480 * end
2481 * end
2482 * um = Test.instance_method(:test)
2483 * class Test
2484 * def test
2485 * :modified
2486 * end
2487 * end
2488 * t = Test.new
2489 * t.test #=> :modified
2490 * um.bind(t).call #=> :original
2491 *
2492 */
2493
2494static void
2495convert_umethod_to_method_components(VALUE method, VALUE recv, VALUE *methclass_out, VALUE *klass_out, VALUE *iclass_out, const rb_method_entry_t **me_out)
2496{
2497 struct METHOD *data;
2498
2499 TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
2500
2501 VALUE methclass = data->me->owner;
2502 VALUE iclass = data->me->defined_class;
2503 VALUE klass = CLASS_OF(recv);
2504
2505 if (RB_TYPE_P(methclass, T_MODULE)) {
2506 VALUE refined_class = rb_refinement_module_get_refined_class(methclass);
2507 if (!NIL_P(refined_class)) methclass = refined_class;
2508 }
2509 if (!RB_TYPE_P(methclass, T_MODULE) &&
2510 methclass != CLASS_OF(recv) && !rb_obj_is_kind_of(recv, methclass)) {
2511 if (FL_TEST(methclass, FL_SINGLETON)) {
2512 rb_raise(rb_eTypeError,
2513 "singleton method called for a different object");
2514 }
2515 else {
2516 rb_raise(rb_eTypeError, "bind argument must be an instance of % "PRIsVALUE,
2517 methclass);
2518 }
2519 }
2520
2521 const rb_method_entry_t *me = rb_method_entry_clone(data->me);
2522
2523 if (RB_TYPE_P(me->owner, T_MODULE)) {
2524 VALUE ic = rb_class_search_ancestor(klass, me->owner);
2525 if (ic) {
2526 klass = ic;
2527 iclass = ic;
2528 }
2529 else {
2530 klass = rb_include_class_new(methclass, klass);
2531 }
2532 me = (const rb_method_entry_t *) rb_method_entry_complement_defined_class(me, me->called_id, klass);
2533 }
2534
2535 *methclass_out = methclass;
2536 *klass_out = klass;
2537 *iclass_out = iclass;
2538 *me_out = me;
2539}
2540
2541/*
2542 * call-seq:
2543 * umeth.bind(obj) -> method
2544 *
2545 * Bind <i>umeth</i> to <i>obj</i>. If Klass was the class from which
2546 * <i>umeth</i> was obtained, <code>obj.kind_of?(Klass)</code> must
2547 * be true.
2548 *
2549 * class A
2550 * def test
2551 * puts "In test, class = #{self.class}"
2552 * end
2553 * end
2554 * class B < A
2555 * end
2556 * class C < B
2557 * end
2558 *
2559 *
2560 * um = B.instance_method(:test)
2561 * bm = um.bind(C.new)
2562 * bm.call
2563 * bm = um.bind(B.new)
2564 * bm.call
2565 * bm = um.bind(A.new)
2566 * bm.call
2567 *
2568 * <em>produces:</em>
2569 *
2570 * In test, class = C
2571 * In test, class = B
2572 * prog.rb:16:in `bind': bind argument must be an instance of B (TypeError)
2573 * from prog.rb:16
2574 */
2575
2576static VALUE
2577umethod_bind(VALUE method, VALUE recv)
2578{
2579 VALUE methclass, klass, iclass;
2580 const rb_method_entry_t *me;
2581 convert_umethod_to_method_components(method, recv, &methclass, &klass, &iclass, &me);
2582
2583 struct METHOD *bound;
2584 method = TypedData_Make_Struct(rb_cMethod, struct METHOD, &method_data_type, bound);
2585 RB_OBJ_WRITE(method, &bound->recv, recv);
2586 RB_OBJ_WRITE(method, &bound->klass, klass);
2587 RB_OBJ_WRITE(method, &bound->iclass, iclass);
2588 RB_OBJ_WRITE(method, &bound->me, me);
2589
2590 return method;
2591}
2592
2593/*
2594 * call-seq:
2595 * umeth.bind_call(recv, args, ...) -> obj
2596 *
2597 * Bind <i>umeth</i> to <i>recv</i> and then invokes the method with the
2598 * specified arguments.
2599 * This is semantically equivalent to <code>umeth.bind(recv).call(args, ...)</code>.
2600 */
2601static VALUE
2602umethod_bind_call(int argc, VALUE *argv, VALUE method)
2603{
2604 rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
2605 VALUE recv = argv[0];
2606 argc--;
2607 argv++;
2608
2609 VALUE methclass, klass, iclass;
2610 const rb_method_entry_t *me;
2611 convert_umethod_to_method_components(method, recv, &methclass, &klass, &iclass, &me);
2612 struct METHOD bound = { recv, klass, 0, me };
2613
2614 VALUE passed_procval = rb_block_given_p() ? rb_block_proc() : Qnil;
2615
2616 rb_execution_context_t *ec = GET_EC();
2617 return call_method_data(ec, &bound, argc, argv, passed_procval, RB_PASS_CALLED_KEYWORDS);
2618}
2619
2620/*
2621 * Returns the number of required parameters and stores the maximum
2622 * number of parameters in max, or UNLIMITED_ARGUMENTS
2623 * if there is no maximum.
2624 */
2625static int
2626rb_method_entry_min_max_arity(const rb_method_entry_t *me, int *max)
2627{
2628 const rb_method_definition_t *def = me->def;
2629
2630 again:
2631 if (!def) return *max = 0;
2632 switch (def->type) {
2633 case VM_METHOD_TYPE_CFUNC:
2634 if (def->body.cfunc.argc < 0) {
2635 *max = UNLIMITED_ARGUMENTS;
2636 return 0;
2637 }
2638 return *max = check_argc(def->body.cfunc.argc);
2639 case VM_METHOD_TYPE_ZSUPER:
2640 *max = UNLIMITED_ARGUMENTS;
2641 return 0;
2642 case VM_METHOD_TYPE_ATTRSET:
2643 return *max = 1;
2644 case VM_METHOD_TYPE_IVAR:
2645 return *max = 0;
2646 case VM_METHOD_TYPE_ALIAS:
2647 def = def->body.alias.original_me->def;
2648 goto again;
2649 case VM_METHOD_TYPE_BMETHOD:
2650 return rb_proc_min_max_arity(def->body.bmethod.proc, max);
2651 case VM_METHOD_TYPE_ISEQ:
2652 return rb_iseq_min_max_arity(rb_iseq_check(def->body.iseq.iseqptr), max);
2653 case VM_METHOD_TYPE_UNDEF:
2654 case VM_METHOD_TYPE_NOTIMPLEMENTED:
2655 return *max = 0;
2656 case VM_METHOD_TYPE_MISSING:
2657 *max = UNLIMITED_ARGUMENTS;
2658 return 0;
2659 case VM_METHOD_TYPE_OPTIMIZED: {
2660 switch (def->body.optimize_type) {
2661 case OPTIMIZED_METHOD_TYPE_SEND:
2662 *max = UNLIMITED_ARGUMENTS;
2663 return 0;
2664 case OPTIMIZED_METHOD_TYPE_CALL:
2665 *max = UNLIMITED_ARGUMENTS;
2666 return 0;
2667 case OPTIMIZED_METHOD_TYPE_BLOCK_CALL:
2668 *max = UNLIMITED_ARGUMENTS;
2669 return 0;
2670 default:
2671 break;
2672 }
2673 break;
2674 }
2675 case VM_METHOD_TYPE_REFINED:
2676 *max = UNLIMITED_ARGUMENTS;
2677 return 0;
2678 }
2679 rb_bug("rb_method_entry_min_max_arity: invalid method entry type (%d)", def->type);
2680 UNREACHABLE_RETURN(Qnil);
2681}
2682
2683int
2684 rb_method_entry_arity(const rb_method_entry_t *me)
2685{
2686 int max, min = rb_method_entry_min_max_arity(me, &max);
2687 return min == max ? min : -min-1;
2688}
2689
2690/*
2691 * call-seq:
2692 * meth.arity -> integer
2693 *
2694 * Returns an indication of the number of arguments accepted by a
2695 * method. Returns a nonnegative integer for methods that take a fixed
2696 * number of arguments. For Ruby methods that take a variable number of
2697 * arguments, returns -n-1, where n is the number of required arguments.
2698 * Keyword arguments will be considered as a single additional argument,
2699 * that argument being mandatory if any keyword argument is mandatory.
2700 * For methods written in C, returns -1 if the call takes a
2701 * variable number of arguments.
2702 *
2703 * class C
2704 * def one; end
2705 * def two(a); end
2706 * def three(*a); end
2707 * def four(a, b); end
2708 * def five(a, b, *c); end
2709 * def six(a, b, *c, &d); end
2710 * def seven(a, b, x:0); end
2711 * def eight(x:, y:); end
2712 * def nine(x:, y:, **z); end
2713 * def ten(*a, x:, y:); end
2714 * end
2715 * c = C.new
2716 * c.method(:one).arity #=> 0
2717 * c.method(:two).arity #=> 1
2718 * c.method(:three).arity #=> -1
2719 * c.method(:four).arity #=> 2
2720 * c.method(:five).arity #=> -3
2721 * c.method(:six).arity #=> -3
2722 * c.method(:seven).arity #=> -3
2723 * c.method(:eight).arity #=> 1
2724 * c.method(:nine).arity #=> 1
2725 * c.method(:ten).arity #=> -2
2726 *
2727 * "cat".method(:size).arity #=> 0
2728 * "cat".method(:replace).arity #=> 1
2729 * "cat".method(:squeeze).arity #=> -1
2730 * "cat".method(:count).arity #=> -1
2731 */
2732
2733static VALUE
2734method_arity_m(VALUE method)
2735{
2736 int n = method_arity(method);
2737 return INT2FIX(n);
2738}
2739
2740static int
2741method_arity(VALUE method)
2742{
2743 struct METHOD *data;
2744
2745 TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
2746 return rb_method_entry_arity(data->me);
2747}
2748
2749static const rb_method_entry_t *
2750original_method_entry(VALUE mod, ID id)
2751{
2752 const rb_method_entry_t *me;
2753
2754 while ((me = rb_method_entry(mod, id)) != 0) {
2755 const rb_method_definition_t *def = me->def;
2756 if (def->type != VM_METHOD_TYPE_ZSUPER) break;
2757 mod = RCLASS_SUPER(me->owner);
2758 id = def->original_id;
2759 }
2760 return me;
2761}
2762
2763static int
2764method_min_max_arity(VALUE method, int *max)
2765{
2766 const struct METHOD *data;
2767
2768 TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
2769 return rb_method_entry_min_max_arity(data->me, max);
2770}
2771
2772int
2773 rb_mod_method_arity(VALUE mod, ID id)
2774{
2775 const rb_method_entry_t *me = original_method_entry(mod, id);
2776 if (!me) return 0; /* should raise? */
2777 return rb_method_entry_arity(me);
2778}
2779
2780int
2781 rb_obj_method_arity(VALUE obj, ID id)
2782{
2783 return rb_mod_method_arity(CLASS_OF(obj), id);
2784}
2785
2786 VALUE
2787 rb_callable_receiver(VALUE callable)
2788{
2789 if (rb_obj_is_proc(callable)) {
2790 VALUE binding = proc_binding(callable);
2791 return rb_funcall(binding, rb_intern("receiver"), 0);
2792 }
2793 else if (rb_obj_is_method(callable)) {
2794 return method_receiver(callable);
2795 }
2796 else {
2797 return Qundef;
2798 }
2799}
2800
2801const rb_method_definition_t *
2802rb_method_def(VALUE method)
2803{
2804 const struct METHOD *data;
2805
2806 TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
2807 return data->me->def;
2808}
2809
2810static const rb_iseq_t *
2811method_def_iseq(const rb_method_definition_t *def)
2812{
2813 switch (def->type) {
2814 case VM_METHOD_TYPE_ISEQ:
2815 return rb_iseq_check(def->body.iseq.iseqptr);
2816 case VM_METHOD_TYPE_BMETHOD:
2817 return rb_proc_get_iseq(def->body.bmethod.proc, 0);
2818 case VM_METHOD_TYPE_ALIAS:
2819 return method_def_iseq(def->body.alias.original_me->def);
2820 case VM_METHOD_TYPE_CFUNC:
2821 case VM_METHOD_TYPE_ATTRSET:
2822 case VM_METHOD_TYPE_IVAR:
2823 case VM_METHOD_TYPE_ZSUPER:
2824 case VM_METHOD_TYPE_UNDEF:
2825 case VM_METHOD_TYPE_NOTIMPLEMENTED:
2826 case VM_METHOD_TYPE_OPTIMIZED:
2827 case VM_METHOD_TYPE_MISSING:
2828 case VM_METHOD_TYPE_REFINED:
2829 break;
2830 }
2831 return NULL;
2832}
2833
2834const rb_iseq_t *
2835 rb_method_iseq(VALUE method)
2836{
2837 return method_def_iseq(rb_method_def(method));
2838}
2839
2840static const rb_cref_t *
2841method_cref(VALUE method)
2842{
2843 const rb_method_definition_t *def = rb_method_def(method);
2844
2845 again:
2846 switch (def->type) {
2847 case VM_METHOD_TYPE_ISEQ:
2848 return def->body.iseq.cref;
2849 case VM_METHOD_TYPE_ALIAS:
2850 def = def->body.alias.original_me->def;
2851 goto again;
2852 default:
2853 return NULL;
2854 }
2855}
2856
2857static VALUE
2858method_def_location(const rb_method_definition_t *def)
2859{
2860 if (def->type == VM_METHOD_TYPE_ATTRSET || def->type == VM_METHOD_TYPE_IVAR) {
2861 if (!def->body.attr.location)
2862 return Qnil;
2863 return rb_ary_dup(def->body.attr.location);
2864 }
2865 return iseq_location(method_def_iseq(def));
2866}
2867
2868 VALUE
2869 rb_method_entry_location(const rb_method_entry_t *me)
2870{
2871 if (!me) return Qnil;
2872 return method_def_location(me->def);
2873}
2874
2875/*
2876 * call-seq:
2877 * meth.source_location -> [String, Integer]
2878 *
2879 * Returns the Ruby source filename and line number containing this method
2880 * or nil if this method was not defined in Ruby (i.e. native).
2881 */
2882
2883 VALUE
2884rb_method_location(VALUE method)
2885{
2886 return method_def_location(rb_method_def(method));
2887}
2888
2889/*
2890 * call-seq:
2891 * meth.parameters -> array
2892 *
2893 * Returns the parameter information of this method.
2894 *
2895 * def foo(bar); end
2896 * method(:foo).parameters #=> [[:req, :bar]]
2897 *
2898 * def foo(bar, baz, bat, &blk); end
2899 * method(:foo).parameters #=> [[:req, :bar], [:req, :baz], [:req, :bat], [:block, :blk]]
2900 *
2901 * def foo(bar, *args); end
2902 * method(:foo).parameters #=> [[:req, :bar], [:rest, :args]]
2903 *
2904 * def foo(bar, baz, *args, &blk); end
2905 * method(:foo).parameters #=> [[:req, :bar], [:req, :baz], [:rest, :args], [:block, :blk]]
2906 */
2907
2908static VALUE
2909rb_method_parameters(VALUE method)
2910{
2911 const rb_iseq_t *iseq = rb_method_iseq(method);
2912 if (!iseq) {
2913 return rb_unnamed_parameters(method_arity(method));
2914 }
2915 return rb_iseq_parameters(iseq, 0);
2916}
2917
2918/*
2919 * call-seq:
2920 * meth.to_s -> string
2921 * meth.inspect -> string
2922 *
2923 * Returns a human-readable description of the underlying method.
2924 *
2925 * "cat".method(:count).inspect #=> "#<Method: String#count(*)>"
2926 * (1..3).method(:map).inspect #=> "#<Method: Range(Enumerable)#map()>"
2927 *
2928 * In the latter case, the method description includes the "owner" of the
2929 * original method (+Enumerable+ module, which is included into +Range+).
2930 *
2931 * +inspect+ also provides, when possible, method argument names (call
2932 * sequence) and source location.
2933 *
2934 * require 'net/http'
2935 * Net::HTTP.method(:get).inspect
2936 * #=> "#<Method: Net::HTTP.get(uri_or_host, path=..., port=...) <skip>/lib/ruby/2.7.0/net/http.rb:457>"
2937 *
2938 * <code>...</code> in argument definition means argument is optional (has
2939 * some default value).
2940 *
2941 * For methods defined in C (language core and extensions), location and
2942 * argument names can't be extracted, and only generic information is provided
2943 * in form of <code>*</code> (any number of arguments) or <code>_</code> (some
2944 * positional argument).
2945 *
2946 * "cat".method(:count).inspect #=> "#<Method: String#count(*)>"
2947 * "cat".method(:+).inspect #=> "#<Method: String#+(_)>""
2948
2949 */
2950
2951static VALUE
2952method_inspect(VALUE method)
2953{
2954 struct METHOD *data;
2955 VALUE str;
2956 const char *sharp = "#";
2957 VALUE mklass;
2958 VALUE defined_class;
2959
2960 TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
2961 str = rb_sprintf("#<% "PRIsVALUE": ", rb_obj_class(method));
2962
2963 mklass = data->iclass;
2964 if (!mklass) mklass = data->klass;
2965
2966 if (RB_TYPE_P(mklass, T_ICLASS)) {
2967 /* TODO: I'm not sure why mklass is T_ICLASS.
2968 * UnboundMethod#bind() can set it as T_ICLASS at convert_umethod_to_method_components()
2969 * but not sure it is needed.
2970 */
2971 mklass = RBASIC_CLASS(mklass);
2972 }
2973
2974 if (data->me->def->type == VM_METHOD_TYPE_ALIAS) {
2975 defined_class = data->me->def->body.alias.original_me->owner;
2976 }
2977 else {
2978 defined_class = method_entry_defined_class(data->me);
2979 }
2980
2981 if (RB_TYPE_P(defined_class, T_ICLASS)) {
2982 defined_class = RBASIC_CLASS(defined_class);
2983 }
2984
2985 if (FL_TEST(mklass, FL_SINGLETON)) {
2986 VALUE v = rb_ivar_get(mklass, attached);
2987
2988 if (data->recv == Qundef) {
2989 rb_str_buf_append(str, rb_inspect(mklass));
2990 }
2991 else if (data->recv == v) {
2992 rb_str_buf_append(str, rb_inspect(v));
2993 sharp = ".";
2994 }
2995 else {
2996 rb_str_buf_append(str, rb_inspect(data->recv));
2997 rb_str_buf_cat2(str, "(");
2998 rb_str_buf_append(str, rb_inspect(v));
2999 rb_str_buf_cat2(str, ")");
3000 sharp = ".";
3001 }
3002 }
3003 else {
3004 mklass = data->klass;
3005 if (FL_TEST(mklass, FL_SINGLETON)) {
3006 VALUE v = rb_ivar_get(mklass, attached);
3007 if (!(RB_TYPE_P(v, T_CLASS) || RB_TYPE_P(v, T_MODULE))) {
3008 do {
3009 mklass = RCLASS_SUPER(mklass);
3010 } while (RB_TYPE_P(mklass, T_ICLASS));
3011 }
3012 }
3013 rb_str_buf_append(str, rb_inspect(mklass));
3014 if (defined_class != mklass) {
3015 rb_str_catf(str, "(% "PRIsVALUE")", defined_class);
3016 }
3017 }
3018 rb_str_buf_cat2(str, sharp);
3019 rb_str_append(str, rb_id2str(data->me->called_id));
3020 if (data->me->called_id != data->me->def->original_id) {
3021 rb_str_catf(str, "(%"PRIsVALUE")",
3022 rb_id2str(data->me->def->original_id));
3023 }
3024 if (data->me->def->type == VM_METHOD_TYPE_NOTIMPLEMENTED) {
3025 rb_str_buf_cat2(str, " (not-implemented)");
3026 }
3027
3028 // parameter information
3029 {
3030 VALUE params = rb_method_parameters(method);
3031 VALUE pair, name, kind;
3032 const VALUE req = ID2SYM(rb_intern("req"));
3033 const VALUE opt = ID2SYM(rb_intern("opt"));
3034 const VALUE keyreq = ID2SYM(rb_intern("keyreq"));
3035 const VALUE key = ID2SYM(rb_intern("key"));
3036 const VALUE rest = ID2SYM(rb_intern("rest"));
3037 const VALUE keyrest = ID2SYM(rb_intern("keyrest"));
3038 const VALUE block = ID2SYM(rb_intern("block"));
3039 const VALUE nokey = ID2SYM(rb_intern("nokey"));
3040 int forwarding = 0;
3041
3042 rb_str_buf_cat2(str, "(");
3043
3044 for (int i = 0; i < RARRAY_LEN(params); i++) {
3045 pair = RARRAY_AREF(params, i);
3046 kind = RARRAY_AREF(pair, 0);
3047 name = RARRAY_AREF(pair, 1);
3048 // FIXME: in tests it turns out that kind, name = [:req] produces name to be false. Why?..
3049 if (NIL_P(name) || name == Qfalse) {
3050 // FIXME: can it be reduced to switch/case?
3051 if (kind == req || kind == opt) {
3052 name = rb_str_new2("_");
3053 }
3054 else if (kind == rest || kind == keyrest) {
3055 name = rb_str_new2("");
3056 }
3057 else if (kind == block) {
3058 name = rb_str_new2("block");
3059 }
3060 else if (kind == nokey) {
3061 name = rb_str_new2("nil");
3062 }
3063 }
3064
3065 if (kind == req) {
3066 rb_str_catf(str, "%"PRIsVALUE, name);
3067 }
3068 else if (kind == opt) {
3069 rb_str_catf(str, "%"PRIsVALUE"=...", name);
3070 }
3071 else if (kind == keyreq) {
3072 rb_str_catf(str, "%"PRIsVALUE":", name);
3073 }
3074 else if (kind == key) {
3075 rb_str_catf(str, "%"PRIsVALUE": ...", name);
3076 }
3077 else if (kind == rest) {
3078 if (name == ID2SYM('*')) {
3079 forwarding = 1;
3080 rb_str_cat_cstr(str, "...");
3081 }
3082 else {
3083 rb_str_catf(str, "*%"PRIsVALUE, name);
3084 }
3085 }
3086 else if (kind == keyrest) {
3087 rb_str_catf(str, "**%"PRIsVALUE, name);
3088 }
3089 else if (kind == block) {
3090 if (name == ID2SYM('&')) {
3091 if (forwarding) {
3092 rb_str_set_len(str, RSTRING_LEN(str) - 2);
3093 }
3094 else {
3095 rb_str_cat_cstr(str, "...");
3096 }
3097 }
3098 else {
3099 rb_str_catf(str, "&%"PRIsVALUE, name);
3100 }
3101 }
3102 else if (kind == nokey) {
3103 rb_str_buf_cat2(str, "**nil");
3104 }
3105
3106 if (i < RARRAY_LEN(params) - 1) {
3107 rb_str_buf_cat2(str, ", ");
3108 }
3109 }
3110 rb_str_buf_cat2(str, ")");
3111 }
3112
3113 { // source location
3114 VALUE loc = rb_method_location(method);
3115 if (!NIL_P(loc)) {
3116 rb_str_catf(str, " %"PRIsVALUE":%"PRIsVALUE,
3117 RARRAY_AREF(loc, 0), RARRAY_AREF(loc, 1));
3118 }
3119 }
3120
3121 rb_str_buf_cat2(str, ">");
3122
3123 return str;
3124}
3125
3126static VALUE
3127mproc(VALUE method)
3128{
3129 return rb_funcallv(rb_mRubyVMFrozenCore, idProc, 0, 0);
3130}
3131
3132static VALUE
3133mlambda(VALUE method)
3134{
3135 return rb_funcallv(rb_mRubyVMFrozenCore, idLambda, 0, 0);
3136}
3137
3138static VALUE
3139bmcall(RB_BLOCK_CALL_FUNC_ARGLIST(args, method))
3140{
3141 return rb_method_call_with_block_kw(argc, argv, method, blockarg, RB_PASS_CALLED_KEYWORDS);
3142}
3143
3144 VALUE
3145 rb_proc_new(
3146 rb_block_call_func_t func,
3147 VALUE val)
3148{
3149 VALUE procval = rb_iterate(mproc, 0, func, val);
3150 return procval;
3151}
3152
3153/*
3154 * call-seq:
3155 * meth.to_proc -> proc
3156 *
3157 * Returns a Proc object corresponding to this method.
3158 */
3159
3160static VALUE
3161method_to_proc(VALUE method)
3162{
3163 VALUE procval;
3164 rb_proc_t *proc;
3165
3166 /*
3167 * class Method
3168 * def to_proc
3169 * lambda{|*args|
3170 * self.call(*args)
3171 * }
3172 * end
3173 * end
3174 */
3175 procval = rb_iterate(mlambda, 0, bmcall, method);
3176 GetProcPtr(procval, proc);
3177 proc->is_from_method = 1;
3178 return procval;
3179}
3180
3181extern VALUE rb_find_defined_class_by_owner(VALUE current_class, VALUE target_owner);
3182
3183/*
3184 * call-seq:
3185 * meth.super_method -> method
3186 *
3187 * Returns a Method of superclass which would be called when super is used
3188 * or nil if there is no method on superclass.
3189 */
3190
3191static VALUE
3192method_super_method(VALUE method)
3193{
3194 const struct METHOD *data;
3195 VALUE super_class, iclass;
3196 ID mid;
3197 const rb_method_entry_t *me;
3198
3199 TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
3200 iclass = data->iclass;
3201 if (!iclass) return Qnil;
3202 if (data->me->def->type == VM_METHOD_TYPE_ALIAS && data->me->defined_class) {
3203 super_class = RCLASS_SUPER(rb_find_defined_class_by_owner(data->me->defined_class,
3204 data->me->def->body.alias.original_me->owner));
3205 mid = data->me->def->body.alias.original_me->def->original_id;
3206 }
3207 else {
3208 super_class = RCLASS_SUPER(RCLASS_ORIGIN(iclass));
3209 mid = data->me->def->original_id;
3210 }
3211 if (!super_class) return Qnil;
3212 me = (rb_method_entry_t *)rb_callable_method_entry_with_refinements(super_class, mid, &iclass);
3213 if (!me) return Qnil;
3214 return mnew_internal(me, me->owner, iclass, data->recv, mid, rb_obj_class(method), FALSE, FALSE);
3215}
3216
3217/*
3218 * call-seq:
3219 * local_jump_error.exit_value -> obj
3220 *
3221 * Returns the exit value associated with this +LocalJumpError+.
3222 */
3223static VALUE
3224localjump_xvalue(VALUE exc)
3225{
3226 return rb_iv_get(exc, "@exit_value");
3227}
3228
3229/*
3230 * call-seq:
3231 * local_jump_error.reason -> symbol
3232 *
3233 * The reason this block was terminated:
3234 * :break, :redo, :retry, :next, :return, or :noreason.
3235 */
3236
3237static VALUE
3238localjump_reason(VALUE exc)
3239{
3240 return rb_iv_get(exc, "@reason");
3241}
3242
3243 rb_cref_t *rb_vm_cref_new_toplevel(void); /* vm.c */
3244
3245static const rb_env_t *
3246env_clone(const rb_env_t *env, const rb_cref_t *cref)
3247{
3248 VALUE *new_ep;
3249 VALUE *new_body;
3250 const rb_env_t *new_env;
3251
3252 VM_ASSERT(env->ep > env->env);
3253 VM_ASSERT(VM_ENV_ESCAPED_P(env->ep));
3254
3255 if (cref == NULL) {
3256 cref = rb_vm_cref_new_toplevel();
3257 }
3258
3259 new_body = ALLOC_N(VALUE, env->env_size);
3260 MEMCPY(new_body, env->env, VALUE, env->env_size);
3261 new_ep = &new_body[env->ep - env->env];
3262 new_env = vm_env_new(new_ep, new_body, env->env_size, env->iseq);
3263 RB_OBJ_WRITE(new_env, &new_ep[VM_ENV_DATA_INDEX_ME_CREF], (VALUE)cref);
3264 VM_ASSERT(VM_ENV_ESCAPED_P(new_ep));
3265 return new_env;
3266}
3267
3268/*
3269 * call-seq:
3270 * prc.binding -> binding
3271 *
3272 * Returns the binding associated with <i>prc</i>.
3273 *
3274 * def fred(param)
3275 * proc {}
3276 * end
3277 *
3278 * b = fred(99)
3279 * eval("param", b.binding) #=> 99
3280 */
3281static VALUE
3282proc_binding(VALUE self)
3283{
3284 VALUE bindval, binding_self = Qundef;
3285 rb_binding_t *bind;
3286 const rb_proc_t *proc;
3287 const rb_iseq_t *iseq = NULL;
3288 const struct rb_block *block;
3289 const rb_env_t *env = NULL;
3290
3291 GetProcPtr(self, proc);
3292 block = &proc->block;
3293
3294 if (proc->is_isolated) rb_raise(rb_eArgError, "Can't create Binding from isolated Proc");
3295
3296 again:
3297 switch (vm_block_type(block)) {
3298 case block_type_iseq:
3299 iseq = block->as.captured.code.iseq;
3300 binding_self = block->as.captured.self;
3301 env = VM_ENV_ENVVAL_PTR(block->as.captured.ep);
3302 break;
3303 case block_type_proc:
3304 GetProcPtr(block->as.proc, proc);
3305 block = &proc->block;
3306 goto again;
3307 case block_type_ifunc:
3308 {
3309 const struct vm_ifunc *ifunc = block->as.captured.code.ifunc;
3310 if (IS_METHOD_PROC_IFUNC(ifunc)) {
3311 VALUE method = (VALUE)ifunc->data;
3312 VALUE name = rb_fstring_lit("<empty_iseq>");
3313 rb_iseq_t *empty;
3314 binding_self = method_receiver(method);
3315 iseq = rb_method_iseq(method);
3316 env = VM_ENV_ENVVAL_PTR(block->as.captured.ep);
3317 env = env_clone(env, method_cref(method));
3318 /* set empty iseq */
3319 empty = rb_iseq_new(NULL, name, name, Qnil, 0, ISEQ_TYPE_TOP);
3320 RB_OBJ_WRITE(env, &env->iseq, empty);
3321 break;
3322 }
3323 }
3324 /* FALLTHROUGH */
3325 case block_type_symbol:
3326 rb_raise(rb_eArgError, "Can't create Binding from C level Proc");
3327 UNREACHABLE_RETURN(Qnil);
3328 }
3329
3330 bindval = rb_binding_alloc(rb_cBinding);
3331 GetBindingPtr(bindval, bind);
3332 RB_OBJ_WRITE(bindval, &bind->block.as.captured.self, binding_self);
3333 RB_OBJ_WRITE(bindval, &bind->block.as.captured.code.iseq, env->iseq);
3334 rb_vm_block_ep_update(bindval, &bind->block, env->ep);
3335 RB_OBJ_WRITTEN(bindval, Qundef, VM_ENV_ENVVAL(env->ep));
3336
3337 if (iseq) {
3338 rb_iseq_check(iseq);
3339 RB_OBJ_WRITE(bindval, &bind->pathobj, iseq->body->location.pathobj);
3340 bind->first_lineno = FIX2INT(rb_iseq_first_lineno(iseq));
3341 }
3342 else {
3343 RB_OBJ_WRITE(bindval, &bind->pathobj,
3344 rb_iseq_pathobj_new(rb_fstring_lit("(binding)"), Qnil));
3345 bind->first_lineno = 1;
3346 }
3347
3348 return bindval;
3349}
3350
3351static rb_block_call_func curry;
3352
3353static VALUE
3354make_curry_proc(VALUE proc, VALUE passed, VALUE arity)
3355{
3356 VALUE args = rb_ary_new3(3, proc, passed, arity);
3357 rb_proc_t *procp;
3358 int is_lambda;
3359
3360 GetProcPtr(proc, procp);
3361 is_lambda = procp->is_lambda;
3362 rb_ary_freeze(passed);
3363 rb_ary_freeze(args);
3364 proc = rb_proc_new(curry, args);
3365 GetProcPtr(proc, procp);
3366 procp->is_lambda = is_lambda;
3367 return proc;
3368}
3369
3370static VALUE
3371curry(RB_BLOCK_CALL_FUNC_ARGLIST(_, args))
3372{
3373 VALUE proc, passed, arity;
3374 proc = RARRAY_AREF(args, 0);
3375 passed = RARRAY_AREF(args, 1);
3376 arity = RARRAY_AREF(args, 2);
3377
3378 passed = rb_ary_plus(passed, rb_ary_new4(argc, argv));
3379 rb_ary_freeze(passed);
3380
3381 if (RARRAY_LEN(passed) < FIX2INT(arity)) {
3382 if (!NIL_P(blockarg)) {
3383 rb_warn("given block not used");
3384 }
3385 arity = make_curry_proc(proc, passed, arity);
3386 return arity;
3387 }
3388 else {
3389 return rb_proc_call_with_block(proc, check_argc(RARRAY_LEN(passed)), RARRAY_CONST_PTR(passed), blockarg);
3390 }
3391}
3392
3393 /*
3394 * call-seq:
3395 * prc.curry -> a_proc
3396 * prc.curry(arity) -> a_proc
3397 *
3398 * Returns a curried proc. If the optional <i>arity</i> argument is given,
3399 * it determines the number of arguments.
3400 * A curried proc receives some arguments. If a sufficient number of
3401 * arguments are supplied, it passes the supplied arguments to the original
3402 * proc and returns the result. Otherwise, returns another curried proc that
3403 * takes the rest of arguments.
3404 *
3405 * b = proc {|x, y, z| (x||0) + (y||0) + (z||0) }
3406 * p b.curry[1][2][3] #=> 6
3407 * p b.curry[1, 2][3, 4] #=> 6
3408 * p b.curry(5)[1][2][3][4][5] #=> 6
3409 * p b.curry(5)[1, 2][3, 4][5] #=> 6
3410 * p b.curry(1)[1] #=> 1
3411 *
3412 * b = proc {|x, y, z, *w| (x||0) + (y||0) + (z||0) + w.inject(0, &:+) }
3413 * p b.curry[1][2][3] #=> 6
3414 * p b.curry[1, 2][3, 4] #=> 10
3415 * p b.curry(5)[1][2][3][4][5] #=> 15
3416 * p b.curry(5)[1, 2][3, 4][5] #=> 15
3417 * p b.curry(1)[1] #=> 1
3418 *
3419 * b = lambda {|x, y, z| (x||0) + (y||0) + (z||0) }
3420 * p b.curry[1][2][3] #=> 6
3421 * p b.curry[1, 2][3, 4] #=> wrong number of arguments (given 4, expected 3)
3422 * p b.curry(5) #=> wrong number of arguments (given 5, expected 3)
3423 * p b.curry(1) #=> wrong number of arguments (given 1, expected 3)
3424 *
3425 * b = lambda {|x, y, z, *w| (x||0) + (y||0) + (z||0) + w.inject(0, &:+) }
3426 * p b.curry[1][2][3] #=> 6
3427 * p b.curry[1, 2][3, 4] #=> 10
3428 * p b.curry(5)[1][2][3][4][5] #=> 15
3429 * p b.curry(5)[1, 2][3, 4][5] #=> 15
3430 * p b.curry(1) #=> wrong number of arguments (given 1, expected 3)
3431 *
3432 * b = proc { :foo }
3433 * p b.curry[] #=> :foo
3434 */
3435static VALUE
3436proc_curry(int argc, const VALUE *argv, VALUE self)
3437{
3438 int sarity, max_arity, min_arity = rb_proc_min_max_arity(self, &max_arity);
3439 VALUE arity;
3440
3441 if (rb_check_arity(argc, 0, 1) == 0 || NIL_P(arity = argv[0])) {
3442 arity = INT2FIX(min_arity);
3443 }
3444 else {
3445 sarity = FIX2INT(arity);
3446 if (rb_proc_lambda_p(self)) {
3447 rb_check_arity(sarity, min_arity, max_arity);
3448 }
3449 }
3450
3451 return make_curry_proc(self, rb_ary_new(), arity);
3452}
3453
3454/*
3455 * call-seq:
3456 * meth.curry -> proc
3457 * meth.curry(arity) -> proc
3458 *
3459 * Returns a curried proc based on the method. When the proc is called with a number of
3460 * arguments that is lower than the method's arity, then another curried proc is returned.
3461 * Only when enough arguments have been supplied to satisfy the method signature, will the
3462 * method actually be called.
3463 *
3464 * The optional <i>arity</i> argument should be supplied when currying methods with
3465 * variable arguments to determine how many arguments are needed before the method is
3466 * called.
3467 *
3468 * def foo(a,b,c)
3469 * [a, b, c]
3470 * end
3471 *
3472 * proc = self.method(:foo).curry
3473 * proc2 = proc.call(1, 2) #=> #<Proc>
3474 * proc2.call(3) #=> [1,2,3]
3475 *
3476 * def vararg(*args)
3477 * args
3478 * end
3479 *
3480 * proc = self.method(:vararg).curry(4)
3481 * proc2 = proc.call(:x) #=> #<Proc>
3482 * proc3 = proc2.call(:y, :z) #=> #<Proc>
3483 * proc3.call(:a) #=> [:x, :y, :z, :a]
3484 */
3485
3486static VALUE
3487rb_method_curry(int argc, const VALUE *argv, VALUE self)
3488{
3489 VALUE proc = method_to_proc(self);
3490 return proc_curry(argc, argv, proc);
3491}
3492
3493static VALUE
3494compose(RB_BLOCK_CALL_FUNC_ARGLIST(_, args))
3495{
3496 VALUE f, g, fargs;
3497 f = RARRAY_AREF(args, 0);
3498 g = RARRAY_AREF(args, 1);
3499
3500 if (rb_obj_is_proc(g))
3501 fargs = rb_proc_call_with_block_kw(g, argc, argv, blockarg, RB_PASS_CALLED_KEYWORDS);
3502 else
3503 fargs = rb_funcall_with_block_kw(g, idCall, argc, argv, blockarg, RB_PASS_CALLED_KEYWORDS);
3504
3505 if (rb_obj_is_proc(f))
3506 return rb_proc_call(f, rb_ary_new3(1, fargs));
3507 else
3508 return rb_funcallv(f, idCall, 1, &fargs);
3509}
3510
3511static VALUE
3512to_callable(VALUE f)
3513{
3514 VALUE mesg;
3515
3516 if (rb_obj_is_proc(f)) return f;
3517 if (rb_obj_is_method(f)) return f;
3518 if (rb_obj_respond_to(f, idCall, TRUE)) return f;
3519 mesg = rb_fstring_lit("callable object is expected");
3520 rb_exc_raise(rb_exc_new_str(rb_eTypeError, mesg));
3521}
3522
3523static VALUE rb_proc_compose_to_left(VALUE self, VALUE g);
3524static VALUE rb_proc_compose_to_right(VALUE self, VALUE g);
3525
3526/*
3527 * call-seq:
3528 * prc << g -> a_proc
3529 *
3530 * Returns a proc that is the composition of this proc and the given <i>g</i>.
3531 * The returned proc takes a variable number of arguments, calls <i>g</i> with them
3532 * then calls this proc with the result.
3533 *
3534 * f = proc {|x| x * x }
3535 * g = proc {|x| x + x }
3536 * p (f << g).call(2) #=> 16
3537 *
3538 * See Proc#>> for detailed explanations.
3539 */
3540static VALUE
3541proc_compose_to_left(VALUE self, VALUE g)
3542{
3543 return rb_proc_compose_to_left(self, to_callable(g));
3544}
3545
3546static VALUE
3547rb_proc_compose_to_left(VALUE self, VALUE g)
3548{
3549 VALUE proc, args, procs[2];
3550 rb_proc_t *procp;
3551 int is_lambda;
3552
3553 procs[0] = self;
3554 procs[1] = g;
3555 args = rb_ary_tmp_new_from_values(0, 2, procs);
3556
3557 if (rb_obj_is_proc(g)) {
3558 GetProcPtr(g, procp);
3559 is_lambda = procp->is_lambda;
3560 }
3561 else {
3562 VM_ASSERT(rb_obj_is_method(g) || rb_obj_respond_to(g, idCall, TRUE));
3563 is_lambda = 1;
3564 }
3565
3566 proc = rb_proc_new(compose, args);
3567 GetProcPtr(proc, procp);
3568 procp->is_lambda = is_lambda;
3569
3570 return proc;
3571}
3572
3573/*
3574 * call-seq:
3575 * prc >> g -> a_proc
3576 *
3577 * Returns a proc that is the composition of this proc and the given <i>g</i>.
3578 * The returned proc takes a variable number of arguments, calls this proc with them
3579 * then calls <i>g</i> with the result.
3580 *
3581 * f = proc {|x| x * x }
3582 * g = proc {|x| x + x }
3583 * p (f >> g).call(2) #=> 8
3584 *
3585 * <i>g</i> could be other Proc, or Method, or any other object responding to
3586 * +call+ method:
3587 *
3588 * class Parser
3589 * def self.call(text)
3590 * # ...some complicated parsing logic...
3591 * end
3592 * end
3593 *
3594 * pipeline = File.method(:read) >> Parser >> proc { |data| puts "data size: #{data.count}" }
3595 * pipeline.call('data.json')
3596 *
3597 * See also Method#>> and Method#<<.
3598 */
3599static VALUE
3600proc_compose_to_right(VALUE self, VALUE g)
3601{
3602 return rb_proc_compose_to_right(self, to_callable(g));
3603}
3604
3605static VALUE
3606rb_proc_compose_to_right(VALUE self, VALUE g)
3607{
3608 VALUE proc, args, procs[2];
3609 rb_proc_t *procp;
3610 int is_lambda;
3611
3612 procs[0] = g;
3613 procs[1] = self;
3614 args = rb_ary_tmp_new_from_values(0, 2, procs);
3615
3616 GetProcPtr(self, procp);
3617 is_lambda = procp->is_lambda;
3618
3619 proc = rb_proc_new(compose, args);
3620 GetProcPtr(proc, procp);
3621 procp->is_lambda = is_lambda;
3622
3623 return proc;
3624}
3625
3626/*
3627 * call-seq:
3628 * meth << g -> a_proc
3629 *
3630 * Returns a proc that is the composition of this method and the given <i>g</i>.
3631 * The returned proc takes a variable number of arguments, calls <i>g</i> with them
3632 * then calls this method with the result.
3633 *
3634 * def f(x)
3635 * x * x
3636 * end
3637 *
3638 * f = self.method(:f)
3639 * g = proc {|x| x + x }
3640 * p (f << g).call(2) #=> 16
3641 */
3642static VALUE
3643rb_method_compose_to_left(VALUE self, VALUE g)
3644{
3645 g = to_callable(g);
3646 self = method_to_proc(self);
3647 return proc_compose_to_left(self, g);
3648}
3649
3650/*
3651 * call-seq:
3652 * meth >> g -> a_proc
3653 *
3654 * Returns a proc that is the composition of this method and the given <i>g</i>.
3655 * The returned proc takes a variable number of arguments, calls this method
3656 * with them then calls <i>g</i> with the result.
3657 *
3658 * def f(x)
3659 * x * x
3660 * end
3661 *
3662 * f = self.method(:f)
3663 * g = proc {|x| x + x }
3664 * p (f >> g).call(2) #=> 8
3665 */
3666static VALUE
3667rb_method_compose_to_right(VALUE self, VALUE g)
3668{
3669 g = to_callable(g);
3670 self = method_to_proc(self);
3671 return proc_compose_to_right(self, g);
3672}
3673
3674/*
3675 * call-seq:
3676 * proc.ruby2_keywords -> proc
3677 *
3678 * Marks the proc as passing keywords through a normal argument splat.
3679 * This should only be called on procs that accept an argument splat
3680 * (<tt>*args</tt>) but not explicit keywords or a keyword splat. It
3681 * marks the proc such that if the proc is called with keyword arguments,
3682 * the final hash argument is marked with a special flag such that if it
3683 * is the final element of a normal argument splat to another method call,
3684 * and that method call does not include explicit keywords or a keyword
3685 * splat, the final element is interpreted as keywords. In other words,
3686 * keywords will be passed through the proc to other methods.
3687 *
3688 * This should only be used for procs that delegate keywords to another
3689 * method, and only for backwards compatibility with Ruby versions before
3690 * 2.7.
3691 *
3692 * This method will probably be removed at some point, as it exists only
3693 * for backwards compatibility. As it does not exist in Ruby versions
3694 * before 2.7, check that the proc responds to this method before calling
3695 * it. Also, be aware that if this method is removed, the behavior of the
3696 * proc will change so that it does not pass through keywords.
3697 *
3698 * module Mod
3699 * foo = ->(meth, *args, &block) do
3700 * send(:"do_#{meth}", *args, &block)
3701 * end
3702 * foo.ruby2_keywords if foo.respond_to?(:ruby2_keywords)
3703 * end
3704 */
3705
3706static VALUE
3707proc_ruby2_keywords(VALUE procval)
3708{
3709 rb_proc_t *proc;
3710 GetProcPtr(procval, proc);
3711
3712 rb_check_frozen(procval);
3713
3714 if (proc->is_from_method) {
3715 rb_warn("Skipping set of ruby2_keywords flag for proc (proc created from method)");
3716 return procval;
3717 }
3718
3719 switch (proc->block.type) {
3720 case block_type_iseq:
3721 if (proc->block.as.captured.code.iseq->body->param.flags.has_rest &&
3722 !proc->block.as.captured.code.iseq->body->param.flags.has_kw &&
3723 !proc->block.as.captured.code.iseq->body->param.flags.has_kwrest) {
3724 proc->block.as.captured.code.iseq->body->param.flags.ruby2_keywords = 1;
3725 }
3726 else {
3727 rb_warn("Skipping set of ruby2_keywords flag for proc (proc accepts keywords or proc does not accept argument splat)");
3728 }
3729 break;
3730 default:
3731 rb_warn("Skipping set of ruby2_keywords flag for proc (proc not defined in Ruby)");
3732 break;
3733 }
3734
3735 return procval;
3736}
3737
3738/*
3739 * Document-class: LocalJumpError
3740 *
3741 * Raised when Ruby can't yield as requested.
3742 *
3743 * A typical scenario is attempting to yield when no block is given:
3744 *
3745 * def call_block
3746 * yield 42
3747 * end
3748 * call_block
3749 *
3750 * <em>raises the exception:</em>
3751 *
3752 * LocalJumpError: no block given (yield)
3753 *
3754 * A more subtle example:
3755 *
3756 * def get_me_a_return
3757 * Proc.new { return 42 }
3758 * end
3759 * get_me_a_return.call
3760 *
3761 * <em>raises the exception:</em>
3762 *
3763 * LocalJumpError: unexpected return
3764 */
3765
3766/*
3767 * Document-class: SystemStackError
3768 *
3769 * Raised in case of a stack overflow.
3770 *
3771 * def me_myself_and_i
3772 * me_myself_and_i
3773 * end
3774 * me_myself_and_i
3775 *
3776 * <em>raises the exception:</em>
3777 *
3778 * SystemStackError: stack level too deep
3779 */
3780
3781/*
3782 * Document-class: Proc
3783 *
3784 * A +Proc+ object is an encapsulation of a block of code, which can be stored
3785 * in a local variable, passed to a method or another Proc, and can be called.
3786 * Proc is an essential concept in Ruby and a core of its functional
3787 * programming features.
3788 *
3789 * square = Proc.new {|x| x**2 }
3790 *
3791 * square.call(3) #=> 9
3792 * # shorthands:
3793 * square.(3) #=> 9
3794 * square[3] #=> 9
3795 *
3796 * Proc objects are _closures_, meaning they remember and can use the entire
3797 * context in which they were created.
3798 *
3799 * def gen_times(factor)
3800 * Proc.new {|n| n*factor } # remembers the value of factor at the moment of creation
3801 * end
3802 *
3803 * times3 = gen_times(3)
3804 * times5 = gen_times(5)
3805 *
3806 * times3.call(12) #=> 36
3807 * times5.call(5) #=> 25
3808 * times3.call(times5.call(4)) #=> 60
3809 *
3810 * == Creation
3811 *
3812 * There are several methods to create a Proc
3813 *
3814 * * Use the Proc class constructor:
3815 *
3816 * proc1 = Proc.new {|x| x**2 }
3817 *
3818 * * Use the Kernel#proc method as a shorthand of Proc.new:
3819 *
3820 * proc2 = proc {|x| x**2 }
3821 *
3822 * * Receiving a block of code into proc argument (note the <code>&</code>):
3823 *
3824 * def make_proc(&block)
3825 * block
3826 * end
3827 *
3828 * proc3 = make_proc {|x| x**2 }
3829 *
3830 * * Construct a proc with lambda semantics using the Kernel#lambda method
3831 * (see below for explanations about lambdas):
3832 *
3833 * lambda1 = lambda {|x| x**2 }
3834 *
3835 * * Use the Lambda literal syntax (also constructs a proc with lambda semantics):
3836 *
3837 * lambda2 = ->(x) { x**2 }
3838 *
3839 * == Lambda and non-lambda semantics
3840 *
3841 * Procs are coming in two flavors: lambda and non-lambda (regular procs).
3842 * Differences are:
3843 *
3844 * * In lambdas, +return+ and +break+ means exit from this lambda;
3845 * * In non-lambda procs, +return+ means exit from embracing method
3846 * (and will throw +LocalJumpError+ if invoked outside the method);
3847 * * In non-lambda procs, +break+ means exit from the method which the block given for.
3848 * (and will throw +LocalJumpError+ if invoked after the method returns);
3849 * * In lambdas, arguments are treated in the same way as in methods: strict,
3850 * with +ArgumentError+ for mismatching argument number,
3851 * and no additional argument processing;
3852 * * Regular procs accept arguments more generously: missing arguments
3853 * are filled with +nil+, single Array arguments are deconstructed if the
3854 * proc has multiple arguments, and there is no error raised on extra
3855 * arguments.
3856 *
3857 * Examples:
3858 *
3859 * # +return+ in non-lambda proc, +b+, exits +m2+.
3860 * # (The block +{ return }+ is given for +m1+ and embraced by +m2+.)
3861 * $a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1 { return }; $a << :m2 end; m2; p $a
3862 * #=> []
3863 *
3864 * # +break+ in non-lambda proc, +b+, exits +m1+.
3865 * # (The block +{ break }+ is given for +m1+ and embraced by +m2+.)
3866 * $a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1 { break }; $a << :m2 end; m2; p $a
3867 * #=> [:m2]
3868 *
3869 * # +next+ in non-lambda proc, +b+, exits the block.
3870 * # (The block +{ next }+ is given for +m1+ and embraced by +m2+.)
3871 * $a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1 { next }; $a << :m2 end; m2; p $a
3872 * #=> [:m1, :m2]
3873 *
3874 * # Using +proc+ method changes the behavior as follows because
3875 * # The block is given for +proc+ method and embraced by +m2+.
3876 * $a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1(&proc { return }); $a << :m2 end; m2; p $a
3877 * #=> []
3878 * $a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1(&proc { break }); $a << :m2 end; m2; p $a
3879 * # break from proc-closure (LocalJumpError)
3880 * $a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1(&proc { next }); $a << :m2 end; m2; p $a
3881 * #=> [:m1, :m2]
3882 *
3883 * # +return+, +break+ and +next+ in the stubby lambda exits the block.
3884 * # (+lambda+ method behaves same.)
3885 * # (The block is given for stubby lambda syntax and embraced by +m2+.)
3886 * $a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1(&-> { return }); $a << :m2 end; m2; p $a
3887 * #=> [:m1, :m2]
3888 * $a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1(&-> { break }); $a << :m2 end; m2; p $a
3889 * #=> [:m1, :m2]
3890 * $a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1(&-> { next }); $a << :m2 end; m2; p $a
3891 * #=> [:m1, :m2]
3892 *
3893 * p = proc {|x, y| "x=#{x}, y=#{y}" }
3894 * p.call(1, 2) #=> "x=1, y=2"
3895 * p.call([1, 2]) #=> "x=1, y=2", array deconstructed
3896 * p.call(1, 2, 8) #=> "x=1, y=2", extra argument discarded
3897 * p.call(1) #=> "x=1, y=", nil substituted instead of error
3898 *
3899 * l = lambda {|x, y| "x=#{x}, y=#{y}" }
3900 * l.call(1, 2) #=> "x=1, y=2"
3901 * l.call([1, 2]) # ArgumentError: wrong number of arguments (given 1, expected 2)
3902 * l.call(1, 2, 8) # ArgumentError: wrong number of arguments (given 3, expected 2)
3903 * l.call(1) # ArgumentError: wrong number of arguments (given 1, expected 2)
3904 *
3905 * def test_return
3906 * -> { return 3 }.call # just returns from lambda into method body
3907 * proc { return 4 }.call # returns from method
3908 * return 5
3909 * end
3910 *
3911 * test_return # => 4, return from proc
3912 *
3913 * Lambdas are useful as self-sufficient functions, in particular useful as
3914 * arguments to higher-order functions, behaving exactly like Ruby methods.
3915 *
3916 * Procs are useful for implementing iterators:
3917 *
3918 * def test
3919 * [[1, 2], [3, 4], [5, 6]].map {|a, b| return a if a + b > 10 }
3920 * # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3921 * end
3922 *
3923 * Inside +map+, the block of code is treated as a regular (non-lambda) proc,
3924 * which means that the internal arrays will be deconstructed to pairs of
3925 * arguments, and +return+ will exit from the method +test+. That would
3926 * not be possible with a stricter lambda.
3927 *
3928 * You can tell a lambda from a regular proc by using the #lambda? instance method.
3929 *
3930 * Lambda semantics is typically preserved during the proc lifetime, including
3931 * <code>&</code>-deconstruction to a block of code:
3932 *
3933 * p = proc {|x, y| x }
3934 * l = lambda {|x, y| x }
3935 * [[1, 2], [3, 4]].map(&p) #=> [1, 3]
3936 * [[1, 2], [3, 4]].map(&l) # ArgumentError: wrong number of arguments (given 1, expected 2)
3937 *
3938 * The only exception is dynamic method definition: even if defined by
3939 * passing a non-lambda proc, methods still have normal semantics of argument
3940 * checking.
3941 *
3942 * class C
3943 * define_method(:e, &proc {})
3944 * end
3945 * C.new.e(1,2) #=> ArgumentError
3946 * C.new.method(:e).to_proc.lambda? #=> true
3947 *
3948 * This exception ensures that methods never have unusual argument passing
3949 * conventions, and makes it easy to have wrappers defining methods that
3950 * behave as usual.
3951 *
3952 * class C
3953 * def self.def2(name, &body)
3954 * define_method(name, &body)
3955 * end
3956 *
3957 * def2(:f) {}
3958 * end
3959 * C.new.f(1,2) #=> ArgumentError
3960 *
3961 * The wrapper <code>def2</code> receives _body_ as a non-lambda proc,
3962 * yet defines a method which has normal semantics.
3963 *
3964 * == Conversion of other objects to procs
3965 *
3966 * Any object that implements the +to_proc+ method can be converted into
3967 * a proc by the <code>&</code> operator, and therefore can be
3968 * consumed by iterators.
3969 *
3970
3971 * class Greeter
3972 * def initialize(greeting)
3973 * @greeting = greeting
3974 * end
3975 *
3976 * def to_proc
3977 * proc {|name| "#{@greeting}, #{name}!" }
3978 * end
3979 * end
3980 *
3981 * hi = Greeter.new("Hi")
3982 * hey = Greeter.new("Hey")
3983 * ["Bob", "Jane"].map(&hi) #=> ["Hi, Bob!", "Hi, Jane!"]
3984 * ["Bob", "Jane"].map(&hey) #=> ["Hey, Bob!", "Hey, Jane!"]
3985 *
3986 * Of the Ruby core classes, this method is implemented by Symbol,
3987 * Method, and Hash.
3988 *
3989 * :to_s.to_proc.call(1) #=> "1"
3990 * [1, 2].map(&:to_s) #=> ["1", "2"]
3991 *
3992 * method(:puts).to_proc.call(1) # prints 1
3993 * [1, 2].each(&method(:puts)) # prints 1, 2
3994 *
3995 * {test: 1}.to_proc.call(:test) #=> 1
3996 * %i[test many keys].map(&{test: 1}) #=> [1, nil, nil]
3997 *
3998 * == Orphaned Proc
3999 *
4000 * +return+ and +break+ in a block exit a method.
4001 * If a Proc object is generated from the block and the Proc object
4002 * survives until the method is returned, +return+ and +break+ cannot work.
4003 * In such case, +return+ and +break+ raises LocalJumpError.
4004 * A Proc object in such situation is called as orphaned Proc object.
4005 *
4006 * Note that the method to exit is different for +return+ and +break+.
4007 * There is a situation that orphaned for +break+ but not orphaned for +return+.
4008 *
4009 * def m1(&b) b.call end; def m2(); m1 { return } end; m2 # ok
4010 * def m1(&b) b.call end; def m2(); m1 { break } end; m2 # ok
4011 *
4012 * def m1(&b) b end; def m2(); m1 { return }.call end; m2 # ok
4013 * def m1(&b) b end; def m2(); m1 { break }.call end; m2 # LocalJumpError
4014 *
4015 * def m1(&b) b end; def m2(); m1 { return } end; m2.call # LocalJumpError
4016 * def m1(&b) b end; def m2(); m1 { break } end; m2.call # LocalJumpError
4017 *
4018 * Since +return+ and +break+ exits the block itself in lambdas,
4019 * lambdas cannot be orphaned.
4020 *
4021 * == Numbered parameters
4022 *
4023 * Numbered parameters are implicitly defined block parameters intended to
4024 * simplify writing short blocks:
4025 *
4026 * # Explicit parameter:
4027 * %w[test me please].each { |str| puts str.upcase } # prints TEST, ME, PLEASE
4028 * (1..5).map { |i| i**2 } # => [1, 4, 9, 16, 25]
4029 *
4030 * # Implicit parameter:
4031 * %w[test me please].each { puts _1.upcase } # prints TEST, ME, PLEASE
4032 * (1..5).map { _1**2 } # => [1, 4, 9, 16, 25]
4033 *
4034 * Parameter names from +_1+ to +_9+ are supported:
4035 *
4036 * [10, 20, 30].zip([40, 50, 60], [70, 80, 90]).map { _1 + _2 + _3 }
4037 * # => [120, 150, 180]
4038 *
4039 * Though, it is advised to resort to them wisely, probably limiting
4040 * yourself to +_1+ and +_2+, and to one-line blocks.
4041 *
4042 * Numbered parameters can't be used together with explicitly named
4043 * ones:
4044 *
4045 * [10, 20, 30].map { |x| _1**2 }
4046 * # SyntaxError (ordinary parameter is defined)
4047 *
4048 * To avoid conflicts, naming local variables or method
4049 * arguments +_1+, +_2+ and so on, causes a warning.
4050 *
4051 * _1 = 'test'
4052 * # warning: `_1' is reserved as numbered parameter
4053 *
4054 * Using implicit numbered parameters affects block's arity:
4055 *
4056 * p = proc { _1 + _2 }
4057 * l = lambda { _1 + _2 }
4058 * p.parameters # => [[:opt, :_1], [:opt, :_2]]
4059 * p.arity # => 2
4060 * l.parameters # => [[:req, :_1], [:req, :_2]]
4061 * l.arity # => 2
4062 *
4063 * Blocks with numbered parameters can't be nested:
4064 *
4065 * %w[test me].each { _1.each_char { p _1 } }
4066 * # SyntaxError (numbered parameter is already used in outer block here)
4067 * # %w[test me].each { _1.each_char { p _1 } }
4068 * # ^~
4069 *
4070 * Numbered parameters were introduced in Ruby 2.7.
4071 */
4072
4073
4074void
4075Init_Proc(void)
4076{
4077#undef rb_intern
4078 /* Proc */
4079 rb_cProc = rb_define_class("Proc", rb_cObject);
4080 rb_undef_alloc_func(rb_cProc);
4081 rb_define_singleton_method(rb_cProc, "new", rb_proc_s_new, -1);
4082
4083 rb_add_method(rb_cProc, idCall, VM_METHOD_TYPE_OPTIMIZED,
4084 (void *)OPTIMIZED_METHOD_TYPE_CALL, METHOD_VISI_PUBLIC);
4085 rb_add_method(rb_cProc, rb_intern("[]"), VM_METHOD_TYPE_OPTIMIZED,
4086 (void *)OPTIMIZED_METHOD_TYPE_CALL, METHOD_VISI_PUBLIC);
4087 rb_add_method(rb_cProc, rb_intern("==="), VM_METHOD_TYPE_OPTIMIZED,
4088 (void *)OPTIMIZED_METHOD_TYPE_CALL, METHOD_VISI_PUBLIC);
4089 rb_add_method(rb_cProc, rb_intern("yield"), VM_METHOD_TYPE_OPTIMIZED,
4090 (void *)OPTIMIZED_METHOD_TYPE_CALL, METHOD_VISI_PUBLIC);
4091
4092#if 0 /* for RDoc */
4093 rb_define_method(rb_cProc, "call", proc_call, -1);
4094 rb_define_method(rb_cProc, "[]", proc_call, -1);
4095 rb_define_method(rb_cProc, "===", proc_call, -1);
4096 rb_define_method(rb_cProc, "yield", proc_call, -1);
4097#endif
4098
4099 rb_define_method(rb_cProc, "to_proc", proc_to_proc, 0);
4100 rb_define_method(rb_cProc, "arity", proc_arity, 0);
4101 rb_define_method(rb_cProc, "clone", proc_clone, 0);
4102 rb_define_method(rb_cProc, "dup", rb_proc_dup, 0);
4103 rb_define_method(rb_cProc, "hash", proc_hash, 0);
4104 rb_define_method(rb_cProc, "to_s", proc_to_s, 0);
4105 rb_define_alias(rb_cProc, "inspect", "to_s");
4106 rb_define_method(rb_cProc, "lambda?", rb_proc_lambda_p, 0);
4107 rb_define_method(rb_cProc, "binding", proc_binding, 0);
4108 rb_define_method(rb_cProc, "curry", proc_curry, -1);
4109 rb_define_method(rb_cProc, "<<", proc_compose_to_left, 1);
4110 rb_define_method(rb_cProc, ">>", proc_compose_to_right, 1);
4111 rb_define_method(rb_cProc, "==", proc_eq, 1);
4112 rb_define_method(rb_cProc, "eql?", proc_eq, 1);
4113 rb_define_method(rb_cProc, "source_location", rb_proc_location, 0);
4114 rb_define_method(rb_cProc, "parameters", rb_proc_parameters, 0);
4115 rb_define_method(rb_cProc, "ruby2_keywords", proc_ruby2_keywords, 0);
4116 // rb_define_method(rb_cProc, "isolate", rb_proc_isolate, 0); is not accepted.
4117
4118 /* Exceptions */
4119 rb_eLocalJumpError = rb_define_class("LocalJumpError", rb_eStandardError);
4120 rb_define_method(rb_eLocalJumpError, "exit_value", localjump_xvalue, 0);
4121 rb_define_method(rb_eLocalJumpError, "reason", localjump_reason, 0);
4122
4123 rb_eSysStackError = rb_define_class("SystemStackError", rb_eException);
4124 rb_vm_register_special_exception(ruby_error_sysstack, rb_eSysStackError, "stack level too deep");
4125
4126 /* utility functions */
4127 rb_define_global_function("proc", f_proc, 0);
4128 rb_define_global_function("lambda", f_lambda, 0);
4129
4130 /* Method */
4131 rb_cMethod = rb_define_class("Method", rb_cObject);
4132 rb_undef_alloc_func(rb_cMethod);
4133 rb_undef_method(CLASS_OF(rb_cMethod), "new");
4134 rb_define_method(rb_cMethod, "==", method_eq, 1);
4135 rb_define_method(rb_cMethod, "eql?", method_eq, 1);
4136 rb_define_method(rb_cMethod, "hash", method_hash, 0);
4137 rb_define_method(rb_cMethod, "clone", method_clone, 0);
4138 rb_define_method(rb_cMethod, "call", rb_method_call_pass_called_kw, -1);
4139 rb_define_method(rb_cMethod, "===", rb_method_call_pass_called_kw, -1);
4140 rb_define_method(rb_cMethod, "curry", rb_method_curry, -1);
4141 rb_define_method(rb_cMethod, "<<", rb_method_compose_to_left, 1);
4142 rb_define_method(rb_cMethod, ">>", rb_method_compose_to_right, 1);
4143 rb_define_method(rb_cMethod, "[]", rb_method_call_pass_called_kw, -1);
4144 rb_define_method(rb_cMethod, "arity", method_arity_m, 0);
4145 rb_define_method(rb_cMethod, "inspect", method_inspect, 0);
4146 rb_define_method(rb_cMethod, "to_s", method_inspect, 0);
4147 rb_define_method(rb_cMethod, "to_proc", method_to_proc, 0);
4148 rb_define_method(rb_cMethod, "receiver", method_receiver, 0);
4149 rb_define_method(rb_cMethod, "name", method_name, 0);
4150 rb_define_method(rb_cMethod, "original_name", method_original_name, 0);
4151 rb_define_method(rb_cMethod, "owner", method_owner, 0);
4152 rb_define_method(rb_cMethod, "unbind", method_unbind, 0);
4153 rb_define_method(rb_cMethod, "source_location", rb_method_location, 0);
4154 rb_define_method(rb_cMethod, "parameters", rb_method_parameters, 0);
4155 rb_define_method(rb_cMethod, "super_method", method_super_method, 0);
4156 rb_define_method(rb_mKernel, "method", rb_obj_method, 1);
4157 rb_define_method(rb_mKernel, "public_method", rb_obj_public_method, 1);
4158 rb_define_method(rb_mKernel, "singleton_method", rb_obj_singleton_method, 1);
4159
4160 /* UnboundMethod */
4161 rb_cUnboundMethod = rb_define_class("UnboundMethod", rb_cObject);
4162 rb_undef_alloc_func(rb_cUnboundMethod);
4163 rb_undef_method(CLASS_OF(rb_cUnboundMethod), "new");
4164 rb_define_method(rb_cUnboundMethod, "==", method_eq, 1);
4165 rb_define_method(rb_cUnboundMethod, "eql?", method_eq, 1);
4166 rb_define_method(rb_cUnboundMethod, "hash", method_hash, 0);
4167 rb_define_method(rb_cUnboundMethod, "clone", method_clone, 0);
4168 rb_define_method(rb_cUnboundMethod, "arity", method_arity_m, 0);
4169 rb_define_method(rb_cUnboundMethod, "inspect", method_inspect, 0);
4170 rb_define_method(rb_cUnboundMethod, "to_s", method_inspect, 0);
4171 rb_define_method(rb_cUnboundMethod, "name", method_name, 0);
4172 rb_define_method(rb_cUnboundMethod, "original_name", method_original_name, 0);
4173 rb_define_method(rb_cUnboundMethod, "owner", method_owner, 0);
4174 rb_define_method(rb_cUnboundMethod, "bind", umethod_bind, 1);
4175 rb_define_method(rb_cUnboundMethod, "bind_call", umethod_bind_call, -1);
4176 rb_define_method(rb_cUnboundMethod, "source_location", rb_method_location, 0);
4177 rb_define_method(rb_cUnboundMethod, "parameters", rb_method_parameters, 0);
4178 rb_define_method(rb_cUnboundMethod, "super_method", method_super_method, 0);
4179
4180 /* Module#*_method */
4181 rb_define_method(rb_cModule, "instance_method", rb_mod_instance_method, 1);
4182 rb_define_method(rb_cModule, "public_instance_method", rb_mod_public_instance_method, 1);
4183 rb_define_method(rb_cModule, "define_method", rb_mod_define_method, -1);
4184
4185 /* Kernel */
4186 rb_define_method(rb_mKernel, "define_singleton_method", rb_obj_define_method, -1);
4187
4188 rb_define_private_method(rb_singleton_class(rb_vm_top_self()),
4189 "define_method", top_define_method, -1);
4190}
4191
4192/*
4193 * Objects of class Binding encapsulate the execution context at some
4194 * particular place in the code and retain this context for future
4195 * use. The variables, methods, value of <code>self</code>, and
4196 * possibly an iterator block that can be accessed in this context
4197 * are all retained. Binding objects can be created using
4198 * Kernel#binding, and are made available to the callback of
4199 * Kernel#set_trace_func and instances of TracePoint.
4200 *
4201 * These binding objects can be passed as the second argument of the
4202 * Kernel#eval method, establishing an environment for the
4203 * evaluation.
4204 *
4205 * class Demo
4206 * def initialize(n)
4207 * @secret = n
4208 * end
4209 * def get_binding
4210 * binding
4211 * end
4212 * end
4213 *
4214 * k1 = Demo.new(99)
4215 * b1 = k1.get_binding
4216 * k2 = Demo.new(-3)
4217 * b2 = k2.get_binding
4218 *
4219 * eval("@secret", b1) #=> 99
4220 * eval("@secret", b2) #=> -3
4221 * eval("@secret") #=> nil
4222 *
4223 * Binding objects have no class-specific methods.
4224 *
4225 */
4226
4227void
4228Init_Binding(void)
4229{
4230 rb_cBinding = rb_define_class("Binding", rb_cObject);
4231 rb_undef_alloc_func(rb_cBinding);
4232 rb_undef_method(CLASS_OF(rb_cBinding), "new");
4233 rb_define_method(rb_cBinding, "clone", binding_clone, 0);
4234 rb_define_method(rb_cBinding, "dup", binding_dup, 0);
4235 rb_define_method(rb_cBinding, "eval", bind_eval, -1);
4236 rb_define_method(rb_cBinding, "local_variables", bind_local_variables, 0);
4237 rb_define_method(rb_cBinding, "local_variable_get", bind_local_variable_get, 1);
4238 rb_define_method(rb_cBinding, "local_variable_set", bind_local_variable_set, 2);
4239 rb_define_method(rb_cBinding, "local_variable_defined?", bind_local_variable_defined_p, 1);
4240 rb_define_method(rb_cBinding, "receiver", bind_receiver, 0);
4241 rb_define_method(rb_cBinding, "source_location", bind_location, 0);
4242 rb_define_global_function("binding", rb_f_binding, 0);
4243}
rb_ary_store
void rb_ary_store(VALUE ary, long idx, VALUE val)
Definition: array.c:1141
rb_ary_tmp_new_from_values
VALUE rb_ary_tmp_new_from_values(VALUE klass, long n, const VALUE *elts)
Definition: array.c:774
rb_ary_dup
VALUE rb_ary_dup(VALUE ary)
Definition: array.c:2666
rb_ary_push
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:1301
rb_ary_freeze
VALUE rb_ary_freeze(VALUE ary)
Definition: array.c:674
rb_ary_new
VALUE rb_ary_new(void)
Definition: array.c:749
rb_ary_tmp_new
VALUE rb_ary_tmp_new(long capa)
Definition: array.c:846
rb_ary_plus
VALUE rb_ary_plus(VALUE x, VALUE y)
Definition: array.c:4800
UNREACHABLE_RETURN
#define UNREACHABLE_RETURN
Definition: assume.h:31
rb_define_method
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
Definition: cxxanyargs.hpp:653
rb_define_singleton_method
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
Definition: cxxanyargs.hpp:668
rb_define_private_method
#define rb_define_private_method(klass, mid, func, arity)
Defines klass#mid and makes it private.
Definition: cxxanyargs.hpp:660
rb_define_global_function
#define rb_define_global_function(mid, func, arity)
Defines rb_mKernel #mid.
Definition: cxxanyargs.hpp:678
mod
#define mod(x, y)
Definition: date_strftime.c:28
ptr
struct RIMemo * ptr
Definition: debug.c:88
MJIT_FUNC_EXPORTED
#define MJIT_FUNC_EXPORTED
Definition: dllexport.h:55
g
struct @77 g
max
int max
Definition: enough.c:225
sym
#define sym(name)
Definition: enumerator.c:4007
str
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
rb_obj_call_init_kw
void rb_obj_call_init_kw(VALUE obj, int argc, const VALUE *argv, int kw_splat)
Definition: eval.c:1717
rb_eLocalJumpError
VALUE rb_eLocalJumpError
Definition: eval.c:48
rb_eSysStackError
VALUE rb_eSysStackError
Definition: eval.c:49
rb_print_undef
void rb_print_undef(VALUE klass, ID id, rb_method_visibility_t visi)
Definition: eval_error.c:397
rb_print_inaccessible
void rb_print_inaccessible(VALUE klass, ID id, rb_method_visibility_t visi)
Definition: eval_error.c:425
eval_intern.h
rb_f_eval
VALUE rb_f_eval(int argc, const VALUE *argv, VALUE self)
Definition: vm_eval.c:1778
RSTRING_LEN
#define RSTRING_LEN(string)
Definition: fbuffer.h:22
FL_SINGLETON
#define FL_SINGLETON
Definition: fl_type.h:49
PRIsVALUE
#define PRIsVALUE
Definition: function.c:10
ruby_xfree
void ruby_xfree(void *x)
Deallocates a storage instance.
Definition: gc.c:10914
rb_gc_location
VALUE rb_gc_location(VALUE value)
Definition: gc.c:9003
rb_gc_mark_movable
void rb_gc_mark_movable(VALUE ptr)
Definition: gc.c:6106
rb_gc_mark
void rb_gc_mark(VALUE ptr)
Definition: gc.c:6112
rb_imemo_new
VALUE rb_imemo_new(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0)
Definition: gc.c:2412
rb_gc_register_mark_object
void rb_gc_register_mark_object(VALUE obj)
Inform the garbage collector that object is a live Ruby object that should not be moved.
Definition: gc.c:8022
RUBY_MARK_LEAVE
#define RUBY_MARK_LEAVE(msg)
Definition: gc.h:65
RUBY_MARK_ENTER
#define RUBY_MARK_ENTER(msg)
Definition: gc.h:64
RUBY_MARK_MOVABLE_UNLESS_NULL
#define RUBY_MARK_MOVABLE_UNLESS_NULL(ptr)
Definition: gc.h:71
RUBY_FREE_ENTER
#define RUBY_FREE_ENTER(msg)
Definition: gc.h:66
RUBY_FREE_LEAVE
#define RUBY_FREE_LEAVE(msg)
Definition: gc.h:67
rb_intern_str
#define rb_intern_str(string)
Definition: generator.h:16
CLASS_OF
#define CLASS_OF
Definition: globals.h:153
rb_define_class
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:748
rb_singleton_class
VALUE rb_singleton_class(VALUE obj)
Returns the singleton class of obj.
Definition: class.c:1924
rb_include_class_new
VALUE rb_include_class_new(VALUE module, VALUE super)
Definition: class.c:923
rb_singleton_class_get
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:1893
rb_undef_method
void rb_undef_method(VALUE klass, const char *name)
Definition: class.c:1777
rb_define_alias
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition: class.c:1999
rb_scan_args
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:2296
rb_block_given_p
int rb_block_given_p(void)
Determines if the current method is given a block.
Definition: eval.c:935
OBJ_FREEZE
#define OBJ_FREEZE
Definition: fl_type.h:134
FL_TEST
#define FL_TEST
Definition: fl_type.h:130
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2917
rb_exc_raise
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
Definition: eval.c:712
rb_typeddata_is_kind_of
int rb_typeddata_is_kind_of(VALUE obj, const rb_data_type_t *data_type)
Definition: error.c:1007
rb_bug
void rb_bug(const char *fmt,...)
Definition: error.c:768
rb_eStandardError
VALUE rb_eStandardError
Definition: error.c:1054
rb_eRangeError
VALUE rb_eRangeError
Definition: error.c:1061
rb_eTypeError
VALUE rb_eTypeError
Definition: error.c:1057
rb_warn_deprecated
void rb_warn_deprecated(const char *fmt, const char *suggest,...)
Definition: error.c:480
rb_warn
void rb_warn(const char *fmt,...)
Definition: error.c:408
rb_exc_new_str
VALUE rb_exc_new_str(VALUE etype, VALUE str)
Definition: error.c:1107
rb_eArgError
VALUE rb_eArgError
Definition: error.c:1058
rb_eException
VALUE rb_eException
Definition: error.c:1049
rb_warning
void rb_warning(const char *fmt,...)
Definition: error.c:439
rb_mKernel
VALUE rb_mKernel
Kernel module.
Definition: object.c:48
rb_cObject
VALUE rb_cObject
Object class.
Definition: object.c:49
rb_obj_class
VALUE rb_obj_class(VALUE)
Definition: object.c:245
rb_inspect
VALUE rb_inspect(VALUE)
Convenient wrapper of Object::inspect.
Definition: object.c:585
rb_cModule
VALUE rb_cModule
Module class.
Definition: object.c:50
rb_class_inherited_p
VALUE rb_class_inherited_p(VALUE, VALUE)
Determines if mod inherits arg.
Definition: object.c:1578
rb_obj_is_kind_of
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Determines if obj is a kind of c.
Definition: object.c:724
rb_class_search_ancestor
VALUE rb_class_search_ancestor(VALUE klass, VALUE super)
Definition: object.c:745
idRespond_to_missing
@ idRespond_to_missing
Definition: id.h:117
imemo_ifunc
@ imemo_ifunc
iterator function
Definition: imemo.h:39
rb_funcall
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:1077
rb_funcall_with_block_kw
VALUE rb_funcall_with_block_kw(VALUE, ID, int, const VALUE *, VALUE, int)
Definition: vm_eval.c:1173
rb_ary_new4
#define rb_ary_new4
Definition: array.h:74
rb_ary_new3
#define rb_ary_new3
Definition: array.h:73
rb_ary_new2
#define rb_ary_new2
Definition: array.h:72
UNLIMITED_ARGUMENTS
#define UNLIMITED_ARGUMENTS
Definition: error.h:29
rb_check_frozen
#define rb_check_frozen
Definition: error.h:72
rb_check_arity
#define rb_check_arity
Definition: error.h:34
rb_is_local_id
int rb_is_local_id(ID)
Definition: symbol.c:1034
rb_str_new2
#define rb_str_new2
Definition: string.h:276
rb_str_buf_cat2
#define rb_str_buf_cat2
Definition: string.h:284
rb_hash_uint
#define rb_hash_uint(h, i)
Definition: string.h:117
rb_hash_end
#define rb_hash_end(h)
Definition: string.h:118
rb_hash_start
st_index_t rb_hash_start(st_index_t)
Definition: random.c:1623
rb_str_set_len
void rb_str_set_len(VALUE, long)
Definition: string.c:2842
rb_str_append
VALUE rb_str_append(VALUE, VALUE)
Definition: string.c:3118
rb_str_buf_append
VALUE rb_str_buf_append(VALUE, VALUE)
Definition: string.c:3103
rb_str_intern
VALUE rb_str_intern(VALUE)
Definition: symbol.c:840
rb_str_cat_cstr
#define rb_str_cat_cstr(buf, str)
Definition: string.h:266
rb_ivar_get
VALUE rb_ivar_get(VALUE, ID)
Definition: variable.c:1234
rb_obj_respond_to
int rb_obj_respond_to(VALUE, ID, int)
Definition: vm_method.c:2545
rb_undef_alloc_func
void rb_undef_alloc_func(VALUE)
Definition: vm_method.c:954
ID2SYM
#define ID2SYM
Definition: symbol.h:44
SYM2ID
#define SYM2ID
Definition: symbol.h:45
rb_intern
ID rb_intern(const char *)
Definition: symbol.c:785
rb_check_id
ID rb_check_id(volatile VALUE *)
Returns ID for the given name if it is interned already, or 0.
Definition: symbol.c:1069
CONST_ID
#define CONST_ID
Definition: symbol.h:47
rb_to_id
ID rb_to_id(VALUE)
Definition: string.c:11501
rb_iv_get
VALUE rb_iv_get(VALUE, const char *)
Definition: variable.c:3569
FIX2INT
#define FIX2INT
Definition: int.h:41
class.h
Internal header for Class.
RCLASS_ORIGIN
#define RCLASS_ORIGIN(c)
Definition: class.h:87
gc.h
Internal header for GC.
object.h
Internal header for Object.
proc.h
Internal header for Proc.
rb_fstring_lit
#define rb_fstring_lit(str)
Definition: string.h:78
rb_is_local_name
int rb_is_local_name(VALUE name)
Definition: symbol.c:1235
rb_vm_top_self
VALUE rb_vm_top_self(void)
Definition: vm.c:3752
internal.h
rb_funcallv
#define rb_funcallv(...)
Definition: internal.h:77
rb_method_basic_definition_p
#define rb_method_basic_definition_p(...)
Definition: internal.h:78
rb_iseq_path
VALUE rb_iseq_path(const rb_iseq_t *iseq)
Definition: iseq.c:1087
rb_iseq_pathobj_new
VALUE rb_iseq_pathobj_new(VALUE path, VALUE realpath)
Definition: iseq.c:502
rb_iseq_parameters
VALUE rb_iseq_parameters(const rb_iseq_t *iseq, int is_proc)
Definition: iseq.c:2993
rb_iseq_first_lineno
VALUE rb_iseq_first_lineno(const rb_iseq_t *iseq)
Definition: iseq.c:1117
rb_iseq_new
rb_iseq_t * rb_iseq_new(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath, const rb_iseq_t *parent, enum iseq_type type)
Definition: iseq.c:809
iseq.h
RB_BLOCK_CALL_FUNC_ARGLIST
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)
Definition: iterator.h:31
rb_block_call_func_t
rb_block_call_func * rb_block_call_func_t
Definition: iterator.h:34
rb_block_call_func
VALUE rb_block_call_func(RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg))
Definition: iterator.h:33
CHAR_BIT
#define CHAR_BIT
Definition: limits.h:44
INT2FIX
#define INT2FIX
Definition: long.h:48
MEMCPY
#define MEMCPY(p1, p2, type, n)
Definition: memory.h:129
ALLOC_N
#define ALLOC_N
Definition: memory.h:133
RB_GC_GUARD
#define RB_GC_GUARD(v)
Definition: memory.h:91
rb_method_entry_clone
const rb_method_entry_t * rb_method_entry_clone(const rb_method_entry_t *me)
Definition: vm_method.c:606
rb_method_entry_eq
int rb_method_entry_eq(const rb_method_entry_t *m1, const rb_method_entry_t *m2)
Definition: vm_method.c:1821
rb_method_entry
const rb_method_entry_t * rb_method_entry(VALUE klass, ID id)
Definition: vm_method.c:1023
rb_callable_method_entry_with_refinements
const rb_callable_method_entry_t * rb_callable_method_entry_with_refinements(VALUE klass, ID id, VALUE *defined_class)
Definition: vm_method.c:1235
rb_add_method
void rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *option, rb_method_visibility_t visi)
Definition: vm_method.c:900
rb_method_visibility_t
rb_method_visibility_t
Definition: method.h:29
METHOD_VISI_PUBLIC
@ METHOD_VISI_PUBLIC
Definition: method.h:31
METHOD_VISI_UNDEF
@ METHOD_VISI_UNDEF
Definition: method.h:30
rb_method_entry_set
rb_method_entry_t * rb_method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *, rb_method_visibility_t noex)
Definition: vm_method.c:939
UNDEFINED_REFINED_METHOD_P
#define UNDEFINED_REFINED_METHOD_P(def)
Definition: method.h:199
VM_METHOD_TYPE_ISEQ
@ VM_METHOD_TYPE_ISEQ
Ruby method.
Definition: method.h:110
VM_METHOD_TYPE_ATTRSET
@ VM_METHOD_TYPE_ATTRSET
attr_writer or attr_accessor
Definition: method.h:112
VM_METHOD_TYPE_CFUNC
@ VM_METHOD_TYPE_CFUNC
C method.
Definition: method.h:111
VM_METHOD_TYPE_OPTIMIZED
@ VM_METHOD_TYPE_OPTIMIZED
Kernel::send, Proc::call, etc.
Definition: method.h:119
VM_METHOD_TYPE_REFINED
@ VM_METHOD_TYPE_REFINED
refinement
Definition: method.h:121
VM_METHOD_TYPE_NOTIMPLEMENTED
@ VM_METHOD_TYPE_NOTIMPLEMENTED
Definition: method.h:118
VM_METHOD_TYPE_MISSING
@ VM_METHOD_TYPE_MISSING
wrapper for method_missing(id)
Definition: method.h:120
VM_METHOD_TYPE_BMETHOD
@ VM_METHOD_TYPE_BMETHOD
Definition: method.h:114
VM_METHOD_TYPE_IVAR
@ VM_METHOD_TYPE_IVAR
attr_reader or attr_accessor
Definition: method.h:113
VM_METHOD_TYPE_ZSUPER
@ VM_METHOD_TYPE_ZSUPER
Definition: method.h:115
VM_METHOD_TYPE_ALIAS
@ VM_METHOD_TYPE_ALIAS
Definition: method.h:116
VM_METHOD_TYPE_UNDEF
@ VM_METHOD_TYPE_UNDEF
Definition: method.h:117
OPTIMIZED_METHOD_TYPE_CALL
@ OPTIMIZED_METHOD_TYPE_CALL
Definition: method.h:167
OPTIMIZED_METHOD_TYPE_BLOCK_CALL
@ OPTIMIZED_METHOD_TYPE_BLOCK_CALL
Definition: method.h:168
OPTIMIZED_METHOD_TYPE_SEND
@ OPTIMIZED_METHOD_TYPE_SEND
Definition: method.h:166
rb_method_entry_with_refinements
const rb_method_entry_t * rb_method_entry_with_refinements(VALUE klass, ID id, VALUE *defined_class)
Definition: vm_method.c:1208
UNDEFINED_METHOD_ENTRY_P
#define UNDEFINED_METHOD_ENTRY_P(me)
Definition: method.h:198
rb_method_entry_without_refinements
const rb_method_entry_t * rb_method_entry_without_refinements(VALUE klass, ID id, VALUE *defined_class)
Definition: vm_method.c:1247
rb_method_entry_at
const rb_method_entry_t * rb_method_entry_at(VALUE obj, ID id)
Definition: vm_method.c:973
rb_method_entry_complement_defined_class
const rb_callable_method_entry_t * rb_method_entry_complement_defined_class(const rb_method_entry_t *src_me, ID called_id, VALUE defined_class)
Definition: vm_method.c:619
rb_hash_method_entry
st_index_t rb_hash_method_entry(st_index_t hash, const rb_method_entry_t *me)
Definition: vm_method.c:1920
rb_method_entry_create
rb_method_entry_t * rb_method_entry_create(ID called_id, VALUE klass, rb_method_visibility_t visi, const rb_method_definition_t *def)
Definition: vm_method.c:597
METHOD_ENTRY_VISI
#define METHOD_ENTRY_VISI(me)
Definition: method.h:70
ruby::backward::cxxanyargs::rb_iterate
VALUE rb_iterate(onearg_type *q, VALUE w, type *e, VALUE r)
Old way to implement iterators.
Definition: cxxanyargs.hpp:204
CLONESETUP
#define CLONESETUP
Definition: newobj.h:37
id
const int id
Definition: nkf.c:209
name
const char * name
Definition: nkf.c:208
TRUE
#define TRUE
Definition: nkf.h:175
FALSE
#define FALSE
Definition: nkf.h:174
key
key
Definition: openssl_missing.h:185
Init_Proc
void Init_Proc(void)
Definition: proc.c:4075
rb_proc_call
VALUE rb_proc_call(VALUE self, VALUE args)
Definition: proc.c:981
rb_cUnboundMethod
VALUE rb_cUnboundMethod
Definition: proc.c:43
rb_vm_cref_new_toplevel
rb_cref_t * rb_vm_cref_new_toplevel(void)
Definition: vm.c:309
rb_method_entry_arity
int rb_method_entry_arity(const rb_method_entry_t *me)
Definition: proc.c:2684
rb_method_def
const rb_method_definition_t * rb_method_def(VALUE method)
Definition: proc.c:2802
ruby_binding_data_type
const rb_data_type_t ruby_binding_data_type
Definition: proc.c:319
rb_obj_singleton_method
VALUE rb_obj_singleton_method(VALUE obj, VALUE vid)
Definition: proc.c:2035
rb_iseq_location
VALUE rb_iseq_location(const rb_iseq_t *iseq)
Definition: proc.c:1373
check_argc
#define check_argc(argc)
Definition: proc.c:962
rb_block_arity
int rb_block_arity(void)
Definition: proc.c:1193
rb_vm_cref_in_context
const rb_cref_t * rb_vm_cref_in_context(VALUE self, VALUE cbase)
Definition: vm.c:1640
rb_binding_alloc
VALUE rb_binding_alloc(VALUE klass)
Definition: proc.c:331
MSG
#define MSG(s)
rb_hash_proc
st_index_t rb_hash_proc(st_index_t hash, VALUE prc)
Definition: proc.c:1433
attached
#define attached
Definition: proc.c:53
rb_proc_call_with_block_kw
VALUE rb_proc_call_with_block_kw(VALUE self, int argc, const VALUE *argv, VALUE passed_procval, int kw_splat)
Definition: proc.c:1001
rb_func_lambda_new
VALUE rb_func_lambda_new(rb_block_call_func_t func, VALUE val, int min_argc, int max_argc)
Definition: proc.c:742
rb_cBinding
VALUE rb_cBinding
Definition: proc.c:45
rb_obj_is_method
VALUE rb_obj_is_method(VALUE m)
Definition: proc.c:1590
rb_proc_get_iseq
const rb_iseq_t * rb_proc_get_iseq(VALUE self, int *is_proc)
Definition: proc.c:1242
rb_block_to_s
VALUE rb_block_to_s(VALUE self, const struct rb_block *block, const char *additional_info)
Definition: proc.c:1491
rb_proc_arity
int rb_proc_arity(VALUE self)
Definition: proc.c:1126
rb_block_proc
VALUE rb_block_proc(void)
Definition: proc.c:826
rb_proc_call_kw
VALUE rb_proc_call_kw(VALUE self, VALUE args, int kw_splat)
Definition: proc.c:966
rb_proc_lambda_p
VALUE rb_proc_lambda_p(VALUE procval)
Definition: proc.c:275
rb_callable_receiver
VALUE rb_callable_receiver(VALUE callable)
Definition: proc.c:2787
rb_mod_method_arity
int rb_mod_method_arity(VALUE mod, ID id)
Definition: proc.c:2773
rb_block_pair_yield_optimizable
int rb_block_pair_yield_optimizable(void)
Definition: proc.c:1158
rb_unnamed_parameters
VALUE rb_unnamed_parameters(int arity)
Definition: proc.c:1393
rb_func_proc_new
VALUE rb_func_proc_new(rb_block_call_func_t func, VALUE val)
Definition: proc.c:735
rb_method_iseq
const rb_iseq_t * rb_method_iseq(VALUE method)
Definition: proc.c:2835
rb_find_defined_class_by_owner
VALUE rb_find_defined_class_by_owner(VALUE current_class, VALUE target_owner)
Definition: vm_insnhelper.c:3011
Init_Binding
void Init_Binding(void)
Definition: proc.c:4228
IS_METHOD_PROC_IFUNC
#define IS_METHOD_PROC_IFUNC(ifunc)
Definition: proc.c:57
rb_obj_method
VALUE rb_obj_method(VALUE obj, VALUE vid)
Definition: proc.c:1992
rb_method_call_kw
VALUE rb_method_call_kw(int argc, const VALUE *argv, VALUE method, int kw_splat)
Definition: proc.c:2391
rb_vm_ifunc_new
struct vm_ifunc * rb_vm_ifunc_new(rb_block_call_func_t func, const void *data, int min_argc, int max_argc)
Definition: proc.c:705
rb_obj_method_arity
int rb_obj_method_arity(VALUE obj, ID id)
Definition: proc.c:2781
rb_proc_location
VALUE rb_proc_location(VALUE self)
Definition: proc.c:1387
UPDATE_REFERENCE
#define UPDATE_REFERENCE(_ref)
Definition: proc.c:31
rb_method_entry_location
VALUE rb_method_entry_location(const rb_method_entry_t *me)
Definition: proc.c:2869
rb_method_location
VALUE rb_method_location(VALUE method)
Definition: proc.c:2884
rb_block_lambda
VALUE rb_block_lambda(void)
Definition: proc.c:845
rb_method_call
VALUE rb_method_call(int argc, const VALUE *argv, VALUE method)
Definition: proc.c:2398
rb_method_name_error
void rb_method_name_error(VALUE klass, VALUE str)
Definition: proc.c:1909
rb_sym_to_proc
VALUE rb_sym_to_proc(VALUE sym)
Definition: proc.c:1443
rb_cProc
VALUE rb_cProc
Definition: proc.c:46
rb_proc_new
VALUE rb_proc_new(rb_block_call_func_t func, VALUE val)
Definition: proc.c:3145
rb_binding_new
VALUE rb_binding_new(void)
Definition: proc.c:364
rb_method_call_with_block
VALUE rb_method_call_with_block(int argc, const VALUE *argv, VALUE method, VALUE passed_procval)
Definition: proc.c:2434
rb_proc_call_with_block
VALUE rb_proc_call_with_block(VALUE self, int argc, const VALUE *argv, VALUE passed_procval)
Definition: proc.c:1013
rb_obj_public_method
VALUE rb_obj_public_method(VALUE obj, VALUE vid)
Definition: proc.c:2005
rb_method_call_with_block_kw
VALUE rb_method_call_with_block_kw(int argc, const VALUE *argv, VALUE method, VALUE passed_procval, int kw_splat)
Definition: proc.c:2421
rb_block_min_max_arity
int rb_block_min_max_arity(int *max)
Definition: proc.c:1226
UPDATE_TYPED_REFERENCE
#define UPDATE_TYPED_REFERENCE(_type, _ref)
Definition: proc.c:30
rb_obj_is_proc
VALUE rb_obj_is_proc(VALUE proc)
Definition: proc.c:152
rb_cMethod
VALUE rb_cMethod
Definition: proc.c:44
rb_proc_alloc
VALUE rb_proc_alloc(VALUE klass)
Definition: proc.c:145
RARRAY_CONST_PTR
#define RARRAY_CONST_PTR(s)
Definition: psych_emitter.c:4
RARRAY_AREF
#define RARRAY_AREF(a, i)
Definition: psych_emitter.c:7
RARRAY_LEN
#define RARRAY_LEN
Definition: rarray.h:52
RBASIC_CLASS
#define RBASIC_CLASS
Definition: rbasic.h:35
RCLASS_SUPER
#define RCLASS_SUPER
Definition: rclass.h:33
DATA_PTR
#define DATA_PTR(obj)
Definition: rdata.h:56
NULL
#define NULL
Definition: regenc.h:69
RB_OBJ_WRITE
#define RB_OBJ_WRITE(a, slot, b)
WB for new reference from ‘a’ to ‘b’.
Definition: rgengc.h:107
RB_OBJ_WRITTEN
#define RB_OBJ_WRITTEN(a, oldv, b)
WB for new reference from ‘a’ to ‘b’.
Definition: rgengc.h:114
rb_mRubyVMFrozenCore
VALUE rb_mRubyVMFrozenCore
Definition: vm.c:375
RUBY_TYPED_DEFAULT_FREE
#define RUBY_TYPED_DEFAULT_FREE
Definition: rtypeddata.h:44
TypedData_Get_Struct
#define TypedData_Get_Struct(obj, type, data_type, sval)
Definition: rtypeddata.h:130
RUBY_TYPED_FREE_IMMEDIATELY
@ RUBY_TYPED_FREE_IMMEDIATELY
Definition: rtypeddata.h:62
RUBY_TYPED_WB_PROTECTED
@ RUBY_TYPED_WB_PROTECTED
Definition: rtypeddata.h:64
TypedData_Make_Struct
#define TypedData_Make_Struct(klass, type, data_type, sval)
Definition: rtypeddata.h:122
Check_TypedStruct
#define Check_TypedStruct(v, t)
Definition: rtypeddata.h:48
rb_obj_classname
const char * rb_obj_classname(VALUE)
Definition: variable.c:308
argc
int argc
Definition: ruby.c:240
argv
char ** argv
Definition: ruby.c:241
ST2FIX
#define ST2FIX(h)
Definition: ruby_missing.h:21
RB_PASS_CALLED_KEYWORDS
#define RB_PASS_CALLED_KEYWORDS
Definition: scan_args.h:48
RB_NO_KEYWORDS
#define RB_NO_KEYWORDS
Definition: scan_args.h:46
Qundef
#define Qundef
Definition: special_consts.h:53
Qtrue
#define Qtrue
Definition: special_consts.h:52
RTEST
#define RTEST
Definition: special_consts.h:42
Qnil
#define Qnil
Definition: special_consts.h:51
Qfalse
#define Qfalse
Definition: special_consts.h:50
NIL_P
#define NIL_P
Definition: special_consts.h:46
f
#define f
rb_str_catf
VALUE rb_str_catf(VALUE, const char *,...)
Definition: sprintf.c:1243
rb_sprintf
VALUE rb_sprintf(const char *,...)
Definition: sprintf.c:1203
st_index_t
st_data_t st_index_t
Definition: st.h:50
_
#define _(args)
Definition: stdarg.h:31
METHOD
Definition: proc.c:35
METHOD::klass
const VALUE klass
Definition: proc.c:37
METHOD::me
const rb_method_entry_t *const me
Definition: proc.c:39
METHOD::iclass
const VALUE iclass
Definition: proc.c:38
METHOD::recv
const VALUE recv
Definition: proc.c:36
cfunc_proc_t
Definition: proc.c:119
cfunc_proc_t::env
VALUE env[VM_ENV_DATA_SIZE+1]
Definition: proc.c:121
cfunc_proc_t::basic
rb_proc_t basic
Definition: proc.c:120
rb_binding_t
Definition: vm_core.h:1112
rb_binding_t::pathobj
const VALUE pathobj
Definition: vm_core.h:1114
rb_binding_t::first_lineno
unsigned short first_lineno
Definition: vm_core.h:1115
rb_binding_t::block
const struct rb_block block
Definition: vm_core.h:1113
rb_block
Definition: vm_core.h:760
rb_block::as
union rb_block::@199 as
rb_block::captured
struct rb_captured_block captured
Definition: vm_core.h:762
rb_block::symbol
VALUE symbol
Definition: vm_core.h:763
rb_block::type
enum rb_block_type type
Definition: vm_core.h:766
rb_block::proc
VALUE proc
Definition: vm_core.h:764
rb_callable_method_entry_struct
Definition: method.h:62
rb_captured_block
Definition: vm_core.h:736
rb_captured_block::ifunc
const struct vm_ifunc * ifunc
Definition: vm_core.h:741
rb_captured_block::ep
const VALUE * ep
Definition: vm_core.h:738
rb_captured_block::iseq
const rb_iseq_t * iseq
Definition: vm_core.h:740
rb_captured_block::code
union rb_captured_block::@198 code
rb_captured_block::self
VALUE self
Definition: vm_core.h:737
rb_captured_block::val
VALUE val
Definition: vm_core.h:742
rb_control_frame_struct
Definition: vm_core.h:769
rb_cref_struct
CREF (Class REFerence)
Definition: method.h:44
rb_data_type_struct
Definition: rtypeddata.h:70
rb_env_t
Definition: vm_core.h:1099
rb_execution_context_struct
Definition: vm_core.h:854
rb_execution_context_struct::cfp
rb_control_frame_t * cfp
Definition: vm_core.h:858
rb_iseq_constant_body::ruby2_keywords
unsigned int ruby2_keywords
Definition: vm_core.h:356
rb_iseq_constant_body::keyword
const struct rb_iseq_constant_body::@188::rb_iseq_param_keyword * keyword
rb_iseq_constant_body::local_iseq
struct rb_iseq_struct * local_iseq
Definition: vm_core.h:412
rb_iseq_constant_body::block_start
int block_start
Definition: vm_core.h:366
rb_iseq_constant_body::has_block
unsigned int has_block
Definition: vm_core.h:352
rb_iseq_constant_body::local_table_size
unsigned int local_table_size
Definition: vm_core.h:424
rb_iseq_constant_body::has_kwrest
unsigned int has_kwrest
Definition: vm_core.h:351
rb_iseq_constant_body::opt_num
int opt_num
Definition: vm_core.h:362
rb_iseq_constant_body::flags
struct rb_iseq_constant_body::@188::@190 flags
rb_iseq_constant_body::lead_num
int lead_num
Definition: vm_core.h:361
rb_iseq_constant_body::location
rb_iseq_location_t location
Definition: vm_core.h:393
rb_iseq_constant_body::has_kw
unsigned int has_kw
Definition: vm_core.h:350
rb_iseq_constant_body::post_num
int post_num
Definition: vm_core.h:365
rb_iseq_constant_body::param
struct rb_iseq_constant_body::@188 param
parameter information
rb_iseq_constant_body::local_table
const ID * local_table
Definition: vm_core.h:405
rb_iseq_constant_body::has_rest
unsigned int has_rest
Definition: vm_core.h:348
rb_iseq_location_struct::first_lineno
VALUE first_lineno
Definition: vm_core.h:270
rb_iseq_location_struct::pathobj
VALUE pathobj
Definition: vm_core.h:267
rb_iseq_struct
Definition: vm_core.h:444
rb_iseq_struct::body
struct rb_iseq_constant_body * body
Definition: vm_core.h:448
rb_method_alias_struct::original_me
struct rb_method_entry_struct * original_me
Definition: method.h:151
rb_method_definition_struct
Definition: method.h:172
rb_method_definition_struct::alias
rb_method_alias_t alias
Definition: method.h:182
rb_method_definition_struct::original_id
ID original_id
Definition: method.h:189
rb_method_definition_struct::body
union rb_method_definition_struct::@123 body
rb_method_entry_struct
Definition: method.h:54
rb_method_entry_struct::called_id
ID called_id
Definition: method.h:58
rb_method_entry_struct::def
struct rb_method_definition_struct *const def
Definition: method.h:57
rb_method_entry_struct::defined_class
VALUE defined_class
Definition: method.h:56
rb_method_entry_struct::owner
VALUE owner
Definition: method.h:59
rb_proc_t
Definition: vm_core.h:1086
rb_proc_t::block
const struct rb_block block
Definition: vm_core.h:1087
rb_proc_t::is_from_method
unsigned int is_from_method
Definition: vm_core.h:1088
rb_proc_t::is_lambda
unsigned int is_lambda
Definition: vm_core.h:1089
rb_scope_visi_struct
Definition: method.h:38
rb_scope_visi_struct::module_func
unsigned int module_func
Definition: method.h:40
rb_thread_struct
Definition: vm_core.h:935
rb_thread_struct::top_wrapper
VALUE top_wrapper
Definition: vm_core.h:950
vm_ifunc_argc
Definition: imemo.h:75
vm_ifunc_argc::max
int max
Definition: imemo.h:80
vm_ifunc_argc::min
int min
Definition: imemo.h:80
vm_ifunc
IFUNC (Internal FUNCtion)
Definition: imemo.h:85
vm_ifunc::data
const void * data
Definition: imemo.h:89
vm_ifunc::argc
struct vm_ifunc_argc argc
Definition: imemo.h:90
vm_ifunc::func
rb_block_call_func_t func
Definition: imemo.h:88
error
void error(const char *msg)
Definition: untgz.c:593
VALUE
unsigned long VALUE
Definition: value.h:38
SIZEOF_VALUE
#define SIZEOF_VALUE
Definition: value.h:41
ID
unsigned long ID
Definition: value.h:39
T_MODULE
#define T_MODULE
Definition: value_type.h:69
T_ICLASS
#define T_ICLASS
Definition: value_type.h:65
T_CLASS
#define T_CLASS
Definition: value_type.h:57
BUILTIN_TYPE
#define BUILTIN_TYPE
Definition: value_type.h:84
rb_vm_block_copy
void rb_vm_block_copy(VALUE obj, const struct rb_block *dst, const struct rb_block *src)
Definition: vm.c:921
rb_vm_frame_block_handler
VALUE rb_vm_frame_block_handler(const rb_control_frame_t *cfp)
Definition: vm.c:126
rb_proc_dup
VALUE rb_proc_dup(VALUE self)
Definition: vm.c:956
rb_vm_make_binding
VALUE rb_vm_make_binding(const rb_execution_context_t *ec, const rb_control_frame_t *src_cfp)
Definition: vm.c:1172
rb_vm_make_proc_lambda
VALUE rb_vm_make_proc_lambda(const rb_execution_context_t *ec, const struct rb_captured_block *captured, VALUE klass, int8_t is_lambda)
Definition: vm.c:1152
rb_vm_env_local_variables
VALUE rb_vm_env_local_variables(const rb_env_t *env)
Definition: vm.c:876
rb_vm_get_ruby_level_next_cfp
rb_control_frame_t * rb_vm_get_ruby_level_next_cfp(const rb_execution_context_t *ec, const rb_control_frame_t *cfp)
Definition: vm.c:589
rb_vm_invoke_proc
VALUE rb_vm_invoke_proc(rb_execution_context_t *ec, rb_proc_t *proc, int argc, const VALUE *argv, int kw_splat, VALUE passed_block_handler)
Definition: vm.c:1475
rb_binding_add_dynavars
const VALUE * rb_binding_add_dynavars(VALUE bindval, rb_binding_t *bind, int dyncount, const ID *dynvars)
Definition: vm.c:1203
rb_vm_env_prev_env
const rb_env_t * rb_vm_env_prev_env(const rb_env_t *env)
Definition: vm.c:830
rb_vm_block_ep_update
void rb_vm_block_ep_update(VALUE obj, const struct rb_block *dst, const VALUE *ep)
Definition: vm.c:326
rb_id2str
#define rb_id2str(id)
Definition: vm_backtrace.c:30
vm_core.h
VM_ENV_DATA_SIZE
#define VM_ENV_DATA_SIZE
Definition: vm_core.h:1206
rb_vm_register_special_exception
#define rb_vm_register_special_exception(sp, e, m)
Definition: vm_core.h:1720
GetBindingPtr
#define GetBindingPtr(obj, ptr)
Definition: vm_core.h:1109
VM_ENV_DATA_INDEX_FLAGS
#define VM_ENV_DATA_INDEX_FLAGS
Definition: vm_core.h:1210
block_type_symbol
@ block_type_symbol
Definition: vm_core.h:756
block_type_iseq
@ block_type_iseq
Definition: vm_core.h:754
block_type_ifunc
@ block_type_ifunc
Definition: vm_core.h:755
block_type_proc
@ block_type_proc
Definition: vm_core.h:757
VM_ASSERT
#define VM_ASSERT(expr)
Definition: vm_core.h:61
block_handler_type_ifunc
@ block_handler_type_ifunc
Definition: vm_core.h:748
block_handler_type_proc
@ block_handler_type_proc
Definition: vm_core.h:750
block_handler_type_symbol
@ block_handler_type_symbol
Definition: vm_core.h:749
block_handler_type_iseq
@ block_handler_type_iseq
Definition: vm_core.h:747
VM_ENV_DATA_INDEX_ENV
#define VM_ENV_DATA_INDEX_ENV
Definition: vm_core.h:1211
ruby_error_sysstack
@ ruby_error_sysstack
Definition: vm_core.h:497
VM_BLOCK_HANDLER_NONE
#define VM_BLOCK_HANDLER_NONE
Definition: vm_core.h:1299
VM_ENV_DATA_INDEX_SPECVAL
#define VM_ENV_DATA_INDEX_SPECVAL
Definition: vm_core.h:1209
GetProcPtr
#define GetProcPtr(obj, ptr)
Definition: vm_core.h:1083
VM_ENV_DATA_INDEX_ME_CREF
#define VM_ENV_DATA_INDEX_ME_CREF
Definition: vm_core.h:1208
rb_vm_bh_to_procval
VALUE rb_vm_bh_to_procval(const rb_execution_context_t *ec, VALUE block_handler)
Definition: vm_insnhelper.c:474
RUBY_VM_PREVIOUS_CONTROL_FRAME
#define RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp)
Definition: vm_core.h:1392
VM_UNREACHABLE
#define VM_UNREACHABLE(func)
Definition: vm_core.h:62
rb_vm_call_kw
VALUE rb_vm_call_kw(rb_execution_context_t *ec, VALUE recv, VALUE id, int argc, const VALUE *argv, const rb_callable_method_entry_t *me, int kw_splat)
Definition: vm_eval.c:260
VM_FRAME_MAGIC_IFUNC
@ VM_FRAME_MAGIC_IFUNC
Definition: vm_core.h:1183
VM_FRAME_FLAG_CFRAME
@ VM_FRAME_FLAG_CFRAME
Definition: vm_core.h:1193
VM_ENV_FLAG_LOCAL
@ VM_ENV_FLAG_LOCAL
Definition: vm_core.h:1200
VM_ENV_FLAG_ESCAPED
@ VM_ENV_FLAG_ESCAPED
Definition: vm_core.h:1201
VM_ENV_FLAG_ISOLATED
@ VM_ENV_FLAG_ISOLATED
Definition: vm_core.h:1203
VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM
@ VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM
Definition: vm_core.h:1195
undefined
#define undefined
Definition: vm_method.c:18
env
#define env
def
int def(FILE *source, FILE *dest, int level)
Definition: zpipe.c:36
ZALLOC
#define ZALLOC(strm, items, size)
Definition: zutil.h:266