Ruby: vm_eval.c Source File

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

vm_eval.c
Go to the documentation of this file.
1/**********************************************************************
2
3 vm_eval.c -
4
5 $Author$
6 created at: Sat May 24 16:02:32 JST 2008
7
8 Copyright (C) 1993-2007 Yukihiro Matsumoto
9 Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
10 Copyright (C) 2000 Information-technology Promotion Agency, Japan
11
12**********************************************************************/
13
14 struct local_var_list {
15 VALUE tbl;
16};
17
18static inline VALUE method_missing(rb_execution_context_t *ec, VALUE obj, ID id, int argc, const VALUE *argv, enum method_missing_reason call_status, int kw_splat);
19static inline VALUE vm_yield_with_cref(rb_execution_context_t *ec, int argc, const VALUE *argv, int kw_splat, const rb_cref_t *cref, int is_lambda);
20static inline VALUE vm_yield(rb_execution_context_t *ec, int argc, const VALUE *argv, int kw_splat);
21static inline VALUE vm_yield_with_block(rb_execution_context_t *ec, int argc, const VALUE *argv, VALUE block_handler, int kw_splat);
22static inline VALUE vm_yield_force_blockarg(rb_execution_context_t *ec, VALUE args);
23 VALUE vm_exec(rb_execution_context_t *ec, bool mjit_enable_p);
24static void vm_set_eval_stack(rb_execution_context_t * th, const rb_iseq_t *iseq, const rb_cref_t *cref, const struct rb_block *base_block);
25static int vm_collect_local_variables_in_heap(const VALUE *dfp, const struct local_var_list *vars);
26
27static VALUE rb_eUncaughtThrow;
28static ID id_result, id_tag, id_value;
29#define id_mesg idMesg
30
31 typedef enum call_type {
32 CALL_PUBLIC,
33 CALL_FCALL,
34 CALL_VCALL,
35 CALL_PUBLIC_KW,
36 CALL_FCALL_KW,
37 CALL_TYPE_MAX
38} call_type;
39
40static VALUE send_internal(int argc, const VALUE *argv, VALUE recv, call_type scope);
41static VALUE vm_call0_body(rb_execution_context_t* ec, struct rb_calling_info *calling, const VALUE *argv);
42
43#ifndef MJIT_HEADER
44
45 MJIT_FUNC_EXPORTED VALUE
46rb_vm_call0(rb_execution_context_t *ec, VALUE recv, ID id, int argc, const VALUE *argv, const rb_callable_method_entry_t *cme, int kw_splat)
47{
48 struct rb_calling_info calling = {
49 .ci = &VM_CI_ON_STACK(id, kw_splat ? VM_CALL_KW_SPLAT : 0, argc, NULL),
50 .cc = &VM_CC_ON_STACK(Qfalse, vm_call_general, { 0 }, cme),
51 .block_handler = vm_passed_block_handler(ec),
52 .recv = recv,
53 .argc = argc,
54 .kw_splat = kw_splat,
55 };
56
57 return vm_call0_body(ec, &calling, argv);
58}
59
60static inline VALUE
61vm_call0_cc(rb_execution_context_t *ec, VALUE recv, ID id, int argc, const VALUE *argv, const struct rb_callcache *cc, int kw_splat)
62{
63 struct rb_calling_info calling = {
64 .ci = &VM_CI_ON_STACK(id, kw_splat ? VM_CALL_KW_SPLAT : 0, argc, NULL),
65 .cc = cc,
66 .block_handler = vm_passed_block_handler(ec),
67 .recv = recv,
68 .argc = argc,
69 .kw_splat = kw_splat,
70 };
71
72 return vm_call0_body(ec, &calling, argv);
73}
74
75static VALUE
76vm_call0_cme(rb_execution_context_t *ec, struct rb_calling_info *calling, const VALUE *argv, const rb_callable_method_entry_t *cme)
77{
78 calling->cc = &VM_CC_ON_STACK(Qfalse, vm_call_general, { 0 }, cme);
79 return vm_call0_body(ec, calling, argv);
80}
81
82static VALUE
83vm_call0_super(rb_execution_context_t *ec, struct rb_calling_info *calling, const VALUE *argv, VALUE klass, enum method_missing_reason ex)
84{
85 ID mid = vm_ci_mid(calling->ci);
86 klass = RCLASS_SUPER(klass);
87
88 if (klass) {
89 const rb_callable_method_entry_t *cme = rb_callable_method_entry(klass, mid);
90
91 if (cme) {
92 RUBY_VM_CHECK_INTS(ec);
93 return vm_call0_cme(ec, calling, argv, cme);
94 }
95 }
96
97 vm_passed_block_handler_set(ec, calling->block_handler);
98 return method_missing(ec, calling->recv, mid, calling->argc, argv, ex, calling->kw_splat);
99}
100
101static VALUE
102vm_call0_cfunc_with_frame(rb_execution_context_t* ec, struct rb_calling_info *calling, const VALUE *argv)
103{
104 const struct rb_callinfo *ci = calling->ci;
105 VALUE val;
106 const rb_callable_method_entry_t *me = vm_cc_cme(calling->cc);
107 const rb_method_cfunc_t *cfunc = UNALIGNED_MEMBER_PTR(me->def, body.cfunc);
108 int len = cfunc->argc;
109 VALUE recv = calling->recv;
110 int argc = calling->argc;
111 ID mid = vm_ci_mid(ci);
112 VALUE block_handler = calling->block_handler;
113 int frame_flags = VM_FRAME_MAGIC_CFUNC | VM_FRAME_FLAG_CFRAME | VM_ENV_FLAG_LOCAL;
114
115 if (calling->kw_splat) {
116 if (argc > 0 && RB_TYPE_P(argv[argc-1], T_HASH) && RHASH_EMPTY_P(argv[argc-1])) {
117 argc--;
118 }
119 else {
120 frame_flags |= VM_FRAME_FLAG_CFRAME_KW;
121 }
122 }
123
124 RUBY_DTRACE_CMETHOD_ENTRY_HOOK(ec, me->owner, me->def->original_id);
125 EXEC_EVENT_HOOK(ec, RUBY_EVENT_C_CALL, recv, me->def->original_id, mid, me->owner, Qnil);
126 {
127 rb_control_frame_t *reg_cfp = ec->cfp;
128
129 vm_push_frame(ec, 0, frame_flags, recv,
130 block_handler, (VALUE)me,
131 0, reg_cfp->sp, 0, 0);
132
133 if (len >= 0) rb_check_arity(argc, len, len);
134
135 val = (*cfunc->invoker)(recv, argc, argv, cfunc->func);
136
137 CHECK_CFP_CONSISTENCY("vm_call0_cfunc_with_frame");
138 rb_vm_pop_frame(ec);
139 }
140 EXEC_EVENT_HOOK(ec, RUBY_EVENT_C_RETURN, recv, me->def->original_id, mid, me->owner, val);
141 RUBY_DTRACE_CMETHOD_RETURN_HOOK(ec, me->owner, me->def->original_id);
142
143 return val;
144}
145
146static VALUE
147vm_call0_cfunc(rb_execution_context_t *ec, struct rb_calling_info *calling, const VALUE *argv)
148{
149 return vm_call0_cfunc_with_frame(ec, calling, argv);
150}
151
152/* `ci' should point temporal value (on stack value) */
153static VALUE
154vm_call0_body(rb_execution_context_t *ec, struct rb_calling_info *calling, const VALUE *argv)
155{
156 const struct rb_callinfo *ci = calling->ci;
157 const struct rb_callcache *cc = calling->cc;
158 VALUE ret;
159
160 switch (vm_cc_cme(cc)->def->type) {
161 case VM_METHOD_TYPE_ISEQ:
162 {
163 rb_control_frame_t *reg_cfp = ec->cfp;
164 int i;
165
166 CHECK_VM_STACK_OVERFLOW(reg_cfp, calling->argc + 1);
167 vm_check_canary(ec, reg_cfp->sp);
168
169 *reg_cfp->sp++ = calling->recv;
170 for (i = 0; i < calling->argc; i++) {
171 *reg_cfp->sp++ = argv[i];
172 }
173
174 vm_call_iseq_setup(ec, reg_cfp, calling);
175 VM_ENV_FLAGS_SET(ec->cfp->ep, VM_FRAME_FLAG_FINISH);
176 return vm_exec(ec, true); /* CHECK_INTS in this function */
177 }
178 case VM_METHOD_TYPE_NOTIMPLEMENTED:
179 case VM_METHOD_TYPE_CFUNC:
180 ret = vm_call0_cfunc(ec, calling, argv);
181 goto success;
182 case VM_METHOD_TYPE_ATTRSET:
183 if (calling->kw_splat &&
184 calling->argc > 0 &&
185 RB_TYPE_P(argv[calling->argc-1], T_HASH) &&
186 RHASH_EMPTY_P(argv[calling->argc-1])) {
187 calling->argc--;
188 }
189
190 rb_check_arity(calling->argc, 1, 1);
191 ret = rb_ivar_set(calling->recv, vm_cc_cme(cc)->def->body.attr.id, argv[0]);
192 goto success;
193 case VM_METHOD_TYPE_IVAR:
194 if (calling->kw_splat &&
195 calling->argc > 0 &&
196 RB_TYPE_P(argv[calling->argc-1], T_HASH) &&
197 RHASH_EMPTY_P(argv[calling->argc-1])) {
198 calling->argc--;
199 }
200
201 rb_check_arity(calling->argc, 0, 0);
202 ret = rb_attr_get(calling->recv, vm_cc_cme(cc)->def->body.attr.id);
203 goto success;
204 case VM_METHOD_TYPE_BMETHOD:
205 ret = vm_call_bmethod_body(ec, calling, argv);
206 goto success;
207 case VM_METHOD_TYPE_ZSUPER:
208 {
209 VALUE klass = RCLASS_ORIGIN(vm_cc_cme(cc)->defined_class);
210 return vm_call0_super(ec, calling, argv, klass, MISSING_SUPER);
211 }
212 case VM_METHOD_TYPE_REFINED:
213 {
214 const rb_callable_method_entry_t *cme = vm_cc_cme(cc);
215
216 if (cme->def->body.refined.orig_me) {
217 const rb_callable_method_entry_t *orig_cme = refined_method_callable_without_refinement(cme);
218 return vm_call0_cme(ec, calling, argv, orig_cme);
219 }
220
221 VALUE klass = cme->defined_class;
222 return vm_call0_super(ec, calling, argv, klass, 0);
223 }
224 case VM_METHOD_TYPE_ALIAS:
225 return vm_call0_cme(ec, calling, argv, aliased_callable_method_entry(vm_cc_cme(cc)));
226 case VM_METHOD_TYPE_MISSING:
227 {
228 vm_passed_block_handler_set(ec, calling->block_handler);
229 return method_missing(ec, calling->recv, vm_ci_mid(ci), calling->argc,
230 argv, MISSING_NOENTRY, calling->kw_splat);
231 }
232 case VM_METHOD_TYPE_OPTIMIZED:
233 switch (vm_cc_cme(cc)->def->body.optimize_type) {
234 case OPTIMIZED_METHOD_TYPE_SEND:
235 ret = send_internal(calling->argc, argv, calling->recv, calling->kw_splat ? CALL_FCALL_KW : CALL_FCALL);
236 goto success;
237 case OPTIMIZED_METHOD_TYPE_CALL:
238 {
239 rb_proc_t *proc;
240 GetProcPtr(calling->recv, proc);
241 ret = rb_vm_invoke_proc(ec, proc, calling->argc, argv, calling->kw_splat, calling->block_handler);
242 goto success;
243 }
244 default:
245 rb_bug("vm_call0: unsupported optimized method type (%d)", vm_cc_cme(cc)->def->body.optimize_type);
246 }
247 break;
248 case VM_METHOD_TYPE_UNDEF:
249 break;
250 }
251 rb_bug("vm_call0: unsupported method type (%d)", vm_cc_cme(cc)->def->type);
252 return Qundef;
253
254 success:
255 RUBY_VM_CHECK_INTS(ec);
256 return ret;
257}
258
259 MJIT_FUNC_EXPORTED VALUE
260 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)
261{
262 return rb_vm_call0(ec, recv, id, argc, argv, me, kw_splat);
263}
264
265static inline VALUE
266vm_call_super(rb_execution_context_t *ec, int argc, const VALUE *argv, int kw_splat)
267{
268 VALUE recv = ec->cfp->self;
269 VALUE klass;
270 ID id;
271 rb_control_frame_t *cfp = ec->cfp;
272 const rb_callable_method_entry_t *me = rb_vm_frame_method_entry(cfp);
273
274 if (VM_FRAME_RUBYFRAME_P(cfp)) {
275 rb_bug("vm_call_super: should not be reached");
276 }
277
278 klass = RCLASS_ORIGIN(me->defined_class);
279 klass = RCLASS_SUPER(klass);
280 id = me->def->original_id;
281 me = rb_callable_method_entry(klass, id);
282
283 if (!me) {
284 return method_missing(ec, recv, id, argc, argv, MISSING_SUPER, kw_splat);
285 }
286 return rb_vm_call_kw(ec, recv, id, argc, argv, me, kw_splat);
287}
288
289 VALUE
290 rb_call_super_kw(int argc, const VALUE *argv, int kw_splat)
291{
292 rb_execution_context_t *ec = GET_EC();
293 PASS_PASSED_BLOCK_HANDLER_EC(ec);
294 return vm_call_super(ec, argc, argv, kw_splat);
295}
296
297 VALUE
298 rb_call_super(int argc, const VALUE *argv)
299{
300 rb_execution_context_t *ec = GET_EC();
301 PASS_PASSED_BLOCK_HANDLER_EC(ec);
302 return vm_call_super(ec, argc, argv, RB_NO_KEYWORDS);
303}
304
305 VALUE
306 rb_current_receiver(void)
307{
308 const rb_execution_context_t *ec = GET_EC();
309 rb_control_frame_t *cfp;
310 if (!ec || !(cfp = ec->cfp)) {
311 rb_raise(rb_eRuntimeError, "no self, no life");
312 }
313 return cfp->self;
314}
315
316#endif /* #ifndef MJIT_HEADER */
317
318static inline void
319 stack_check(rb_execution_context_t *ec)
320{
321 if (!rb_ec_raised_p(ec, RAISED_STACKOVERFLOW) &&
322 rb_ec_stack_check(ec)) {
323 rb_ec_raised_set(ec, RAISED_STACKOVERFLOW);
324 rb_ec_stack_overflow(ec, FALSE);
325 }
326}
327
328#ifndef MJIT_HEADER
329
330void
331 rb_check_stack_overflow(void)
332{
333#ifndef RB_THREAD_LOCAL_SPECIFIER
334 if (!ruby_current_ec_key) return;
335#endif
336 rb_execution_context_t *ec = GET_EC();
337 if (ec) stack_check(ec);
338}
339
340 NORETURN(static void uncallable_object(VALUE recv, ID mid));
341static inline const rb_callable_method_entry_t *rb_search_method_entry(VALUE recv, ID mid);
342static inline enum method_missing_reason rb_method_call_status(rb_execution_context_t *ec, const rb_callable_method_entry_t *me, call_type scope, VALUE self);
343
344static const struct rb_callcache *
345cc_new(VALUE klass, ID mid, int argc, const rb_callable_method_entry_t *cme)
346{
347 const struct rb_callcache *cc;
348
349 RB_VM_LOCK_ENTER();
350 {
351 struct rb_class_cc_entries *ccs;
352 struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
353
354 if (rb_id_table_lookup(cc_tbl, mid, (VALUE*)&ccs)) {
355 // ok
356 }
357 else {
358 ccs = vm_ccs_create(klass, cme);
359 rb_id_table_insert(cc_tbl, mid, (VALUE)ccs);
360 }
361
362 if (ccs->len > 0) {
363 cc = ccs->entries[0].cc;
364 }
365 else {
366 const struct rb_callinfo *ci = vm_ci_new(mid, 0, argc, false); // TODO: proper ci
367 cc = vm_cc_new(klass, cme, vm_call_general);
368 METHOD_ENTRY_CACHED_SET((struct rb_callable_method_entry_struct *)cme);
369 vm_ccs_push(klass, ccs, ci, cc);
370 }
371 }
372 RB_VM_LOCK_LEAVE();
373
374 return cc;
375}
376
377static VALUE
378gccct_hash(VALUE klass, ID mid)
379{
380 return (klass >> 3) ^ (VALUE)mid;
381}
382
383 NOINLINE(static const struct rb_callcache *gccct_method_search_slowpath(rb_vm_t *vm, VALUE klass, ID mid, int argc, unsigned int index));
384
385static const struct rb_callcache *
386gccct_method_search_slowpath(rb_vm_t *vm, VALUE klass, ID mid, int argc, unsigned int index)
387{
388 const rb_callable_method_entry_t *cme = rb_callable_method_entry(klass, mid);
389 const struct rb_callcache *cc;
390
391 if (cme != NULL) {
392 cc = cc_new(klass, mid, argc, cme);
393 }
394 else {
395 cc = NULL;
396 }
397
398 return vm->global_cc_cache_table[index] = cc;
399}
400
401static inline const struct rb_callcache *
402gccct_method_search(rb_execution_context_t *ec, VALUE recv, ID mid, int argc)
403{
404 VALUE klass;
405
406 if (!SPECIAL_CONST_P(recv)) {
407 klass = RBASIC_CLASS(recv);
408 if (UNLIKELY(!klass)) uncallable_object(recv, mid);
409 }
410 else {
411 klass = CLASS_OF(recv);
412 }
413
414 // search global method cache
415 unsigned int index = (unsigned int)(gccct_hash(klass, mid) % VM_GLOBAL_CC_CACHE_TABLE_SIZE);
416 rb_vm_t *vm = rb_ec_vm_ptr(ec);
417 const struct rb_callcache *cc = vm->global_cc_cache_table[index];
418
419 if (LIKELY(cc)) {
420 if (LIKELY(vm_cc_class_check(cc, klass))) {
421 const rb_callable_method_entry_t *cme = vm_cc_cme(cc);
422 if (LIKELY(!METHOD_ENTRY_INVALIDATED(cme) &&
423 cme->called_id == mid)) {
424
425 VM_ASSERT(vm_cc_cme(cc) == rb_callable_method_entry(klass, mid));
426 RB_DEBUG_COUNTER_INC(gccct_hit);
427
428 return cc;
429 }
430 }
431 }
432 else {
433 RB_DEBUG_COUNTER_INC(gccct_null);
434 }
435
436 RB_DEBUG_COUNTER_INC(gccct_miss);
437 return gccct_method_search_slowpath(vm, klass, mid, argc, index);
438}
439
456static inline VALUE
457rb_call0(rb_execution_context_t *ec,
458 VALUE recv, ID mid, int argc, const VALUE *argv,
459 call_type call_scope, VALUE self)
460{
461 enum method_missing_reason call_status;
462 call_type scope = call_scope;
463 int kw_splat = RB_NO_KEYWORDS;
464
465 switch(scope) {
466 case(CALL_PUBLIC_KW):
467 scope = CALL_PUBLIC;
468 kw_splat = 1;
469 break;
470 case(CALL_FCALL_KW):
471 scope = CALL_FCALL;
472 kw_splat = 1;
473 break;
474 default:
475 break;
476 }
477
478 const struct rb_callcache *cc = gccct_method_search(ec, recv, mid, argc);
479
480 if (scope == CALL_PUBLIC) {
481 RB_DEBUG_COUNTER_INC(call0_public);
482
483 const rb_callable_method_entry_t *cc_cme = cc ? vm_cc_cme(cc) : NULL;
484 const rb_callable_method_entry_t *cme = callable_method_entry_refeinements0(CLASS_OF(recv), mid, NULL, true, cc_cme);
485 call_status = rb_method_call_status(ec, cme, scope, self);
486
487 if (UNLIKELY(call_status != MISSING_NONE)) {
488 return method_missing(ec, recv, mid, argc, argv, call_status, kw_splat);
489 }
490 else if (UNLIKELY(cc_cme != cme)) { // refinement is solved
491 stack_check(ec);
492 return rb_vm_call_kw(ec, recv, mid, argc, argv, cme, kw_splat);
493 }
494 }
495 else {
496 RB_DEBUG_COUNTER_INC(call0_other);
497 call_status = rb_method_call_status(ec, cc ? vm_cc_cme(cc) : NULL, scope, self);
498
499 if (UNLIKELY(call_status != MISSING_NONE)) {
500 return method_missing(ec, recv, mid, argc, argv, call_status, kw_splat);
501 }
502 }
503
504 stack_check(ec);
505 return vm_call0_cc(ec, recv, mid, argc, argv, cc, kw_splat);
506}
507
508 struct rescue_funcall_args {
509 VALUE defined_class;
510 VALUE recv;
511 ID mid;
512 rb_execution_context_t *ec;
513 const rb_callable_method_entry_t *cme;
514 unsigned int respond: 1;
515 unsigned int respond_to_missing: 1;
516 int argc;
517 const VALUE *argv;
518 int kw_splat;
519};
520
521static VALUE
522check_funcall_exec(VALUE v)
523{
524 struct rescue_funcall_args *args = (void *)v;
525 return call_method_entry(args->ec, args->defined_class,
526 args->recv, idMethodMissing,
527 args->cme, args->argc, args->argv, args->kw_splat);
528}
529
530static VALUE
531check_funcall_failed(VALUE v, VALUE e)
532{
533 struct rescue_funcall_args *args = (void *)v;
534 int ret = args->respond;
535 if (!ret) {
536 switch (method_boundp(args->defined_class, args->mid,
537 BOUND_PRIVATE|BOUND_RESPONDS)) {
538 case 2:
539 ret = TRUE;
540 break;
541 case 0:
542 ret = args->respond_to_missing;
543 break;
544 default:
545 ret = FALSE;
546 break;
547 }
548 }
549 if (ret) {
550 rb_exc_raise(e);
551 }
552 return Qundef;
553}
554
555static int
556check_funcall_respond_to(rb_execution_context_t *ec, VALUE klass, VALUE recv, ID mid)
557{
558 return vm_respond_to(ec, klass, recv, mid, TRUE);
559}
560
561static int
562check_funcall_callable(rb_execution_context_t *ec, const rb_callable_method_entry_t *me)
563{
564 return rb_method_call_status(ec, me, CALL_FCALL, ec->cfp->self) == MISSING_NONE;
565}
566
567static VALUE
568check_funcall_missing(rb_execution_context_t *ec, VALUE klass, VALUE recv, ID mid, int argc, const VALUE *argv, int respond, VALUE def, int kw_splat)
569{
570 struct rescue_funcall_args args;
571 const rb_callable_method_entry_t *cme;
572 VALUE ret = Qundef;
573
574 ret = basic_obj_respond_to_missing(ec, klass, recv,
575 ID2SYM(mid), Qtrue);
576 if (!RTEST(ret)) return def;
577 args.respond = respond > 0;
578 args.respond_to_missing = (ret != Qundef);
579 ret = def;
580 cme = callable_method_entry(klass, idMethodMissing, &args.defined_class);
581
582 if (cme && !METHOD_ENTRY_BASIC(cme)) {
583 VALUE argbuf, *new_args = ALLOCV_N(VALUE, argbuf, argc+1);
584
585 new_args[0] = ID2SYM(mid);
586 #ifdef __GLIBC__
587 if (!argv) {
588 static const VALUE buf = Qfalse;
589 VM_ASSERT(argc == 0);
590 argv = &buf;
591 }
592 #endif
593 MEMCPY(new_args+1, argv, VALUE, argc);
594 ec->method_missing_reason = MISSING_NOENTRY;
595 args.ec = ec;
596 args.recv = recv;
597 args.cme = cme;
598 args.mid = mid;
599 args.argc = argc + 1;
600 args.argv = new_args;
601 args.kw_splat = kw_splat;
602 ret = rb_rescue2(check_funcall_exec, (VALUE)&args,
603 check_funcall_failed, (VALUE)&args,
604 rb_eNoMethodError, (VALUE)0);
605 ALLOCV_END(argbuf);
606 }
607 return ret;
608}
609
610static VALUE rb_check_funcall_default_kw(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE def, int kw_splat);
611
612 VALUE
613 rb_check_funcall_kw(VALUE recv, ID mid, int argc, const VALUE *argv, int kw_splat)
614{
615 return rb_check_funcall_default_kw(recv, mid, argc, argv, Qundef, kw_splat);
616}
617
618 VALUE
619 rb_check_funcall(VALUE recv, ID mid, int argc, const VALUE *argv)
620{
621 return rb_check_funcall_default_kw(recv, mid, argc, argv, Qundef, RB_NO_KEYWORDS);
622}
623
624static VALUE
625rb_check_funcall_default_kw(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE def, int kw_splat)
626{
627 VALUE klass = CLASS_OF(recv);
628 const rb_callable_method_entry_t *me;
629 rb_execution_context_t *ec = GET_EC();
630 int respond = check_funcall_respond_to(ec, klass, recv, mid);
631
632 if (!respond)
633 return def;
634
635 me = rb_search_method_entry(recv, mid);
636 if (!check_funcall_callable(ec, me)) {
637 VALUE ret = check_funcall_missing(ec, klass, recv, mid, argc, argv,
638 respond, def, kw_splat);
639 if (ret == Qundef) ret = def;
640 return ret;
641 }
642 stack_check(ec);
643 return rb_vm_call_kw(ec, recv, mid, argc, argv, me, kw_splat);
644}
645
646 VALUE
647 rb_check_funcall_default(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE def)
648{
649 return rb_check_funcall_default_kw(recv, mid, argc, argv, def, RB_NO_KEYWORDS);
650}
651
652 VALUE
653 rb_check_funcall_with_hook_kw(VALUE recv, ID mid, int argc, const VALUE *argv,
654 rb_check_funcall_hook *hook, VALUE arg, int kw_splat)
655{
656 VALUE klass = CLASS_OF(recv);
657 const rb_callable_method_entry_t *me;
658 rb_execution_context_t *ec = GET_EC();
659 int respond = check_funcall_respond_to(ec, klass, recv, mid);
660
661 if (!respond) {
662 (*hook)(FALSE, recv, mid, argc, argv, arg);
663 return Qundef;
664 }
665
666 me = rb_search_method_entry(recv, mid);
667 if (!check_funcall_callable(ec, me)) {
668 VALUE ret = check_funcall_missing(ec, klass, recv, mid, argc, argv,
669 respond, Qundef, kw_splat);
670 (*hook)(ret != Qundef, recv, mid, argc, argv, arg);
671 return ret;
672 }
673 stack_check(ec);
674 (*hook)(TRUE, recv, mid, argc, argv, arg);
675 return rb_vm_call_kw(ec, recv, mid, argc, argv, me, kw_splat);
676}
677
678 VALUE
679 rb_check_funcall_with_hook(VALUE recv, ID mid, int argc, const VALUE *argv,
680 rb_check_funcall_hook *hook, VALUE arg)
681{
682 return rb_check_funcall_with_hook_kw(recv, mid, argc, argv, hook, arg, RB_NO_KEYWORDS);
683}
684
685const char *
686 rb_type_str(enum ruby_value_type type)
687{
688#define type_case(t) t: return #t
689 switch (type) {
690 case type_case(T_NONE);
691 case type_case(T_OBJECT);
692 case type_case(T_CLASS);
693 case type_case(T_MODULE);
694 case type_case(T_FLOAT);
695 case type_case(T_STRING);
696 case type_case(T_REGEXP);
697 case type_case(T_ARRAY);
698 case type_case(T_HASH);
699 case type_case(T_STRUCT);
700 case type_case(T_BIGNUM);
701 case type_case(T_FILE);
702 case type_case(T_DATA);
703 case type_case(T_MATCH);
704 case type_case(T_COMPLEX);
705 case type_case(T_RATIONAL);
706 case type_case(T_NIL);
707 case type_case(T_TRUE);
708 case type_case(T_FALSE);
709 case type_case(T_SYMBOL);
710 case type_case(T_FIXNUM);
711 case type_case(T_IMEMO);
712 case type_case(T_UNDEF);
713 case type_case(T_NODE);
714 case type_case(T_ICLASS);
715 case type_case(T_ZOMBIE);
716 case type_case(T_MOVED);
717 case T_MASK: break;
718 }
719#undef type_case
720 return NULL;
721}
722
723static void
724uncallable_object(VALUE recv, ID mid)
725{
726 VALUE flags;
727 int type;
728 const char *typestr;
729 VALUE mname = rb_id2str(mid);
730
731 if (SPECIAL_CONST_P(recv)) {
732 rb_raise(rb_eNotImpError,
733 "method `%"PRIsVALUE"' called on unexpected immediate object (%p)",
734 mname, (void *)recv);
735 }
736 else if ((flags = RBASIC(recv)->flags) == 0) {
737 rb_raise(rb_eNotImpError,
738 "method `%"PRIsVALUE"' called on terminated object (%p)",
739 mname, (void *)recv);
740 }
741 else if (!(typestr = rb_type_str(type = BUILTIN_TYPE(recv)))) {
742 rb_raise(rb_eNotImpError,
743 "method `%"PRIsVALUE"' called on broken T_?""?""?(0x%02x) object"
744 " (%p flags=0x%"PRIxVALUE")",
745 mname, type, (void *)recv, flags);
746 }
747 else if (T_OBJECT <= type && type < T_NIL) {
748 rb_raise(rb_eNotImpError,
749 "method `%"PRIsVALUE"' called on hidden %s object"
750 " (%p flags=0x%"PRIxVALUE")",
751 mname, typestr, (void *)recv, flags);
752 }
753 else {
754 rb_raise(rb_eNotImpError,
755 "method `%"PRIsVALUE"' called on unexpected %s object"
756 " (%p flags=0x%"PRIxVALUE")",
757 mname, typestr, (void *)recv, flags);
758 }
759}
760
761static inline const rb_callable_method_entry_t *
762rb_search_method_entry(VALUE recv, ID mid)
763{
764 VALUE klass = CLASS_OF(recv);
765
766 if (!klass) uncallable_object(recv, mid);
767 return rb_callable_method_entry(klass, mid);
768}
769
770static inline enum method_missing_reason
771rb_method_call_status(rb_execution_context_t *ec, const rb_callable_method_entry_t *me, call_type scope, VALUE self)
772{
773 VALUE klass;
774 ID oid;
775 rb_method_visibility_t visi;
776
777 if (UNDEFINED_METHOD_ENTRY_P(me)) {
778 goto undefined;
779 }
780 if (me->def->type == VM_METHOD_TYPE_REFINED) {
781 me = rb_resolve_refined_method_callable(Qnil, me);
782 if (UNDEFINED_METHOD_ENTRY_P(me)) goto undefined;
783 }
784
785 klass = me->owner;
786 oid = me->def->original_id;
787 visi = METHOD_ENTRY_VISI(me);
788
789 if (oid != idMethodMissing) {
790 /* receiver specified form for private method */
791 if (UNLIKELY(visi != METHOD_VISI_PUBLIC)) {
792 if (visi == METHOD_VISI_PRIVATE && scope == CALL_PUBLIC) {
793 return MISSING_PRIVATE;
794 }
795
796 /* self must be kind of a specified form for protected method */
797 if (visi == METHOD_VISI_PROTECTED && scope == CALL_PUBLIC) {
798 VALUE defined_class = klass;
799
800 if (RB_TYPE_P(defined_class, T_ICLASS)) {
801 defined_class = RBASIC(defined_class)->klass;
802 }
803
804 if (self == Qundef || !rb_obj_is_kind_of(self, defined_class)) {
805 return MISSING_PROTECTED;
806 }
807 }
808 }
809 }
810
811 return MISSING_NONE;
812 undefined:
813 return scope == CALL_VCALL ? MISSING_VCALL : MISSING_NOENTRY;
814}
815
816
828static inline VALUE
829rb_call(VALUE recv, ID mid, int argc, const VALUE *argv, call_type scope)
830{
831 rb_execution_context_t *ec = GET_EC();
832 return rb_call0(ec, recv, mid, argc, argv, scope, ec->cfp->self);
833}
834
835 NORETURN(static void raise_method_missing(rb_execution_context_t *ec, int argc, const VALUE *argv,
836 VALUE obj, enum method_missing_reason call_status));
837
838/*
839 * call-seq:
840 * obj.method_missing(symbol [, *args] ) -> result
841 *
842 * Invoked by Ruby when <i>obj</i> is sent a message it cannot handle.
843 * <i>symbol</i> is the symbol for the method called, and <i>args</i>
844 * are any arguments that were passed to it. By default, the interpreter
845 * raises an error when this method is called. However, it is possible
846 * to override the method to provide more dynamic behavior.
847 * If it is decided that a particular method should not be handled, then
848 * <i>super</i> should be called, so that ancestors can pick up the
849 * missing method.
850 * The example below creates
851 * a class <code>Roman</code>, which responds to methods with names
852 * consisting of roman numerals, returning the corresponding integer
853 * values.
854 *
855 * class Roman
856 * def roman_to_int(str)
857 * # ...
858 * end
859 *
860 * def method_missing(symbol, *args)
861 * str = symbol.id2name
862 * begin
863 * roman_to_int(str)
864 * rescue
865 * super(symbol, *args)
866 * end
867 * end
868 * end
869 *
870 * r = Roman.new
871 * r.iv #=> 4
872 * r.xxiii #=> 23
873 * r.mm #=> 2000
874 * r.foo #=> NoMethodError
875 */
876
877static VALUE
878rb_method_missing(int argc, const VALUE *argv, VALUE obj)
879{
880 rb_execution_context_t *ec = GET_EC();
881 raise_method_missing(ec, argc, argv, obj, ec->method_missing_reason);
882 UNREACHABLE_RETURN(Qnil);
883}
884
885 MJIT_FUNC_EXPORTED VALUE
886rb_make_no_method_exception(VALUE exc, VALUE format, VALUE obj,
887 int argc, const VALUE *argv, int priv)
888{
889 VALUE name = argv[0];
890
891 if (!format) {
892 format = rb_fstring_lit("undefined method `%s' for %s%s%s");
893 }
894 if (exc == rb_eNoMethodError) {
895 VALUE args = rb_ary_new4(argc - 1, argv + 1);
896 return rb_nomethod_err_new(format, obj, name, args, priv);
897 }
898 else {
899 return rb_name_err_new(format, obj, name);
900 }
901}
902
903#endif /* #ifndef MJIT_HEADER */
904
905static void
906raise_method_missing(rb_execution_context_t *ec, int argc, const VALUE *argv, VALUE obj,
907 enum method_missing_reason last_call_status)
908{
909 VALUE exc = rb_eNoMethodError;
910 VALUE format = 0;
911
912 if (UNLIKELY(argc == 0)) {
913 rb_raise(rb_eArgError, "no method name given");
914 }
915 else if (UNLIKELY(!SYMBOL_P(argv[0]))) {
916 const VALUE e = rb_eArgError; /* TODO: TypeError? */
917 rb_raise(e, "method name must be a Symbol but %"PRIsVALUE" is given",
918 rb_obj_class(argv[0]));
919 }
920
921 stack_check(ec);
922
923 if (last_call_status & MISSING_PRIVATE) {
924 format = rb_fstring_lit("private method `%s' called for %s%s%s");
925 }
926 else if (last_call_status & MISSING_PROTECTED) {
927 format = rb_fstring_lit("protected method `%s' called for %s%s%s");
928 }
929 else if (last_call_status & MISSING_VCALL) {
930 format = rb_fstring_lit("undefined local variable or method `%s' for %s%s%s");
931 exc = rb_eNameError;
932 }
933 else if (last_call_status & MISSING_SUPER) {
934 format = rb_fstring_lit("super: no superclass method `%s' for %s%s%s");
935 }
936
937 {
938 exc = rb_make_no_method_exception(exc, format, obj, argc, argv,
939 last_call_status & (MISSING_FCALL|MISSING_VCALL));
940 if (!(last_call_status & MISSING_MISSING)) {
941 rb_vm_pop_cfunc_frame();
942 }
943 rb_exc_raise(exc);
944 }
945}
946
947static void
948vm_raise_method_missing(rb_execution_context_t *ec, int argc, const VALUE *argv,
949 VALUE obj, int call_status)
950{
951 vm_passed_block_handler_set(ec, VM_BLOCK_HANDLER_NONE);
952 raise_method_missing(ec, argc, argv, obj, call_status | MISSING_MISSING);
953}
954
955static inline VALUE
956method_missing(rb_execution_context_t *ec, VALUE obj, ID id, int argc, const VALUE *argv, enum method_missing_reason call_status, int kw_splat)
957{
958 VALUE *nargv, result, work, klass;
959 VALUE block_handler = vm_passed_block_handler(ec);
960 const rb_callable_method_entry_t *me;
961
962 ec->method_missing_reason = call_status;
963
964 if (id == idMethodMissing) {
965 goto missing;
966 }
967
968 nargv = ALLOCV_N(VALUE, work, argc + 1);
969 nargv[0] = ID2SYM(id);
970 #ifdef __GLIBC__
971 if (!argv) {
972 static const VALUE buf = Qfalse;
973 VM_ASSERT(argc == 0);
974 argv = &buf;
975 }
976 #endif
977 MEMCPY(nargv + 1, argv, VALUE, argc);
978 ++argc;
979 argv = nargv;
980
981 klass = CLASS_OF(obj);
982 if (!klass) goto missing;
983 me = rb_callable_method_entry(klass, idMethodMissing);
984 if (!me || METHOD_ENTRY_BASIC(me)) goto missing;
985 vm_passed_block_handler_set(ec, block_handler);
986 result = rb_vm_call_kw(ec, obj, idMethodMissing, argc, argv, me, kw_splat);
987 if (work) ALLOCV_END(work);
988 return result;
989 missing:
990 raise_method_missing(ec, argc, argv, obj, call_status | MISSING_MISSING);
991 UNREACHABLE_RETURN(Qundef);
992}
993
994#ifndef MJIT_HEADER
995
996static inline VALUE
997rb_funcallv_scope(VALUE recv, ID mid, int argc, const VALUE *argv, call_type scope)
998{
999 rb_execution_context_t *ec = GET_EC();
1000 const struct rb_callcache *cc = gccct_method_search(ec, recv, mid, argc);
1001 VALUE self = ec->cfp->self;
1002
1003 if (LIKELY(cc) &&
1004 LIKELY(rb_method_call_status(ec, vm_cc_cme(cc), scope, self) == MISSING_NONE)) {
1005 // fastpath
1006 return vm_call0_cc(ec, recv, mid, argc, argv, cc, false);
1007 }
1008 else {
1009 return rb_call0(ec, recv, mid, argc, argv, scope, self);
1010 }
1011}
1012
1013#ifdef rb_funcallv
1014#undef rb_funcallv
1015#endif
1023 VALUE
1024 rb_funcallv(VALUE recv, ID mid, int argc, const VALUE *argv)
1025{
1026 return rb_funcallv_scope(recv, mid, argc, argv, CALL_FCALL);
1027}
1028
1029 VALUE
1030 rb_funcallv_kw(VALUE recv, ID mid, int argc, const VALUE *argv, int kw_splat)
1031{
1032 return rb_call(recv, mid, argc, argv, kw_splat ? CALL_FCALL_KW : CALL_FCALL);
1033}
1034
1043 VALUE
1044 rb_apply(VALUE recv, ID mid, VALUE args)
1045{
1046 int argc;
1047 VALUE *argv, ret;
1048
1049 argc = RARRAY_LENINT(args);
1050 if (argc >= 0x100) {
1051 args = rb_ary_subseq(args, 0, argc);
1052 RBASIC_CLEAR_CLASS(args);
1053 OBJ_FREEZE(args);
1054 ret = rb_call(recv, mid, argc, RARRAY_CONST_PTR(args), CALL_FCALL);
1055 RB_GC_GUARD(args);
1056 return ret;
1057 }
1058 argv = ALLOCA_N(VALUE, argc);
1059 MEMCPY(argv, RARRAY_CONST_PTR_TRANSIENT(args), VALUE, argc);
1060
1061 return rb_funcallv(recv, mid, argc, argv);
1062}
1063
1064#ifdef rb_funcall
1065#undef rb_funcall
1066#endif
1076 VALUE
1077 rb_funcall(VALUE recv, ID mid, int n, ...)
1078{
1079 VALUE *argv;
1080 va_list ar;
1081
1082 if (n > 0) {
1083 long i;
1084
1085 va_start(ar, n);
1086
1087 argv = ALLOCA_N(VALUE, n);
1088
1089 for (i = 0; i < n; i++) {
1090 argv[i] = va_arg(ar, VALUE);
1091 }
1092 va_end(ar);
1093 }
1094 else {
1095 argv = 0;
1096 }
1097 return rb_funcallv(recv, mid, n, argv);
1098}
1099
1110 VALUE
1111 rb_check_funcall_basic_kw(VALUE recv, ID mid, VALUE ancestor, int argc, const VALUE *argv, int kw_splat)
1112{
1113 const rb_callable_method_entry_t *cme;
1114 rb_execution_context_t *ec;
1115 VALUE klass = CLASS_OF(recv);
1116 if (!klass) return Qundef; /* hidden object */
1117
1118 cme = rb_callable_method_entry(klass, mid);
1119 if (cme && METHOD_ENTRY_BASIC(cme) && RBASIC_CLASS(cme->defined_class) == ancestor) {
1120 ec = GET_EC();
1121 return rb_vm_call0(ec, recv, mid, argc, argv, cme, kw_splat);
1122 }
1123
1124 return Qundef;
1125}
1126
1136 VALUE
1137 rb_funcallv_public(VALUE recv, ID mid, int argc, const VALUE *argv)
1138{
1139 return rb_funcallv_scope(recv, mid, argc, argv, CALL_PUBLIC);
1140}
1141
1142 VALUE
1143 rb_funcallv_public_kw(VALUE recv, ID mid, int argc, const VALUE *argv, int kw_splat)
1144{
1145 return rb_call(recv, mid, argc, argv, kw_splat ? CALL_PUBLIC_KW : CALL_PUBLIC);
1146}
1147
1148 VALUE
1149 rb_funcall_passing_block(VALUE recv, ID mid, int argc, const VALUE *argv)
1150{
1151 PASS_PASSED_BLOCK_HANDLER();
1152 return rb_funcallv_public(recv, mid, argc, argv);
1153}
1154
1155 VALUE
1156 rb_funcall_passing_block_kw(VALUE recv, ID mid, int argc, const VALUE *argv, int kw_splat)
1157{
1158 PASS_PASSED_BLOCK_HANDLER();
1159 return rb_call(recv, mid, argc, argv, kw_splat ? CALL_PUBLIC_KW : CALL_PUBLIC);
1160}
1161
1162 VALUE
1163 rb_funcall_with_block(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE passed_procval)
1164{
1165 if (!NIL_P(passed_procval)) {
1166 vm_passed_block_handler_set(GET_EC(), passed_procval);
1167 }
1168
1169 return rb_funcallv_public(recv, mid, argc, argv);
1170}
1171
1172 VALUE
1173 rb_funcall_with_block_kw(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE passed_procval, int kw_splat)
1174{
1175 if (!NIL_P(passed_procval)) {
1176 vm_passed_block_handler_set(GET_EC(), passed_procval);
1177 }
1178
1179 return rb_call(recv, mid, argc, argv, kw_splat ? CALL_PUBLIC_KW : CALL_PUBLIC);
1180}
1181
1182static VALUE *
1183current_vm_stack_arg(const rb_execution_context_t *ec, const VALUE *argv)
1184{
1185 rb_control_frame_t *prev_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(ec->cfp);
1186 if (RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(ec, prev_cfp)) return NULL;
1187 if (prev_cfp->sp + 1 != argv) return NULL;
1188 return prev_cfp->sp + 1;
1189}
1190
1191static VALUE
1192send_internal(int argc, const VALUE *argv, VALUE recv, call_type scope)
1193{
1194 ID id;
1195 VALUE vid;
1196 VALUE self;
1197 VALUE ret, vargv = 0;
1198 rb_execution_context_t *ec = GET_EC();
1199 int public = scope == CALL_PUBLIC || scope == CALL_PUBLIC_KW;
1200
1201 if (public) {
1202 self = Qundef;
1203 }
1204 else {
1205 self = RUBY_VM_PREVIOUS_CONTROL_FRAME(ec->cfp)->self;
1206 }
1207
1208 if (argc == 0) {
1209 rb_raise(rb_eArgError, "no method name given");
1210 }
1211
1212 vid = *argv;
1213
1214 id = rb_check_id(&vid);
1215 if (!id) {
1216 if (rb_method_basic_definition_p(CLASS_OF(recv), idMethodMissing)) {
1217 VALUE exc = rb_make_no_method_exception(rb_eNoMethodError, 0,
1218 recv, argc, argv,
1219 !public);
1220 rb_exc_raise(exc);
1221 }
1222 if (!SYMBOL_P(*argv)) {
1223 VALUE *tmp_argv = current_vm_stack_arg(ec, argv);
1224 vid = rb_str_intern(vid);
1225 if (tmp_argv) {
1226 tmp_argv[0] = vid;
1227 }
1228 else if (argc > 1) {
1229 tmp_argv = ALLOCV_N(VALUE, vargv, argc);
1230 tmp_argv[0] = vid;
1231 MEMCPY(tmp_argv+1, argv+1, VALUE, argc-1);
1232 argv = tmp_argv;
1233 }
1234 else {
1235 argv = &vid;
1236 }
1237 }
1238 id = idMethodMissing;
1239 ec->method_missing_reason = MISSING_NOENTRY;
1240 }
1241 else {
1242 argv++; argc--;
1243 }
1244 PASS_PASSED_BLOCK_HANDLER_EC(ec);
1245 ret = rb_call0(ec, recv, id, argc, argv, scope, self);
1246 ALLOCV_END(vargv);
1247 return ret;
1248}
1249
1250static VALUE
1251send_internal_kw(int argc, const VALUE *argv, VALUE recv, call_type scope)
1252{
1253 if (rb_keyword_given_p()) {
1254 switch (scope) {
1255 case CALL_PUBLIC:
1256 scope = CALL_PUBLIC_KW;
1257 break;
1258 case CALL_FCALL:
1259 scope = CALL_FCALL_KW;
1260 break;
1261 default:
1262 break;
1263 }
1264 }
1265 return send_internal(argc, argv, recv, scope);
1266}
1267
1268/*
1269 * call-seq:
1270 * foo.send(symbol [, args...]) -> obj
1271 * foo.__send__(symbol [, args...]) -> obj
1272 * foo.send(string [, args...]) -> obj
1273 * foo.__send__(string [, args...]) -> obj
1274 *
1275 * Invokes the method identified by _symbol_, passing it any
1276 * arguments specified.
1277 * When the method is identified by a string, the string is converted
1278 * to a symbol.
1279 *
1280 * BasicObject implements +__send__+, Kernel implements +send+.
1281 * <code>__send__</code> is safer than +send+
1282 * when _obj_ has the same method name like <code>Socket</code>.
1283 * See also <code>public_send</code>.
1284 *
1285 * class Klass
1286 * def hello(*args)
1287 * "Hello " + args.join(' ')
1288 * end
1289 * end
1290 * k = Klass.new
1291 * k.send :hello, "gentle", "readers" #=> "Hello gentle readers"
1292 */
1293
1294 VALUE
1295 rb_f_send(int argc, VALUE *argv, VALUE recv)
1296{
1297 return send_internal_kw(argc, argv, recv, CALL_FCALL);
1298}
1299
1300/*
1301 * call-seq:
1302 * obj.public_send(symbol [, args...]) -> obj
1303 * obj.public_send(string [, args...]) -> obj
1304 *
1305 * Invokes the method identified by _symbol_, passing it any
1306 * arguments specified. Unlike send, public_send calls public
1307 * methods only.
1308 * When the method is identified by a string, the string is converted
1309 * to a symbol.
1310 *
1311 * 1.public_send(:puts, "hello") # causes NoMethodError
1312 */
1313
1314static VALUE
1315rb_f_public_send(int argc, VALUE *argv, VALUE recv)
1316{
1317 return send_internal_kw(argc, argv, recv, CALL_PUBLIC);
1318}
1319
1320/* yield */
1321
1322static inline VALUE
1323rb_yield_0_kw(int argc, const VALUE * argv, int kw_splat)
1324{
1325 return vm_yield(GET_EC(), argc, argv, kw_splat);
1326}
1327
1328static inline VALUE
1329rb_yield_0(int argc, const VALUE * argv)
1330{
1331 return vm_yield(GET_EC(), argc, argv, RB_NO_KEYWORDS);
1332}
1333
1334 VALUE
1335 rb_yield_1(VALUE val)
1336{
1337 return rb_yield_0(1, &val);
1338}
1339
1340 VALUE
1341 rb_yield(VALUE val)
1342{
1343 if (val == Qundef) {
1344 return rb_yield_0(0, NULL);
1345 }
1346 else {
1347 return rb_yield_0(1, &val);
1348 }
1349}
1350
1351#undef rb_yield_values
1352 VALUE
1353 rb_yield_values(int n, ...)
1354{
1355 if (n == 0) {
1356 return rb_yield_0(0, 0);
1357 }
1358 else {
1359 int i;
1360 VALUE *argv;
1361 va_list args;
1362 argv = ALLOCA_N(VALUE, n);
1363
1364 va_start(args, n);
1365 for (i=0; i<n; i++) {
1366 argv[i] = va_arg(args, VALUE);
1367 }
1368 va_end(args);
1369
1370 return rb_yield_0(n, argv);
1371 }
1372}
1373
1374 VALUE
1375 rb_yield_values2(int argc, const VALUE *argv)
1376{
1377 return rb_yield_0(argc, argv);
1378}
1379
1380 VALUE
1381 rb_yield_values_kw(int argc, const VALUE *argv, int kw_splat)
1382{
1383 return rb_yield_0_kw(argc, argv, kw_splat);
1384}
1385
1386 VALUE
1387 rb_yield_splat(VALUE values)
1388{
1389 VALUE tmp = rb_check_array_type(values);
1390 VALUE v;
1391 if (NIL_P(tmp)) {
1392 rb_raise(rb_eArgError, "not an array");
1393 }
1394 v = rb_yield_0(RARRAY_LENINT(tmp), RARRAY_CONST_PTR(tmp));
1395 RB_GC_GUARD(tmp);
1396 return v;
1397}
1398
1399 VALUE
1400 rb_yield_splat_kw(VALUE values, int kw_splat)
1401{
1402 VALUE tmp = rb_check_array_type(values);
1403 VALUE v;
1404 if (NIL_P(tmp)) {
1405 rb_raise(rb_eArgError, "not an array");
1406 }
1407 v = rb_yield_0_kw(RARRAY_LENINT(tmp), RARRAY_CONST_PTR(tmp), kw_splat);
1408 RB_GC_GUARD(tmp);
1409 return v;
1410}
1411
1412 VALUE
1413 rb_yield_force_blockarg(VALUE values)
1414{
1415 return vm_yield_force_blockarg(GET_EC(), values);
1416}
1417
1418 VALUE
1419rb_yield_block(RB_BLOCK_CALL_FUNC_ARGLIST(val, arg))
1420{
1421 return vm_yield_with_block(GET_EC(), argc, argv,
1422 NIL_P(blockarg) ? VM_BLOCK_HANDLER_NONE : blockarg,
1423 rb_keyword_given_p());
1424}
1425
1426static VALUE
1427loop_i(VALUE _)
1428{
1429 for (;;) {
1430 rb_yield_0(0, 0);
1431 }
1432 return Qnil;
1433}
1434
1435static VALUE
1436loop_stop(VALUE dummy, VALUE exc)
1437{
1438 return rb_attr_get(exc, id_result);
1439}
1440
1441static VALUE
1442rb_f_loop_size(VALUE self, VALUE args, VALUE eobj)
1443{
1444 return DBL2NUM(HUGE_VAL);
1445}
1446
1447/*
1448 * call-seq:
1449 * loop { block }
1450 * loop -> an_enumerator
1451 *
1452 * Repeatedly executes the block.
1453 *
1454 * If no block is given, an enumerator is returned instead.
1455 *
1456 * loop do
1457 * print "Input: "
1458 * line = gets
1459 * break if !line or line =~ /^qQ/
1460 * # ...
1461 * end
1462 *
1463 * StopIteration raised in the block breaks the loop. In this case,
1464 * loop returns the "result" value stored in the exception.
1465 *
1466 * enum = Enumerator.new { |y|
1467 * y << "one"
1468 * y << "two"
1469 * :ok
1470 * }
1471 *
1472 * result = loop {
1473 * puts enum.next
1474 * } #=> :ok
1475 */
1476
1477static VALUE
1478rb_f_loop(VALUE self)
1479{
1480 RETURN_SIZED_ENUMERATOR(self, 0, 0, rb_f_loop_size);
1481 return rb_rescue2(loop_i, (VALUE)0, loop_stop, (VALUE)0, rb_eStopIteration, (VALUE)0);
1482}
1483
1484#if VMDEBUG
1485static const char *
1486vm_frametype_name(const rb_control_frame_t *cfp);
1487#endif
1488
1489static VALUE
1490rb_iterate0(VALUE (* it_proc) (VALUE), VALUE data1,
1491 const struct vm_ifunc *const ifunc,
1492 rb_execution_context_t *ec)
1493{
1494 enum ruby_tag_type state;
1495 volatile VALUE retval = Qnil;
1496 rb_control_frame_t *const cfp = ec->cfp;
1497
1498 EC_PUSH_TAG(ec);
1499 state = EC_EXEC_TAG();
1500 if (state == 0) {
1501 iter_retry:
1502 {
1503 VALUE block_handler;
1504
1505 if (ifunc) {
1506 struct rb_captured_block *captured = VM_CFP_TO_CAPTURED_BLOCK(cfp);
1507 captured->code.ifunc = ifunc;
1508 block_handler = VM_BH_FROM_IFUNC_BLOCK(captured);
1509 }
1510 else {
1511 block_handler = VM_CF_BLOCK_HANDLER(cfp);
1512 }
1513 vm_passed_block_handler_set(ec, block_handler);
1514 }
1515 retval = (*it_proc) (data1);
1516 }
1517 else if (state == TAG_BREAK || state == TAG_RETRY) {
1518 const struct vm_throw_data *const err = (struct vm_throw_data *)ec->errinfo;
1519 const rb_control_frame_t *const escape_cfp = THROW_DATA_CATCH_FRAME(err);
1520
1521 if (cfp == escape_cfp) {
1522 rb_vm_rewind_cfp(ec, cfp);
1523
1524 state = 0;
1525 ec->tag->state = TAG_NONE;
1526 ec->errinfo = Qnil;
1527
1528 if (state == TAG_RETRY) goto iter_retry;
1529 retval = THROW_DATA_VAL(err);
1530 }
1531 else if (0) {
1532 SDR(); fprintf(stderr, "%p, %p\n", (void *)cfp, (void *)escape_cfp);
1533 }
1534 }
1535 EC_POP_TAG();
1536
1537 if (state) {
1538 EC_JUMP_TAG(ec, state);
1539 }
1540 return retval;
1541}
1542
1543 VALUE
1544 rb_iterate(VALUE (* it_proc)(VALUE), VALUE data1,
1545 rb_block_call_func_t bl_proc, VALUE data2)
1546{
1547 return rb_iterate0(it_proc, data1,
1548 bl_proc ? rb_vm_ifunc_proc_new(bl_proc, (void *)data2) : 0,
1549 GET_EC());
1550}
1551
1552 struct iter_method_arg {
1553 VALUE obj;
1554 ID mid;
1555 int argc;
1556 const VALUE *argv;
1557 int kw_splat;
1558};
1559
1560static VALUE
1561iterate_method(VALUE obj)
1562{
1563 const struct iter_method_arg * arg =
1564 (struct iter_method_arg *) obj;
1565
1566 return rb_call(arg->obj, arg->mid, arg->argc, arg->argv, arg->kw_splat ? CALL_FCALL_KW : CALL_FCALL);
1567}
1568
1569 VALUE
1570 rb_block_call(VALUE obj, ID mid, int argc, const VALUE * argv,
1571 rb_block_call_func_t bl_proc, VALUE data2)
1572{
1573 struct iter_method_arg arg;
1574
1575 arg.obj = obj;
1576 arg.mid = mid;
1577 arg.argc = argc;
1578 arg.argv = argv;
1579 arg.kw_splat = 0;
1580 return rb_iterate(iterate_method, (VALUE)&arg, bl_proc, data2);
1581}
1582
1583 VALUE
1584 rb_block_call_kw(VALUE obj, ID mid, int argc, const VALUE * argv,
1585 rb_block_call_func_t bl_proc, VALUE data2, int kw_splat)
1586{
1587 struct iter_method_arg arg;
1588
1589 arg.obj = obj;
1590 arg.mid = mid;
1591 arg.argc = argc;
1592 arg.argv = argv;
1593 arg.kw_splat = kw_splat;
1594 return rb_iterate(iterate_method, (VALUE)&arg, bl_proc, data2);
1595}
1596
1597 VALUE
1598 rb_lambda_call(VALUE obj, ID mid, int argc, const VALUE *argv,
1599 rb_block_call_func_t bl_proc, int min_argc, int max_argc,
1600 VALUE data2)
1601{
1602 struct iter_method_arg arg;
1603 struct vm_ifunc *block;
1604
1605 if (!bl_proc) rb_raise(rb_eArgError, "NULL lambda function");
1606 arg.obj = obj;
1607 arg.mid = mid;
1608 arg.argc = argc;
1609 arg.argv = argv;
1610 arg.kw_splat = 0;
1611 block = rb_vm_ifunc_new(bl_proc, (void *)data2, min_argc, max_argc);
1612 return rb_iterate0(iterate_method, (VALUE)&arg, block, GET_EC());
1613}
1614
1615static VALUE
1616iterate_check_method(VALUE obj)
1617{
1618 const struct iter_method_arg * arg =
1619 (struct iter_method_arg *) obj;
1620
1621 return rb_check_funcall(arg->obj, arg->mid, arg->argc, arg->argv);
1622}
1623
1624 VALUE
1625 rb_check_block_call(VALUE obj, ID mid, int argc, const VALUE *argv,
1626 rb_block_call_func_t bl_proc, VALUE data2)
1627{
1628 struct iter_method_arg arg;
1629
1630 arg.obj = obj;
1631 arg.mid = mid;
1632 arg.argc = argc;
1633 arg.argv = argv;
1634 arg.kw_splat = 0;
1635 return rb_iterate(iterate_check_method, (VALUE)&arg, bl_proc, data2);
1636}
1637
1638 VALUE
1639 rb_each(VALUE obj)
1640{
1641 return rb_call(obj, idEach, 0, 0, CALL_FCALL);
1642}
1643
1644 void rb_parser_warn_location(VALUE, int);
1645static const rb_iseq_t *
1646eval_make_iseq(VALUE src, VALUE fname, int line, const rb_binding_t *bind,
1647 const struct rb_block *base_block)
1648{
1649 const VALUE parser = rb_parser_new();
1650 const rb_iseq_t *const parent = vm_block_iseq(base_block);
1651 VALUE realpath = Qnil;
1652 rb_iseq_t *iseq = NULL;
1653 rb_ast_t *ast;
1654 int isolated_depth = 0;
1655 {
1656 int depth = 1;
1657 const VALUE *ep = vm_block_ep(base_block);
1658
1659 while (1) {
1660 if (VM_ENV_FLAGS(ep, VM_ENV_FLAG_ISOLATED)) {
1661 isolated_depth = depth;
1662 break;
1663 }
1664 else if (VM_ENV_LOCAL_P(ep)) {
1665 break;
1666 }
1667 ep = VM_ENV_PREV_EP(ep);
1668 depth++;
1669 }
1670 }
1671
1672 if (!fname) {
1673 fname = rb_source_location(&line);
1674 }
1675
1676 if (fname != Qundef) {
1677 if (!NIL_P(fname)) fname = rb_fstring(fname);
1678 realpath = fname;
1679 }
1680 else {
1681 fname = rb_fstring_lit("(eval)");
1682 }
1683
1684 rb_parser_set_context(parser, parent, FALSE);
1685 ast = rb_parser_compile_string_path(parser, fname, src, line);
1686 if (ast->body.root) {
1687 iseq = rb_iseq_new_eval(&ast->body,
1688 parent->body->location.label,
1689 fname, realpath, INT2FIX(line),
1690 parent, isolated_depth);
1691 }
1692 rb_ast_dispose(ast);
1693
1694 if (iseq != NULL) {
1695 if (0 && iseq) { /* for debug */
1696 VALUE disasm = rb_iseq_disasm(iseq);
1697 printf("%s\n", StringValuePtr(disasm));
1698 }
1699
1700 rb_exec_event_hook_script_compiled(GET_EC(), iseq, src);
1701 }
1702
1703 return iseq;
1704}
1705
1706static VALUE
1707eval_string_with_cref(VALUE self, VALUE src, rb_cref_t *cref, VALUE file, int line)
1708{
1709 rb_execution_context_t *ec = GET_EC();
1710 struct rb_block block;
1711 const rb_iseq_t *iseq;
1712 rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(ec, ec->cfp);
1713 if (!cfp) {
1714 rb_raise(rb_eRuntimeError, "Can't eval on top of Fiber or Thread");
1715 }
1716
1717 block.as.captured = *VM_CFP_TO_CAPTURED_BLOCK(cfp);
1718 block.as.captured.self = self;
1719 block.as.captured.code.iseq = cfp->iseq;
1720 block.type = block_type_iseq;
1721
1722 iseq = eval_make_iseq(src, file, line, NULL, &block);
1723 if (!iseq) {
1724 rb_exc_raise(ec->errinfo);
1725 }
1726
1727 /* TODO: what the code checking? */
1728 if (!cref && block.as.captured.code.val) {
1729 rb_cref_t *orig_cref = vm_get_cref(vm_block_ep(&block));
1730 cref = vm_cref_dup(orig_cref);
1731 }
1732 vm_set_eval_stack(ec, iseq, cref, &block);
1733
1734 /* kick */
1735 return vm_exec(ec, true);
1736}
1737
1738static VALUE
1739eval_string_with_scope(VALUE scope, VALUE src, VALUE file, int line)
1740{
1741 rb_execution_context_t *ec = GET_EC();
1742 rb_binding_t *bind = Check_TypedStruct(scope, &ruby_binding_data_type);
1743 const rb_iseq_t *iseq = eval_make_iseq(src, file, line, bind, &bind->block);
1744 if (!iseq) {
1745 rb_exc_raise(ec->errinfo);
1746 }
1747
1748 vm_set_eval_stack(ec, iseq, NULL, &bind->block);
1749
1750 /* save new env */
1751 if (iseq->body->local_table_size > 0) {
1752 vm_bind_update_env(scope, bind, vm_make_env_object(ec, ec->cfp));
1753 }
1754
1755 /* kick */
1756 return vm_exec(ec, true);
1757}
1758
1759/*
1760 * call-seq:
1761 * eval(string [, binding [, filename [,lineno]]]) -> obj
1762 *
1763 * Evaluates the Ruby expression(s) in <em>string</em>. If
1764 * <em>binding</em> is given, which must be a Binding object, the
1765 * evaluation is performed in its context. If the optional
1766 * <em>filename</em> and <em>lineno</em> parameters are present, they
1767 * will be used when reporting syntax errors.
1768 *
1769 * def get_binding(str)
1770 * return binding
1771 * end
1772 * str = "hello"
1773 * eval "str + ' Fred'" #=> "hello Fred"
1774 * eval "str + ' Fred'", get_binding("bye") #=> "bye Fred"
1775 */
1776
1777 VALUE
1778 rb_f_eval(int argc, const VALUE *argv, VALUE self)
1779{
1780 VALUE src, scope, vfile, vline;
1781 VALUE file = Qundef;
1782 int line = 1;
1783
1784 rb_scan_args(argc, argv, "13", &src, &scope, &vfile, &vline);
1785 SafeStringValue(src);
1786 if (argc >= 3) {
1787 StringValue(vfile);
1788 }
1789 if (argc >= 4) {
1790 line = NUM2INT(vline);
1791 }
1792
1793 if (!NIL_P(vfile))
1794 file = vfile;
1795
1796 if (NIL_P(scope))
1797 return eval_string_with_cref(self, src, NULL, file, line);
1798 else
1799 return eval_string_with_scope(scope, src, file, line);
1800}
1801
1803 VALUE
1804ruby_eval_string_from_file(const char *str, const char *filename)
1805{
1806 VALUE file = filename ? rb_str_new_cstr(filename) : 0;
1807 return eval_string_with_cref(rb_vm_top_self(), rb_str_new2(str), NULL, file, 1);
1808}
1809
1822 VALUE
1823 rb_eval_string(const char *str)
1824{
1825 return ruby_eval_string_from_file(str, "eval");
1826}
1827
1828static VALUE
1829eval_string_protect(VALUE str)
1830{
1831 return rb_eval_string((char *)str);
1832}
1833
1844 VALUE
1845 rb_eval_string_protect(const char *str, int *pstate)
1846{
1847 return rb_protect(eval_string_protect, (VALUE)str, pstate);
1848}
1849
1850 struct eval_string_wrap_arg {
1851 VALUE top_self;
1852 VALUE klass;
1853 const char *str;
1854};
1855
1856static VALUE
1857eval_string_wrap_protect(VALUE data)
1858{
1859 const struct eval_string_wrap_arg *const arg = (struct eval_string_wrap_arg*)data;
1860 rb_cref_t *cref = rb_vm_cref_new_toplevel();
1861 cref->klass = arg->klass;
1862 return eval_string_with_cref(arg->top_self, rb_str_new_cstr(arg->str), cref, rb_str_new_cstr("eval"), 1);
1863}
1864
1876 VALUE
1877 rb_eval_string_wrap(const char *str, int *pstate)
1878{
1879 int state;
1880 rb_thread_t *th = GET_THREAD();
1881 VALUE self = th->top_self;
1882 VALUE wrapper = th->top_wrapper;
1883 VALUE val;
1884 struct eval_string_wrap_arg data;
1885
1886 th->top_wrapper = rb_module_new();
1887 th->top_self = rb_obj_clone(rb_vm_top_self());
1888 rb_extend_object(th->top_self, th->top_wrapper);
1889
1890 data.top_self = th->top_self;
1891 data.klass = th->top_wrapper;
1892 data.str = str;
1893
1894 val = rb_protect(eval_string_wrap_protect, (VALUE)&data, &state);
1895
1896 th->top_self = self;
1897 th->top_wrapper = wrapper;
1898
1899 if (pstate) {
1900 *pstate = state;
1901 }
1902 else if (state != TAG_NONE) {
1903 EC_JUMP_TAG(th->ec, state);
1904 }
1905 return val;
1906}
1907
1908 VALUE
1909 rb_eval_cmd_kw(VALUE cmd, VALUE arg, int kw_splat)
1910{
1911 enum ruby_tag_type state;
1912 volatile VALUE val = Qnil; /* OK */
1913 rb_execution_context_t * volatile ec = GET_EC();
1914
1915 EC_PUSH_TAG(ec);
1916 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
1917 if (!RB_TYPE_P(cmd, T_STRING)) {
1918 val = rb_funcallv_kw(cmd, idCall, RARRAY_LENINT(arg),
1919 RARRAY_CONST_PTR(arg), kw_splat);
1920 }
1921 else {
1922 val = eval_string_with_cref(rb_vm_top_self(), cmd, NULL, 0, 0);
1923 }
1924 }
1925 EC_POP_TAG();
1926
1927 if (state) EC_JUMP_TAG(ec, state);
1928 return val;
1929}
1930
1931/* block eval under the class/module context */
1932
1933static VALUE
1934yield_under(VALUE under, VALUE self, int argc, const VALUE *argv, int kw_splat)
1935{
1936 rb_execution_context_t *ec = GET_EC();
1937 rb_control_frame_t *cfp = ec->cfp;
1938 VALUE block_handler = VM_CF_BLOCK_HANDLER(cfp);
1939 VALUE new_block_handler = 0;
1940 const struct rb_captured_block *captured = NULL;
1941 struct rb_captured_block new_captured;
1942 const VALUE *ep = NULL;
1943 rb_cref_t *cref;
1944 int is_lambda = FALSE;
1945
1946 if (block_handler != VM_BLOCK_HANDLER_NONE) {
1947 again:
1948 switch (vm_block_handler_type(block_handler)) {
1949 case block_handler_type_iseq:
1950 captured = VM_BH_TO_CAPT_BLOCK(block_handler);
1951 new_captured = *captured;
1952 new_block_handler = VM_BH_FROM_ISEQ_BLOCK(&new_captured);
1953 break;
1954 case block_handler_type_ifunc:
1955 captured = VM_BH_TO_CAPT_BLOCK(block_handler);
1956 new_captured = *captured;
1957 new_block_handler = VM_BH_FROM_IFUNC_BLOCK(&new_captured);
1958 break;
1959 case block_handler_type_proc:
1960 is_lambda = rb_proc_lambda_p(block_handler) != Qfalse;
1961 block_handler = vm_proc_to_block_handler(VM_BH_TO_PROC(block_handler));
1962 goto again;
1963 case block_handler_type_symbol:
1964 return rb_sym_proc_call(SYM2ID(VM_BH_TO_SYMBOL(block_handler)),
1965 argc, argv, kw_splat,
1966 VM_BLOCK_HANDLER_NONE);
1967 }
1968
1969 new_captured.self = self;
1970 ep = captured->ep;
1971
1972 VM_FORCE_WRITE_SPECIAL_CONST(&VM_CF_LEP(ec->cfp)[VM_ENV_DATA_INDEX_SPECVAL], new_block_handler);
1973 }
1974
1975 cref = vm_cref_push(ec, under, ep, TRUE);
1976 return vm_yield_with_cref(ec, argc, argv, kw_splat, cref, is_lambda);
1977}
1978
1979 VALUE
1980 rb_yield_refine_block(VALUE refinement, VALUE refinements)
1981{
1982 rb_execution_context_t *ec = GET_EC();
1983 VALUE block_handler = VM_CF_BLOCK_HANDLER(ec->cfp);
1984
1985 if (vm_block_handler_type(block_handler) != block_handler_type_iseq) {
1986 rb_bug("rb_yield_refine_block: an iseq block is required");
1987 }
1988 else {
1989 const struct rb_captured_block *captured = VM_BH_TO_ISEQ_BLOCK(block_handler);
1990 struct rb_captured_block new_captured = *captured;
1991 VALUE new_block_handler = VM_BH_FROM_ISEQ_BLOCK(&new_captured);
1992 const VALUE *ep = captured->ep;
1993 rb_cref_t *cref = vm_cref_push(ec, refinement, ep, TRUE);
1994 CREF_REFINEMENTS_SET(cref, refinements);
1995 VM_FORCE_WRITE_SPECIAL_CONST(&VM_CF_LEP(ec->cfp)[VM_ENV_DATA_INDEX_SPECVAL], new_block_handler);
1996 new_captured.self = refinement;
1997 return vm_yield_with_cref(ec, 0, NULL, RB_NO_KEYWORDS, cref, FALSE);
1998 }
1999}
2000
2001/* string eval under the class/module context */
2002static VALUE
2003eval_under(VALUE under, VALUE self, VALUE src, VALUE file, int line)
2004{
2005 rb_cref_t *cref = vm_cref_push(GET_EC(), under, NULL, SPECIAL_CONST_P(self) && !NIL_P(under));
2006 SafeStringValue(src);
2007 return eval_string_with_cref(self, src, cref, file, line);
2008}
2009
2010static VALUE
2011specific_eval(int argc, const VALUE *argv, VALUE klass, VALUE self, int kw_splat)
2012{
2013 if (rb_block_given_p()) {
2014 rb_check_arity(argc, 0, 0);
2015 return yield_under(klass, self, 1, &self, kw_splat);
2016 }
2017 else {
2018 VALUE file = Qundef;
2019 int line = 1;
2020 VALUE code;
2021
2022 rb_check_arity(argc, 1, 3);
2023 code = argv[0];
2024 SafeStringValue(code);
2025 if (argc > 2)
2026 line = NUM2INT(argv[2]);
2027 if (argc > 1) {
2028 file = argv[1];
2029 if (!NIL_P(file)) StringValue(file);
2030 }
2031 return eval_under(klass, self, code, file, line);
2032 }
2033}
2034
2035static VALUE
2036singleton_class_for_eval(VALUE self)
2037{
2038 if (SPECIAL_CONST_P(self)) {
2039 return rb_special_singleton_class(self);
2040 }
2041 switch (BUILTIN_TYPE(self)) {
2042 case T_FLOAT: case T_BIGNUM: case T_SYMBOL:
2043 return Qnil;
2044 case T_STRING:
2045 if (FL_TEST_RAW(self, RSTRING_FSTR)) return Qnil;
2046 default:
2047 return rb_singleton_class(self);
2048 }
2049}
2050
2051/*
2052 * call-seq:
2053 * obj.instance_eval(string [, filename [, lineno]] ) -> obj
2054 * obj.instance_eval {|obj| block } -> obj
2055 *
2056 * Evaluates a string containing Ruby source code, or the given block,
2057 * within the context of the receiver (_obj_). In order to set the
2058 * context, the variable +self+ is set to _obj_ while
2059 * the code is executing, giving the code access to _obj_'s
2060 * instance variables and private methods.
2061 *
2062 * When <code>instance_eval</code> is given a block, _obj_ is also
2063 * passed in as the block's only argument.
2064 *
2065 * When <code>instance_eval</code> is given a +String+, the optional
2066 * second and third parameters supply a filename and starting line number
2067 * that are used when reporting compilation errors.
2068 *
2069 * class KlassWithSecret
2070 * def initialize
2071 * @secret = 99
2072 * end
2073 * private
2074 * def the_secret
2075 * "Ssssh! The secret is #{@secret}."
2076 * end
2077 * end
2078 * k = KlassWithSecret.new
2079 * k.instance_eval { @secret } #=> 99
2080 * k.instance_eval { the_secret } #=> "Ssssh! The secret is 99."
2081 * k.instance_eval {|obj| obj == self } #=> true
2082 */
2083
2084static VALUE
2085rb_obj_instance_eval_internal(int argc, const VALUE *argv, VALUE self)
2086{
2087 VALUE klass = singleton_class_for_eval(self);
2088 return specific_eval(argc, argv, klass, self, RB_PASS_CALLED_KEYWORDS);
2089}
2090
2091 VALUE
2092 rb_obj_instance_eval(int argc, const VALUE *argv, VALUE self)
2093{
2094 VALUE klass = singleton_class_for_eval(self);
2095 return specific_eval(argc, argv, klass, self, RB_NO_KEYWORDS);
2096}
2097
2098/*
2099 * call-seq:
2100 * obj.instance_exec(arg...) {|var...| block } -> obj
2101 *
2102 * Executes the given block within the context of the receiver
2103 * (_obj_). In order to set the context, the variable +self+ is set
2104 * to _obj_ while the code is executing, giving the code access to
2105 * _obj_'s instance variables. Arguments are passed as block parameters.
2106 *
2107 * class KlassWithSecret
2108 * def initialize
2109 * @secret = 99
2110 * end
2111 * end
2112 * k = KlassWithSecret.new
2113 * k.instance_exec(5) {|x| @secret+x } #=> 104
2114 */
2115
2116static VALUE
2117rb_obj_instance_exec_internal(int argc, const VALUE *argv, VALUE self)
2118{
2119 VALUE klass = singleton_class_for_eval(self);
2120 return yield_under(klass, self, argc, argv, RB_PASS_CALLED_KEYWORDS);
2121}
2122
2123 VALUE
2124 rb_obj_instance_exec(int argc, const VALUE *argv, VALUE self)
2125{
2126 VALUE klass = singleton_class_for_eval(self);
2127 return yield_under(klass, self, argc, argv, RB_NO_KEYWORDS);
2128}
2129
2130/*
2131 * call-seq:
2132 * mod.class_eval(string [, filename [, lineno]]) -> obj
2133 * mod.class_eval {|mod| block } -> obj
2134 * mod.module_eval(string [, filename [, lineno]]) -> obj
2135 * mod.module_eval {|mod| block } -> obj
2136 *
2137 * Evaluates the string or block in the context of _mod_, except that when
2138 * a block is given, constant/class variable lookup is not affected. This
2139 * can be used to add methods to a class. <code>module_eval</code> returns
2140 * the result of evaluating its argument. The optional _filename_ and
2141 * _lineno_ parameters set the text for error messages.
2142 *
2143 * class Thing
2144 * end
2145 * a = %q{def hello() "Hello there!" end}
2146 * Thing.module_eval(a)
2147 * puts Thing.new.hello()
2148 * Thing.module_eval("invalid code", "dummy", 123)
2149 *
2150 * <em>produces:</em>
2151 *
2152 * Hello there!
2153 * dummy:123:in `module_eval': undefined local variable
2154 * or method `code' for Thing:Class
2155 */
2156
2157static VALUE
2158rb_mod_module_eval_internal(int argc, const VALUE *argv, VALUE mod)
2159{
2160 return specific_eval(argc, argv, mod, mod, RB_PASS_CALLED_KEYWORDS);
2161}
2162
2163 VALUE
2164 rb_mod_module_eval(int argc, const VALUE *argv, VALUE mod)
2165{
2166 return specific_eval(argc, argv, mod, mod, RB_NO_KEYWORDS);
2167}
2168
2169/*
2170 * call-seq:
2171 * mod.module_exec(arg...) {|var...| block } -> obj
2172 * mod.class_exec(arg...) {|var...| block } -> obj
2173 *
2174 * Evaluates the given block in the context of the class/module.
2175 * The method defined in the block will belong to the receiver.
2176 * Any arguments passed to the method will be passed to the block.
2177 * This can be used if the block needs to access instance variables.
2178 *
2179 * class Thing
2180 * end
2181 * Thing.class_exec{
2182 * def hello() "Hello there!" end
2183 * }
2184 * puts Thing.new.hello()
2185 *
2186 * <em>produces:</em>
2187 *
2188 * Hello there!
2189 */
2190
2191static VALUE
2192rb_mod_module_exec_internal(int argc, const VALUE *argv, VALUE mod)
2193{
2194 return yield_under(mod, mod, argc, argv, RB_PASS_CALLED_KEYWORDS);
2195}
2196
2197 VALUE
2198 rb_mod_module_exec(int argc, const VALUE *argv, VALUE mod)
2199{
2200 return yield_under(mod, mod, argc, argv, RB_NO_KEYWORDS);
2201}
2202
2203/*
2204 * Document-class: UncaughtThrowError
2205 *
2206 * Raised when +throw+ is called with a _tag_ which does not have
2207 * corresponding +catch+ block.
2208 *
2209 * throw "foo", "bar"
2210 *
2211 * <em>raises the exception:</em>
2212 *
2213 * UncaughtThrowError: uncaught throw "foo"
2214 */
2215
2216static VALUE
2217uncaught_throw_init(int argc, const VALUE *argv, VALUE exc)
2218{
2219 rb_check_arity(argc, 2, UNLIMITED_ARGUMENTS);
2220 rb_call_super(argc - 2, argv + 2);
2221 rb_ivar_set(exc, id_tag, argv[0]);
2222 rb_ivar_set(exc, id_value, argv[1]);
2223 return exc;
2224}
2225
2226/*
2227 * call-seq:
2228 * uncaught_throw.tag -> obj
2229 *
2230 * Return the tag object which was called for.
2231 */
2232
2233static VALUE
2234uncaught_throw_tag(VALUE exc)
2235{
2236 return rb_ivar_get(exc, id_tag);
2237}
2238
2239/*
2240 * call-seq:
2241 * uncaught_throw.value -> obj
2242 *
2243 * Return the return value which was called for.
2244 */
2245
2246static VALUE
2247uncaught_throw_value(VALUE exc)
2248{
2249 return rb_ivar_get(exc, id_value);
2250}
2251
2252/*
2253 * call-seq:
2254 * uncaught_throw.to_s -> string
2255 *
2256 * Returns formatted message with the inspected tag.
2257 */
2258
2259static VALUE
2260uncaught_throw_to_s(VALUE exc)
2261{
2262 VALUE mesg = rb_attr_get(exc, id_mesg);
2263 VALUE tag = uncaught_throw_tag(exc);
2264 return rb_str_format(1, &tag, mesg);
2265}
2266
2267/*
2268 * call-seq:
2269 * throw(tag [, obj])
2270 *
2271 * Transfers control to the end of the active +catch+ block
2272 * waiting for _tag_. Raises +UncaughtThrowError+ if there
2273 * is no +catch+ block for the _tag_. The optional second
2274 * parameter supplies a return value for the +catch+ block,
2275 * which otherwise defaults to +nil+. For examples, see
2276 * Kernel::catch.
2277 */
2278
2279static VALUE
2280rb_f_throw(int argc, VALUE *argv, VALUE _)
2281{
2282 VALUE tag, value;
2283
2284 rb_scan_args(argc, argv, "11", &tag, &value);
2285 rb_throw_obj(tag, value);
2286 UNREACHABLE_RETURN(Qnil);
2287}
2288
2289void
2290 rb_throw_obj(VALUE tag, VALUE value)
2291{
2292 rb_execution_context_t *ec = GET_EC();
2293 struct rb_vm_tag *tt = ec->tag;
2294
2295 while (tt) {
2296 if (tt->tag == tag) {
2297 tt->retval = value;
2298 break;
2299 }
2300 tt = tt->prev;
2301 }
2302 if (!tt) {
2303 VALUE desc[3];
2304 desc[0] = tag;
2305 desc[1] = value;
2306 desc[2] = rb_str_new_cstr("uncaught throw %p");
2307 rb_exc_raise(rb_class_new_instance(numberof(desc), desc, rb_eUncaughtThrow));
2308 }
2309
2310 ec->errinfo = (VALUE)THROW_DATA_NEW(tag, NULL, TAG_THROW);
2311 EC_JUMP_TAG(ec, TAG_THROW);
2312}
2313
2314void
2315 rb_throw(const char *tag, VALUE val)
2316{
2317 rb_throw_obj(rb_sym_intern_ascii_cstr(tag), val);
2318}
2319
2320static VALUE
2321catch_i(RB_BLOCK_CALL_FUNC_ARGLIST(tag, _))
2322{
2323 return rb_yield_0(1, &tag);
2324}
2325
2326/*
2327 * call-seq:
2328 * catch([tag]) {|tag| block } -> obj
2329 *
2330 * +catch+ executes its block. If +throw+ is not called, the block executes
2331 * normally, and +catch+ returns the value of the last expression evaluated.
2332 *
2333 * catch(1) { 123 } # => 123
2334 *
2335 * If <code>throw(tag2, val)</code> is called, Ruby searches up its stack for
2336 * a +catch+ block whose +tag+ has the same +object_id+ as _tag2_. When found,
2337 * the block stops executing and returns _val_ (or +nil+ if no second argument
2338 * was given to +throw+).
2339 *
2340 * catch(1) { throw(1, 456) } # => 456
2341 * catch(1) { throw(1) } # => nil
2342 *
2343 * When +tag+ is passed as the first argument, +catch+ yields it as the
2344 * parameter of the block.
2345 *
2346 * catch(1) {|x| x + 2 } # => 3
2347 *
2348 * When no +tag+ is given, +catch+ yields a new unique object (as from
2349 * +Object.new+) as the block parameter. This object can then be used as the
2350 * argument to +throw+, and will match the correct +catch+ block.
2351 *
2352 * catch do |obj_A|
2353 * catch do |obj_B|
2354 * throw(obj_B, 123)
2355 * puts "This puts is not reached"
2356 * end
2357 *
2358 * puts "This puts is displayed"
2359 * 456
2360 * end
2361 *
2362 * # => 456
2363 *
2364 * catch do |obj_A|
2365 * catch do |obj_B|
2366 * throw(obj_A, 123)
2367 * puts "This puts is still not reached"
2368 * end
2369 *
2370 * puts "Now this puts is also not reached"
2371 * 456
2372 * end
2373 *
2374 * # => 123
2375 */
2376
2377static VALUE
2378rb_f_catch(int argc, VALUE *argv, VALUE self)
2379{
2380 VALUE tag = rb_check_arity(argc, 0, 1) ? argv[0] : rb_obj_alloc(rb_cObject);
2381 return rb_catch_obj(tag, catch_i, 0);
2382}
2383
2384 VALUE
2385 rb_catch(const char *tag, rb_block_call_func_t func, VALUE data)
2386{
2387 VALUE vtag = tag ? rb_sym_intern_ascii_cstr(tag) : rb_obj_alloc(rb_cObject);
2388 return rb_catch_obj(vtag, func, data);
2389}
2390
2391static VALUE
2392vm_catch_protect(VALUE tag, rb_block_call_func *func, VALUE data,
2393 enum ruby_tag_type *stateptr, rb_execution_context_t *volatile ec)
2394{
2395 enum ruby_tag_type state;
2396 VALUE val = Qnil; /* OK */
2397 rb_control_frame_t *volatile saved_cfp = ec->cfp;
2398
2399 EC_PUSH_TAG(ec);
2400
2401 _tag.tag = tag;
2402
2403 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
2404 /* call with argc=1, argv = [tag], block = Qnil to insure compatibility */
2405 val = (*func)(tag, data, 1, (const VALUE *)&tag, Qnil);
2406 }
2407 else if (state == TAG_THROW && THROW_DATA_VAL((struct vm_throw_data *)ec->errinfo) == tag) {
2408 rb_vm_rewind_cfp(ec, saved_cfp);
2409 val = ec->tag->retval;
2410 ec->errinfo = Qnil;
2411 state = 0;
2412 }
2413 EC_POP_TAG();
2414 if (stateptr)
2415 *stateptr = state;
2416
2417 return val;
2418}
2419
2420 VALUE
2421 rb_catch_protect(VALUE t, rb_block_call_func *func, VALUE data, enum ruby_tag_type *stateptr)
2422{
2423 return vm_catch_protect(t, func, data, stateptr, GET_EC());
2424}
2425
2426 VALUE
2427 rb_catch_obj(VALUE t, rb_block_call_func_t func, VALUE data)
2428{
2429 enum ruby_tag_type state;
2430 rb_execution_context_t *ec = GET_EC();
2431 VALUE val = vm_catch_protect(t, (rb_block_call_func *)func, data, &state, ec);
2432 if (state) EC_JUMP_TAG(ec, state);
2433 return val;
2434}
2435
2436static void
2437local_var_list_init(struct local_var_list *vars)
2438{
2439 vars->tbl = rb_ident_hash_new();
2440 RBASIC_CLEAR_CLASS(vars->tbl);
2441}
2442
2443static VALUE
2444local_var_list_finish(struct local_var_list *vars)
2445{
2446 /* TODO: not to depend on the order of st_table */
2447 VALUE ary = rb_hash_keys(vars->tbl);
2448 rb_hash_clear(vars->tbl);
2449 vars->tbl = 0;
2450 return ary;
2451}
2452
2453static int
2454local_var_list_update(st_data_t *key, st_data_t *value, st_data_t arg, int existing)
2455{
2456 if (existing) return ST_STOP;
2457 *value = (st_data_t)Qtrue; /* INT2FIX(arg) */
2458 return ST_CONTINUE;
2459}
2460
2461static void
2462local_var_list_add(const struct local_var_list *vars, ID lid)
2463{
2464 if (lid && rb_is_local_id(lid)) {
2465 /* should skip temporary variable */
2466 st_data_t idx = 0; /* tbl->num_entries */
2467 rb_hash_stlike_update(vars->tbl, ID2SYM(lid), local_var_list_update, idx);
2468 }
2469}
2470
2471/*
2472 * call-seq:
2473 * local_variables -> array
2474 *
2475 * Returns the names of the current local variables.
2476 *
2477 * fred = 1
2478 * for i in 1..10
2479 * # ...
2480 * end
2481 * local_variables #=> [:fred, :i]
2482 */
2483
2484static VALUE
2485rb_f_local_variables(VALUE _)
2486{
2487 struct local_var_list vars;
2488 rb_execution_context_t *ec = GET_EC();
2489 rb_control_frame_t *cfp = vm_get_ruby_level_caller_cfp(ec, RUBY_VM_PREVIOUS_CONTROL_FRAME(ec->cfp));
2490 unsigned int i;
2491
2492 local_var_list_init(&vars);
2493 while (cfp) {
2494 if (cfp->iseq) {
2495 for (i = 0; i < cfp->iseq->body->local_table_size; i++) {
2496 local_var_list_add(&vars, cfp->iseq->body->local_table[i]);
2497 }
2498 }
2499 if (!VM_ENV_LOCAL_P(cfp->ep)) {
2500 /* block */
2501 const VALUE *ep = VM_CF_PREV_EP(cfp);
2502
2503 if (vm_collect_local_variables_in_heap(ep, &vars)) {
2504 break;
2505 }
2506 else {
2507 while (cfp->ep != ep) {
2508 cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
2509 }
2510 }
2511 }
2512 else {
2513 break;
2514 }
2515 }
2516 return local_var_list_finish(&vars);
2517}
2518
2519/*
2520 * call-seq:
2521 * block_given? -> true or false
2522 *
2523 * Returns <code>true</code> if <code>yield</code> would execute a
2524 * block in the current context. The <code>iterator?</code> form
2525 * is mildly deprecated.
2526 *
2527 * def try
2528 * if block_given?
2529 * yield
2530 * else
2531 * "no block"
2532 * end
2533 * end
2534 * try #=> "no block"
2535 * try { "hello" } #=> "hello"
2536 * try do "hello" end #=> "hello"
2537 */
2538
2539static VALUE
2540rb_f_block_given_p(VALUE _)
2541{
2542 rb_execution_context_t *ec = GET_EC();
2543 rb_control_frame_t *cfp = ec->cfp;
2544 cfp = vm_get_ruby_level_caller_cfp(ec, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
2545
2546 if (cfp != NULL && VM_CF_BLOCK_HANDLER(cfp) != VM_BLOCK_HANDLER_NONE) {
2547 return Qtrue;
2548 }
2549 else {
2550 return Qfalse;
2551 }
2552}
2553
2554/*
2555 * call-seq:
2556 * iterator? -> true or false
2557 *
2558 * Deprecated. Use block_given? instead.
2559 */
2560
2561static VALUE
2562rb_f_iterator_p(VALUE self)
2563{
2564 rb_warn_deprecated("iterator?", "block_given?");
2565 return rb_f_block_given_p(self);
2566}
2567
2568 VALUE
2569 rb_current_realfilepath(void)
2570{
2571 const rb_execution_context_t *ec = GET_EC();
2572 rb_control_frame_t *cfp = ec->cfp;
2573 cfp = vm_get_ruby_level_caller_cfp(ec, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
2574 if (cfp != 0) return rb_iseq_realpath(cfp->iseq);
2575 return Qnil;
2576}
2577
2578void
2579 Init_vm_eval(void)
2580{
2581 rb_define_global_function("eval", rb_f_eval, -1);
2582 rb_define_global_function("local_variables", rb_f_local_variables, 0);
2583 rb_define_global_function("iterator?", rb_f_iterator_p, 0);
2584 rb_define_global_function("block_given?", rb_f_block_given_p, 0);
2585
2586 rb_define_global_function("catch", rb_f_catch, -1);
2587 rb_define_global_function("throw", rb_f_throw, -1);
2588
2589 rb_define_global_function("loop", rb_f_loop, 0);
2590
2591 rb_define_method(rb_cBasicObject, "instance_eval", rb_obj_instance_eval_internal, -1);
2592 rb_define_method(rb_cBasicObject, "instance_exec", rb_obj_instance_exec_internal, -1);
2593 rb_define_private_method(rb_cBasicObject, "method_missing", rb_method_missing, -1);
2594
2595#if 1
2596 rb_add_method(rb_cBasicObject, id__send__,
2597 VM_METHOD_TYPE_OPTIMIZED, (void *)OPTIMIZED_METHOD_TYPE_SEND, METHOD_VISI_PUBLIC);
2598 rb_add_method(rb_mKernel, idSend,
2599 VM_METHOD_TYPE_OPTIMIZED, (void *)OPTIMIZED_METHOD_TYPE_SEND, METHOD_VISI_PUBLIC);
2600#else
2601 rb_define_method(rb_cBasicObject, "__send__", rb_f_send, -1);
2602 rb_define_method(rb_mKernel, "send", rb_f_send, -1);
2603#endif
2604 rb_define_method(rb_mKernel, "public_send", rb_f_public_send, -1);
2605
2606 rb_define_method(rb_cModule, "module_exec", rb_mod_module_exec_internal, -1);
2607 rb_define_method(rb_cModule, "class_exec", rb_mod_module_exec_internal, -1);
2608 rb_define_method(rb_cModule, "module_eval", rb_mod_module_eval_internal, -1);
2609 rb_define_method(rb_cModule, "class_eval", rb_mod_module_eval_internal, -1);
2610
2611 rb_eUncaughtThrow = rb_define_class("UncaughtThrowError", rb_eArgError);
2612 rb_define_method(rb_eUncaughtThrow, "initialize", uncaught_throw_init, -1);
2613 rb_define_method(rb_eUncaughtThrow, "tag", uncaught_throw_tag, 0);
2614 rb_define_method(rb_eUncaughtThrow, "value", uncaught_throw_value, 0);
2615 rb_define_method(rb_eUncaughtThrow, "to_s", uncaught_throw_to_s, 0);
2616
2617 id_result = rb_intern_const("result");
2618 id_tag = rb_intern_const("tag");
2619 id_value = rb_intern_const("value");
2620}
2621
2622#endif /* #ifndef MJIT_HEADER */
rb_check_array_type
VALUE rb_check_array_type(VALUE ary)
Definition: array.c:988
NOINLINE
#define NOINLINE(x)
Definition: attributes.h:82
NORETURN
#define NORETURN(x)
Definition: attributes.h:152
UNREACHABLE_RETURN
#define UNREACHABLE_RETURN
Definition: assume.h:31
rb_ary_subseq
#define rb_ary_subseq(ary, beg, len)
Definition: cparse.c:76
rb_define_method
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
Definition: cxxanyargs.hpp:653
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
RB_DEBUG_COUNTER_INC
#define RB_DEBUG_COUNTER_INC(type)
Definition: debug_counter.h:444
MJIT_FUNC_EXPORTED
#define MJIT_FUNC_EXPORTED
Definition: dllexport.h:55
DBL2NUM
#define DBL2NUM
Definition: double.h:29
rb_eStopIteration
VALUE rb_eStopIteration
Definition: enumerator.c:141
len
uint8_t len
Definition: escape.c:17
str
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
numberof
#define numberof(array)
Definition: etc.c:649
rb_keyword_given_p
int rb_keyword_given_p(void)
Definition: eval.c:948
rb_ec_raised_p
#define rb_ec_raised_p(ec, f)
Definition: eval_intern.h:272
rb_ec_raised_set
#define rb_ec_raised_set(ec, f)
Definition: eval_intern.h:270
EC_EXEC_TAG
#define EC_EXEC_TAG()
Definition: eval_intern.h:193
EC_PUSH_TAG
#define EC_PUSH_TAG(ec)
Definition: eval_intern.h:130
EC_JUMP_TAG
#define EC_JUMP_TAG(ec, st)
Definition: eval_intern.h:196
rb_ec_stack_check
int rb_ec_stack_check(rb_execution_context_t *ec)
Definition: gc.c:5546
EC_POP_TAG
#define EC_POP_TAG()
Definition: eval_intern.h:138
PASS_PASSED_BLOCK_HANDLER
#define PASS_PASSED_BLOCK_HANDLER()
Definition: eval_intern.h:23
PASS_PASSED_BLOCK_HANDLER_EC
#define PASS_PASSED_BLOCK_HANDLER_EC(ec)
Definition: eval_intern.h:22
RAISED_STACKOVERFLOW
@ RAISED_STACKOVERFLOW
Definition: eval_intern.h:267
RUBY_EVENT_C_CALL
#define RUBY_EVENT_C_CALL
Definition: event.h:35
RUBY_EVENT_C_RETURN
#define RUBY_EVENT_C_RETURN
Definition: event.h:36
UNLIKELY
#define UNLIKELY(x)
Definition: ffi_common.h:126
LIKELY
#define LIKELY(x)
Definition: ffi_common.h:125
PRIsVALUE
#define PRIsVALUE
Definition: function.c:10
stack_check
#define stack_check(ec, water_mark)
Definition: gc.c:5540
CLASS_OF
#define CLASS_OF
Definition: globals.h:153
rb_extend_object
void rb_extend_object(VALUE obj, VALUE module)
Extend the object with the module.
Definition: eval.c:1730
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_module_new
VALUE rb_module_new(void)
Definition: class.c:856
rb_special_singleton_class
VALUE rb_special_singleton_class(VALUE obj)
Definition: class.c:1819
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_RAW
#define FL_TEST_RAW
Definition: fl_type.h:131
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2917
rb_rescue2
VALUE rb_rescue2(VALUE(*b_proc)(VALUE), VALUE data1, VALUE(*r_proc)(VALUE, VALUE), VALUE data2,...)
An equivalent of rescue clause.
Definition: eval.c:991
rb_eNotImpError
VALUE rb_eNotImpError
Definition: error.c:1067
rb_exc_raise
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
Definition: eval.c:712
rb_bug
void rb_bug(const char *fmt,...)
Definition: error.c:768
rb_nomethod_err_new
VALUE rb_nomethod_err_new(VALUE mesg, VALUE recv, VALUE method, VALUE args, int priv)
Definition: error.c:1809
rb_ident_hash_new
VALUE rb_ident_hash_new(void)
Definition: hash.c:4443
rb_protect
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *pstate)
Protects a function call from potential global escapes from the function.
Definition: eval.c:1105
rb_eNameError
VALUE rb_eNameError
Definition: error.c:1062
rb_eNoMethodError
VALUE rb_eNoMethodError
Definition: error.c:1065
rb_warn_deprecated
void rb_warn_deprecated(const char *fmt, const char *suggest,...)
Definition: error.c:480
rb_eRuntimeError
VALUE rb_eRuntimeError
Definition: error.c:1055
rb_name_err_new
VALUE rb_name_err_new(VALUE mesg, VALUE recv, VALUE method)
Definition: error.c:1728
rb_eArgError
VALUE rb_eArgError
Definition: error.c:1058
rb_mKernel
VALUE rb_mKernel
Kernel module.
Definition: object.c:48
rb_cObject
VALUE rb_cObject
Object class.
Definition: object.c:49
rb_obj_alloc
VALUE rb_obj_alloc(VALUE)
Allocates an instance of klass.
Definition: object.c:1900
rb_class_new_instance
VALUE rb_class_new_instance(int, const VALUE *, VALUE)
Allocates and initializes an instance of klass.
Definition: object.c:1953
rb_obj_class
VALUE rb_obj_class(VALUE)
Definition: object.c:245
rb_cBasicObject
VALUE rb_cBasicObject
BasicObject class.
Definition: object.c:47
rb_cModule
VALUE rb_cModule
Module class.
Definition: object.c:50
rb_obj_clone
VALUE rb_obj_clone(VALUE)
Almost same as Object::clone.
Definition: object.c:457
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_hash_keys
VALUE rb_hash_keys(VALUE hash)
Definition: hash.c:3549
rb_hash_stlike_update
int rb_hash_stlike_update(VALUE hash, st_data_t key, st_update_callback_func *func, st_data_t arg)
Definition: hash.c:1659
rb_hash_clear
VALUE rb_hash_clear(VALUE hash)
Definition: hash.c:2819
rb_id_table_insert
int rb_id_table_insert(struct rb_id_table *tbl, ID id, VALUE val)
Definition: id_table.c:257
rb_id_table_lookup
int rb_id_table_lookup(struct rb_id_table *tbl, ID id, VALUE *valp)
Definition: id_table.c:227
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_ary_new4
#define rb_ary_new4
Definition: array.h:74
RETURN_SIZED_ENUMERATOR
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn)
Definition: enumerator.h:64
UNLIMITED_ARGUMENTS
#define UNLIMITED_ARGUMENTS
Definition: error.h:29
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_proc_lambda_p
VALUE rb_proc_lambda_p(VALUE)
Definition: proc.c:275
rb_str_new2
#define rb_str_new2
Definition: string.h:276
rb_str_intern
VALUE rb_str_intern(VALUE)
Definition: symbol.c:840
rb_str_new_cstr
#define rb_str_new_cstr(str)
Definition: string.h:219
rb_ivar_get
VALUE rb_ivar_get(VALUE, ID)
Definition: variable.c:1234
rb_attr_get
VALUE rb_attr_get(VALUE, ID)
Definition: variable.c:1242
rb_ivar_set
VALUE rb_ivar_set(VALUE, ID, VALUE)
Definition: variable.c:1493
ID2SYM
#define ID2SYM
Definition: symbol.h:44
SYM2ID
#define SYM2ID
Definition: symbol.h:45
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
HUGE_VAL
#define HUGE_VAL
Definition: missing.h:156
NUM2INT
#define NUM2INT
Definition: int.h:44
RCLASS_CC_TBL
#define RCLASS_CC_TBL(c)
Definition: class.h:85
RCLASS_ORIGIN
#define RCLASS_ORIGIN(c)
Definition: class.h:87
UNALIGNED_MEMBER_PTR
#define UNALIGNED_MEMBER_PTR(ptr, mem)
Definition: gc.h:59
rb_sym_proc_call
VALUE rb_sym_proc_call(ID mid, int argc, const VALUE *argv, int kw_splat, VALUE passed_proc)
Definition: string.c:11171
rb_fstring_lit
#define rb_fstring_lit(str)
Definition: string.h:78
rb_fstring
VALUE rb_fstring(VALUE)
Definition: string.c:353
rb_check_funcall_hook
void rb_check_funcall_hook(int, VALUE, ID, int, const VALUE *, VALUE)
Definition: vm.h:70
rb_vm_top_self
VALUE rb_vm_top_self(void)
Definition: vm.c:3752
method_missing_reason
method_missing_reason
Definition: vm.h:32
MISSING_SUPER
@ MISSING_SUPER
Definition: vm.h:38
MISSING_VCALL
@ MISSING_VCALL
Definition: vm.h:37
MISSING_PRIVATE
@ MISSING_PRIVATE
Definition: vm.h:34
MISSING_PROTECTED
@ MISSING_PROTECTED
Definition: vm.h:35
MISSING_NOENTRY
@ MISSING_NOENTRY
Definition: vm.h:33
MISSING_NONE
@ MISSING_NONE
Definition: vm.h:40
MISSING_MISSING
@ MISSING_MISSING
Definition: vm.h:39
MISSING_FCALL
@ MISSING_FCALL
Definition: vm.h:36
rb_source_location
VALUE rb_source_location(int *pline)
Definition: vm.c:1600
rb_vm_pop_cfunc_frame
void rb_vm_pop_cfunc_frame(void)
Definition: vm.c:625
rb_sym_intern_ascii_cstr
#define rb_sym_intern_ascii_cstr(...)
Definition: internal.h:74
rb_funcallv
#define rb_funcallv(...)
Definition: internal.h:77
rb_method_basic_definition_p
#define rb_method_basic_definition_p(...)
Definition: internal.h:78
PRIxVALUE
#define PRIxVALUE
Definition: inttypes.h:75
filename
const char * filename
Definition: ioapi.h:137
int
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
buf
voidpf void * buf
Definition: ioapi.h:138
rb_iseq_new_eval
rb_iseq_t * rb_iseq_new_eval(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath, VALUE first_lineno, const rb_iseq_t *parent, int isolated_depth)
Definition: iseq.c:841
rb_iseq_disasm
VALUE rb_iseq_disasm(const rb_iseq_t *iseq)
Definition: iseq.c:2335
rb_iseq_realpath
VALUE rb_iseq_realpath(const rb_iseq_t *iseq)
Definition: iseq.c:1093
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
INT2FIX
#define INT2FIX
Definition: long.h:48
T_MASK
#define T_MASK
Definition: md5.c:131
MEMCPY
#define MEMCPY(p1, p2, type, n)
Definition: memory.h:129
ALLOCA_N
#define ALLOCA_N(type, n)
Definition: memory.h:112
RB_GC_GUARD
#define RB_GC_GUARD(v)
Definition: memory.h:91
ALLOCV_N
#define ALLOCV_N
Definition: memory.h:139
ALLOCV_END
#define ALLOCV_END
Definition: memory.h:140
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_PRIVATE
@ METHOD_VISI_PRIVATE
Definition: method.h:32
METHOD_VISI_PROTECTED
@ METHOD_VISI_PROTECTED
Definition: method.h:33
METHOD_VISI_PUBLIC
@ METHOD_VISI_PUBLIC
Definition: method.h:31
rb_callable_method_entry
const rb_callable_method_entry_t * rb_callable_method_entry(VALUE klass, ID id)
Definition: vm_method.c:1177
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
METHOD_ENTRY_INVALIDATED
#define METHOD_ENTRY_INVALIDATED(me)
Definition: method.h:76
OPTIMIZED_METHOD_TYPE_CALL
@ OPTIMIZED_METHOD_TYPE_CALL
Definition: method.h:167
OPTIMIZED_METHOD_TYPE_SEND
@ OPTIMIZED_METHOD_TYPE_SEND
Definition: method.h:166
UNDEFINED_METHOD_ENTRY_P
#define UNDEFINED_METHOD_ENTRY_P(me)
Definition: method.h:198
METHOD_ENTRY_CACHED_SET
#define METHOD_ENTRY_CACHED_SET(me)
Definition: method.h:75
METHOD_ENTRY_BASIC
#define METHOD_ENTRY_BASIC(me)
Definition: method.h:71
METHOD_ENTRY_VISI
#define METHOD_ENTRY_VISI(me)
Definition: method.h:70
ruby::backward::cxxanyargs::type
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:56
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
rb_ast_dispose
void rb_ast_dispose(rb_ast_t *ast)
Definition: node.c:1448
key
key
Definition: openssl_missing.h:185
RUBY_DTRACE_CMETHOD_ENTRY_HOOK
#define RUBY_DTRACE_CMETHOD_ENTRY_HOOK(ec, klass, id)
Definition: probes_helper.h:38
RUBY_DTRACE_CMETHOD_RETURN_HOOK
#define RUBY_DTRACE_CMETHOD_RETURN_HOOK(ec, klass, id)
Definition: probes_helper.h:41
rb_vm_cref_new_toplevel
rb_cref_t * rb_vm_cref_new_toplevel(void)
Definition: vm.c:309
ruby_binding_data_type
const rb_data_type_t ruby_binding_data_type
Definition: proc.c:319
RARRAY_CONST_PTR
#define RARRAY_CONST_PTR(s)
Definition: psych_emitter.c:4
RARRAY_CONST_PTR_TRANSIENT
#define RARRAY_CONST_PTR_TRANSIENT
Definition: rarray.h:54
RBASIC
#define RBASIC(obj)
Definition: rbasic.h:34
RBASIC_CLASS
#define RBASIC_CLASS
Definition: rbasic.h:35
RCLASS_SUPER
#define RCLASS_SUPER
Definition: rclass.h:33
NULL
#define NULL
Definition: regenc.h:69
RHASH_EMPTY_P
#define RHASH_EMPTY_P(h)
Definition: rhash.h:51
rb_parser_new
VALUE rb_parser_new(void)
Definition: ripper.c:20781
rb_parser_compile_string_path
rb_ast_t * rb_parser_compile_string_path(VALUE vparser, VALUE f, VALUE s, int line)
Definition: ripper.c:14014
rb_parser_set_context
VALUE rb_parser_set_context(VALUE vparser, const struct rb_iseq_struct *base, int main)
Definition: ripper.c:20791
SafeStringValue
#define SafeStringValue(v)
Definition: rstring.h:53
StringValue
#define StringValue(v)
Definition: rstring.h:50
StringValuePtr
#define StringValuePtr(v)
Definition: rstring.h:51
RSTRING_FSTR
#define RSTRING_FSTR
Definition: rstring.h:40
Check_TypedStruct
#define Check_TypedStruct(v, t)
Definition: rtypeddata.h:48
argc
int argc
Definition: ruby.c:240
argv
char ** argv
Definition: ruby.c:241
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
SPECIAL_CONST_P
#define SPECIAL_CONST_P
Definition: special_consts.h:47
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
rb_str_format
VALUE rb_str_format(int, const VALUE *, VALUE)
Definition: sprintf.c:214
ST_STOP
@ ST_STOP
Definition: st.h:99
ST_CONTINUE
@ ST_CONTINUE
Definition: st.h:99
st_data_t
unsigned long st_data_t
Definition: st.h:22
_
#define _(args)
Definition: stdarg.h:31
code
Definition: inftree9.h:24
eval_string_wrap_arg
Definition: vm_eval.c:1850
eval_string_wrap_arg::klass
VALUE klass
Definition: vm_eval.c:1852
eval_string_wrap_arg::top_self
VALUE top_self
Definition: vm_eval.c:1851
eval_string_wrap_arg::str
const char * str
Definition: vm_eval.c:1853
file
Definition: gzappend.c:170
iter_method_arg
Definition: vm_eval.c:1552
iter_method_arg::argv
const VALUE * argv
Definition: vm_eval.c:1556
iter_method_arg::argc
int argc
Definition: vm_eval.c:1555
iter_method_arg::obj
VALUE obj
Definition: vm_eval.c:1553
iter_method_arg::mid
ID mid
Definition: vm_eval.c:1554
iter_method_arg::kw_splat
int kw_splat
Definition: vm_eval.c:1557
local_var_list
Definition: vm_eval.c:14
local_var_list::tbl
VALUE tbl
Definition: vm_eval.c:15
rb_ast_body_struct::root
const NODE * root
Definition: node.h:399
rb_ast_struct
Definition: node.h:403
rb_ast_struct::body
rb_ast_body_t body
Definition: node.h:406
rb_binding_t
Definition: vm_core.h:1112
rb_binding_t::block
const struct rb_block block
Definition: vm_core.h:1113
rb_block
Definition: vm_core.h:760
rb_callable_method_entry_struct
Definition: method.h:62
rb_callable_method_entry_struct::called_id
ID called_id
Definition: method.h:66
rb_callable_method_entry_struct::defined_class
const VALUE defined_class
Definition: method.h:64
rb_callable_method_entry_struct::owner
const VALUE owner
Definition: method.h:67
rb_callable_method_entry_struct::def
struct rb_method_definition_struct *const def
Definition: method.h:65
rb_callcache
Definition: vm_callinfo.h:274
rb_callcache::klass
const VALUE klass
Definition: vm_callinfo.h:278
rb_callcache::v
VALUE v
Definition: vm_callinfo.h:289
rb_callinfo
Definition: vm_callinfo.h:61
rb_callinfo::mid
VALUE mid
Definition: vm_callinfo.h:64
rb_calling_info
Definition: vm_core.h:248
rb_calling_info::argc
int argc
Definition: vm_core.h:253
rb_calling_info::cc
const struct rb_callcache * cc
Definition: vm_core.h:250
rb_calling_info::recv
VALUE recv
Definition: vm_core.h:252
rb_calling_info::kw_splat
int kw_splat
Definition: vm_core.h:254
rb_calling_info::ci
const struct rb_callinfo * ci
Definition: vm_core.h:249
rb_calling_info::block_handler
VALUE block_handler
Definition: vm_core.h:251
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::code
union rb_captured_block::@198 code
rb_captured_block::self
VALUE self
Definition: vm_core.h:737
rb_class_cc_entries
Definition: vm_callinfo.h:431
rb_control_frame_struct
Definition: vm_core.h:769
rb_control_frame_struct::sp
VALUE * sp
Definition: vm_core.h:771
rb_control_frame_struct::ep
const VALUE * ep
Definition: vm_core.h:774
rb_control_frame_struct::self
VALUE self
Definition: vm_core.h:773
rb_control_frame_struct::iseq
const rb_iseq_t * iseq
Definition: vm_core.h:772
rb_cref_struct
CREF (Class REFerence)
Definition: method.h:44
rb_cref_struct::klass
VALUE klass
Definition: method.h:47
rb_execution_context_struct
Definition: vm_core.h:854
rb_execution_context_struct::errinfo
VALUE errinfo
Definition: vm_core.h:889
rb_execution_context_struct::cfp
rb_control_frame_t * cfp
Definition: vm_core.h:858
rb_execution_context_struct::tag
struct rb_vm_tag * tag
Definition: vm_core.h:860
rb_id_table
Definition: id_table.c:41
rb_iseq_constant_body::local_table_size
unsigned int local_table_size
Definition: vm_core.h:424
rb_iseq_constant_body::location
rb_iseq_location_t location
Definition: vm_core.h:393
rb_iseq_constant_body::local_table
const ID * local_table
Definition: vm_core.h:405
rb_iseq_location_struct::label
VALUE label
Definition: vm_core.h:269
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_cfunc_struct
Definition: method.h:139
rb_method_cfunc_struct::invoker
VALUE(* invoker)(VALUE recv, int argc, const VALUE *argv, VALUE(*func)(ANYARGS))
Definition: method.h:141
rb_method_cfunc_struct::argc
int argc
Definition: method.h:142
rb_method_cfunc_struct::func
VALUE(* func)(ANYARGS)
Definition: method.h:140
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_definition_struct::cfunc
rb_method_cfunc_t cfunc
Definition: method.h:180
rb_method_definition_struct::refined
rb_method_refined_t refined
Definition: method.h:183
rb_method_refined_struct::orig_me
struct rb_method_entry_struct * orig_me
Definition: method.h:155
rb_proc_t
Definition: vm_core.h:1086
rb_thread_struct
Definition: vm_core.h:935
rb_thread_struct::ec
rb_execution_context_t * ec
Definition: vm_core.h:941
rb_thread_struct::top_wrapper
VALUE top_wrapper
Definition: vm_core.h:950
rb_thread_struct::top_self
VALUE top_self
Definition: vm_core.h:949
rb_vm_struct
Definition: vm_core.h:564
rb_vm_struct::global_cc_cache_table
const struct rb_callcache * global_cc_cache_table[VM_GLOBAL_CC_CACHE_TABLE_SIZE]
Definition: vm_core.h:664
rb_vm_tag
Definition: vm_core.h:808
rb_vm_tag::retval
VALUE retval
Definition: vm_core.h:810
rb_vm_tag::prev
struct rb_vm_tag * prev
Definition: vm_core.h:812
rb_vm_tag::state
enum ruby_tag_type state
Definition: vm_core.h:813
rb_vm_tag::tag
VALUE tag
Definition: vm_core.h:809
rescue_funcall_args
Definition: vm_eval.c:508
rescue_funcall_args::recv
VALUE recv
Definition: vm_eval.c:510
rescue_funcall_args::kw_splat
int kw_splat
Definition: vm_eval.c:518
rescue_funcall_args::mid
ID mid
Definition: vm_eval.c:511
rescue_funcall_args::respond_to_missing
unsigned int respond_to_missing
Definition: vm_eval.c:515
rescue_funcall_args::argv
const VALUE * argv
Definition: vm_eval.c:517
rescue_funcall_args::ec
rb_execution_context_t * ec
Definition: vm_eval.c:512
rescue_funcall_args::argc
int argc
Definition: vm_eval.c:516
rescue_funcall_args::respond
unsigned int respond
Definition: vm_eval.c:514
rescue_funcall_args::cme
const rb_callable_method_entry_t * cme
Definition: vm_eval.c:513
rescue_funcall_args::defined_class
VALUE defined_class
Definition: vm_eval.c:509
state
Definition: blast.c:41
vm_ifunc
IFUNC (Internal FUNCtion)
Definition: imemo.h:85
vm_throw_data
THROW_DATA.
Definition: imemo.h:63
t
#define t
Definition: symbol.c:253
ruby_current_ec_key
native_tls_key_t ruby_current_ec_key
Definition: vm.c:400
VALUE
unsigned long VALUE
Definition: value.h:38
ID
unsigned long ID
Definition: value.h:39
T_COMPLEX
#define T_COMPLEX
Definition: value_type.h:58
T_FILE
#define T_FILE
Definition: value_type.h:61
T_STRING
#define T_STRING
Definition: value_type.h:77
T_NIL
#define T_NIL
Definition: value_type.h:71
T_FLOAT
#define T_FLOAT
Definition: value_type.h:63
T_IMEMO
#define T_IMEMO
Definition: value_type.h:66
T_BIGNUM
#define T_BIGNUM
Definition: value_type.h:56
T_STRUCT
#define T_STRUCT
Definition: value_type.h:78
T_FIXNUM
#define T_FIXNUM
Definition: value_type.h:62
T_DATA
#define T_DATA
Definition: value_type.h:59
T_NONE
#define T_NONE
Definition: value_type.h:73
T_NODE
#define T_NODE
Definition: value_type.h:72
T_MODULE
#define T_MODULE
Definition: value_type.h:69
T_TRUE
#define T_TRUE
Definition: value_type.h:80
T_RATIONAL
#define T_RATIONAL
Definition: value_type.h:75
T_ICLASS
#define T_ICLASS
Definition: value_type.h:65
T_HASH
#define T_HASH
Definition: value_type.h:64
T_FALSE
#define T_FALSE
Definition: value_type.h:60
T_UNDEF
#define T_UNDEF
Definition: value_type.h:81
T_ZOMBIE
#define T_ZOMBIE
Definition: value_type.h:82
T_ARRAY
#define T_ARRAY
Definition: value_type.h:55
T_OBJECT
#define T_OBJECT
Definition: value_type.h:74
T_SYMBOL
#define T_SYMBOL
Definition: value_type.h:79
T_MATCH
#define T_MATCH
Definition: value_type.h:68
T_CLASS
#define T_CLASS
Definition: value_type.h:57
BUILTIN_TYPE
#define BUILTIN_TYPE
Definition: value_type.h:84
T_MOVED
#define T_MOVED
Definition: value_type.h:70
ruby_value_type
ruby_value_type
C-level type of an object.
Definition: value_type.h:110
SYMBOL_P
#define SYMBOL_P
Definition: value_type.h:87
T_REGEXP
#define T_REGEXP
Definition: value_type.h:76
vm_exec
#define vm_exec
Definition: vm.c:11
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_vm_rewind_cfp
void rb_vm_rewind_cfp(rb_execution_context_t *ec, rb_control_frame_t *cfp)
Definition: vm.c:639
rb_resolve_refined_method_callable
const rb_callable_method_entry_t * rb_resolve_refined_method_callable(VALUE refinements, const rb_callable_method_entry_t *me)
Definition: vm_method.c:1301
rb_id2str
#define rb_id2str(id)
Definition: vm_backtrace.c:30
VM_CI_ON_STACK
#define VM_CI_ON_STACK(mid_, flags_, argc_, kwarg_)
Definition: vm_callinfo.h:256
vm_ci_new
#define vm_ci_new(mid, flag, argc, kwarg)
Definition: vm_callinfo.h:180
VM_CALL_KW_SPLAT
#define VM_CALL_KW_SPLAT
Definition: vm_callinfo.h:38
VM_CC_ON_STACK
#define VM_CC_ON_STACK(clazz, call, aux, cme)
Definition: vm_callinfo.h:305
rb_vm_frame_method_entry
const rb_callable_method_entry_t * rb_vm_frame_method_entry(const rb_control_frame_t *cfp)
Definition: vm_insnhelper.c:667
TAG_NONE
#define TAG_NONE
Definition: vm_core.h:198
rb_vm_pop_frame
void rb_vm_pop_frame(rb_execution_context_t *ec)
Definition: vm_insnhelper.c:419
TAG_RETRY
#define TAG_RETRY
Definition: vm_core.h:202
ruby_tag_type
ruby_tag_type
Definition: vm_core.h:185
block_type_iseq
@ block_type_iseq
Definition: vm_core.h:754
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
EXEC_EVENT_HOOK
#define EXEC_EVENT_HOOK(ec_, flag_, self_, id_, called_id_, klass_, data_)
Definition: vm_core.h:2001
VM_GLOBAL_CC_CACHE_TABLE_SIZE
#define VM_GLOBAL_CC_CACHE_TABLE_SIZE
Definition: vm_core.h:662
TAG_THROW
#define TAG_THROW
Definition: vm_core.h:205
RUBY_VM_CHECK_INTS
#define RUBY_VM_CHECK_INTS(ec)
Definition: vm_core.h:1921
CHECK_VM_STACK_OVERFLOW
#define CHECK_VM_STACK_OVERFLOW(cfp, margin)
Definition: vm_core.h:1740
TAG_BREAK
#define TAG_BREAK
Definition: vm_core.h:200
SDR
#define SDR()
Definition: vm_core.h:1647
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
RUBY_VM_PREVIOUS_CONTROL_FRAME
#define RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp)
Definition: vm_core.h:1392
VM_FRAME_FLAG_CFRAME_KW
@ VM_FRAME_FLAG_CFRAME_KW
Definition: vm_core.h:1196
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_FRAME_MAGIC_CFUNC
@ VM_FRAME_MAGIC_CFUNC
Definition: vm_core.h:1182
VM_ENV_FLAG_ISOLATED
@ VM_ENV_FLAG_ISOLATED
Definition: vm_core.h:1203
VM_FRAME_FLAG_FINISH
@ VM_FRAME_FLAG_FINISH
Definition: vm_core.h:1191
rb_yield_splat_kw
VALUE rb_yield_splat_kw(VALUE values, int kw_splat)
Definition: vm_eval.c:1400
rb_check_funcall_basic_kw
VALUE rb_check_funcall_basic_kw(VALUE recv, ID mid, VALUE ancestor, int argc, const VALUE *argv, int kw_splat)
Calls a method only if it is the basic method of ancestor otherwise returns Qundef;.
Definition: vm_eval.c:1111
rb_funcall_passing_block
VALUE rb_funcall_passing_block(VALUE recv, ID mid, int argc, const VALUE *argv)
Definition: vm_eval.c:1149
rb_f_send
VALUE rb_f_send(int argc, VALUE *argv, VALUE recv)
Definition: vm_eval.c:1295
rb_funcall
VALUE rb_funcall(VALUE recv, ID mid, int n,...)
Calls a method.
Definition: vm_eval.c:1077
call_type
call_type
Definition: vm_eval.c:31
CALL_PUBLIC
@ CALL_PUBLIC
Definition: vm_eval.c:32
CALL_PUBLIC_KW
@ CALL_PUBLIC_KW
Definition: vm_eval.c:35
CALL_FCALL
@ CALL_FCALL
Definition: vm_eval.c:33
CALL_VCALL
@ CALL_VCALL
Definition: vm_eval.c:34
CALL_FCALL_KW
@ CALL_FCALL_KW
Definition: vm_eval.c:36
CALL_TYPE_MAX
@ CALL_TYPE_MAX
Definition: vm_eval.c:37
rb_funcallv_kw
VALUE rb_funcallv_kw(VALUE recv, ID mid, int argc, const VALUE *argv, int kw_splat)
Definition: vm_eval.c:1030
rb_yield_1
VALUE rb_yield_1(VALUE val)
Definition: vm_eval.c:1335
rb_funcall_with_block_kw
VALUE rb_funcall_with_block_kw(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE passed_procval, int kw_splat)
Definition: vm_eval.c:1173
rb_catch_obj
VALUE rb_catch_obj(VALUE t, rb_block_call_func_t func, VALUE data)
Definition: vm_eval.c:2427
Init_vm_eval
void Init_vm_eval(void)
Definition: vm_eval.c:2579
id_mesg
#define id_mesg
Definition: vm_eval.c:29
rb_call_super_kw
VALUE rb_call_super_kw(int argc, const VALUE *argv, int kw_splat)
Definition: vm_eval.c:290
rb_block_call_kw
VALUE rb_block_call_kw(VALUE obj, ID mid, int argc, const VALUE *argv, rb_block_call_func_t bl_proc, VALUE data2, int kw_splat)
Definition: vm_eval.c:1584
rb_yield_values2
VALUE rb_yield_values2(int argc, const VALUE *argv)
Definition: vm_eval.c:1375
type_case
#define type_case(t)
rb_eval_string_protect
VALUE rb_eval_string_protect(const char *str, int *pstate)
Evaluates the given string in an isolated binding.
Definition: vm_eval.c:1845
rb_funcallv_public
VALUE rb_funcallv_public(VALUE recv, ID mid, int argc, const VALUE *argv)
Calls a method.
Definition: vm_eval.c:1137
rb_type_str
const char * rb_type_str(enum ruby_value_type type)
Definition: vm_eval.c:686
rb_obj_instance_exec
VALUE rb_obj_instance_exec(int argc, const VALUE *argv, VALUE self)
Definition: vm_eval.c:2124
rb_check_block_call
VALUE rb_check_block_call(VALUE obj, ID mid, int argc, const VALUE *argv, rb_block_call_func_t bl_proc, VALUE data2)
Definition: vm_eval.c:1625
rb_current_receiver
VALUE rb_current_receiver(void)
Definition: vm_eval.c:306
rb_each
VALUE rb_each(VALUE obj)
Definition: vm_eval.c:1639
rb_vm_call0
VALUE rb_vm_call0(rb_execution_context_t *ec, VALUE recv, ID id, int argc, const VALUE *argv, const rb_callable_method_entry_t *cme, int kw_splat)
Definition: vm_eval.c:46
rb_check_funcall
VALUE rb_check_funcall(VALUE recv, ID mid, int argc, const VALUE *argv)
Definition: vm_eval.c:619
rb_funcall_passing_block_kw
VALUE rb_funcall_passing_block_kw(VALUE recv, ID mid, int argc, const VALUE *argv, int kw_splat)
Definition: vm_eval.c:1156
rb_block_call
VALUE rb_block_call(VALUE obj, ID mid, int argc, const VALUE *argv, rb_block_call_func_t bl_proc, VALUE data2)
Definition: vm_eval.c:1570
rb_make_no_method_exception
VALUE rb_make_no_method_exception(VALUE exc, VALUE format, VALUE obj, int argc, const VALUE *argv, int priv)
Definition: vm_eval.c:886
rb_yield_values
VALUE rb_yield_values(int n,...)
Definition: vm_eval.c:1353
rb_yield_refine_block
VALUE rb_yield_refine_block(VALUE refinement, VALUE refinements)
Definition: vm_eval.c:1980
rb_f_eval
VALUE rb_f_eval(int argc, const VALUE *argv, VALUE self)
Definition: vm_eval.c:1778
rb_check_funcall_kw
VALUE rb_check_funcall_kw(VALUE recv, ID mid, int argc, const VALUE *argv, int kw_splat)
Definition: vm_eval.c:613
rb_check_funcall_default
VALUE rb_check_funcall_default(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE def)
Definition: vm_eval.c:647
rb_throw
void rb_throw(const char *tag, VALUE val)
Definition: vm_eval.c:2315
rb_yield_force_blockarg
VALUE rb_yield_force_blockarg(VALUE values)
Definition: vm_eval.c:1413
rb_check_funcall_with_hook_kw
VALUE rb_check_funcall_with_hook_kw(VALUE recv, ID mid, int argc, const VALUE *argv, rb_check_funcall_hook *hook, VALUE arg, int kw_splat)
Definition: vm_eval.c:653
rb_catch_protect
VALUE rb_catch_protect(VALUE t, rb_block_call_func *func, VALUE data, enum ruby_tag_type *stateptr)
Definition: vm_eval.c:2421
rb_check_funcall_with_hook
VALUE rb_check_funcall_with_hook(VALUE recv, ID mid, int argc, const VALUE *argv, rb_check_funcall_hook *hook, VALUE arg)
Definition: vm_eval.c:679
rb_lambda_call
VALUE rb_lambda_call(VALUE obj, ID mid, int argc, const VALUE *argv, rb_block_call_func_t bl_proc, int min_argc, int max_argc, VALUE data2)
Definition: vm_eval.c:1598
rb_yield
VALUE rb_yield(VALUE val)
Definition: vm_eval.c:1341
rb_mod_module_eval
VALUE rb_mod_module_eval(int argc, const VALUE *argv, VALUE mod)
Definition: vm_eval.c:2164
rb_check_stack_overflow
void rb_check_stack_overflow(void)
Definition: vm_eval.c:331
rb_eval_string
VALUE rb_eval_string(const char *str)
Evaluates the given string in an isolated binding.
Definition: vm_eval.c:1823
rb_yield_block
VALUE rb_yield_block(RB_BLOCK_CALL_FUNC_ARGLIST(val, arg))
Definition: vm_eval.c:1419
rb_iterate
VALUE rb_iterate(VALUE(*it_proc)(VALUE), VALUE data1, rb_block_call_func_t bl_proc, VALUE data2)
Definition: vm_eval.c:1544
rb_mod_module_exec
VALUE rb_mod_module_exec(int argc, const VALUE *argv, VALUE mod)
Definition: vm_eval.c:2198
ruby_eval_string_from_file
VALUE ruby_eval_string_from_file(const char *str, const char *filename)
Definition: vm_eval.c:1804
rb_obj_instance_eval
VALUE rb_obj_instance_eval(int argc, const VALUE *argv, VALUE self)
Definition: vm_eval.c:2092
rb_eval_string_wrap
VALUE rb_eval_string_wrap(const char *str, int *pstate)
Evaluates the given string under a module binding in an isolated binding.
Definition: vm_eval.c:1877
rb_eval_cmd_kw
VALUE rb_eval_cmd_kw(VALUE cmd, VALUE arg, int kw_splat)
Definition: vm_eval.c:1909
rb_parser_warn_location
void rb_parser_warn_location(VALUE, int)
rb_apply
VALUE rb_apply(VALUE recv, ID mid, VALUE args)
Calls a method.
Definition: vm_eval.c:1044
rb_catch
VALUE rb_catch(const char *tag, rb_block_call_func_t func, VALUE data)
Definition: vm_eval.c:2385
rb_call_super
VALUE rb_call_super(int argc, const VALUE *argv)
Definition: vm_eval.c:298
rb_yield_splat
VALUE rb_yield_splat(VALUE values)
Definition: vm_eval.c:1387
rb_current_realfilepath
VALUE rb_current_realfilepath(void)
Definition: vm_eval.c:2569
rb_funcallv_public_kw
VALUE rb_funcallv_public_kw(VALUE recv, ID mid, int argc, const VALUE *argv, int kw_splat)
Definition: vm_eval.c:1143
rb_funcall_with_block
VALUE rb_funcall_with_block(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE passed_procval)
Definition: vm_eval.c:1163
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
rb_throw_obj
void rb_throw_obj(VALUE tag, VALUE value)
Definition: vm_eval.c:2290
rb_yield_values_kw
VALUE rb_yield_values_kw(int argc, const VALUE *argv, int kw_splat)
Definition: vm_eval.c:1381
CHECK_CFP_CONSISTENCY
#define CHECK_CFP_CONSISTENCY(func)
Definition: vm_insnhelper.c:2865
rb_ec_stack_overflow
void rb_ec_stack_overflow(rb_execution_context_t *ec, int crit)
Definition: vm_insnhelper.c:84
vm_check_canary
#define vm_check_canary(ec, sp)
Definition: vm_insnhelper.c:290
BOUND_PRIVATE
#define BOUND_PRIVATE
Definition: vm_method.c:1429
undefined
#define undefined
Definition: vm_method.c:18
BOUND_RESPONDS
#define BOUND_RESPONDS
Definition: vm_method.c:1430
RB_VM_LOCK_ENTER
#define RB_VM_LOCK_ENTER()
Definition: vm_sync.h:121
RB_VM_LOCK_LEAVE
#define RB_VM_LOCK_LEAVE()
Definition: vm_sync.h:122
err
int err
Definition: win32.c:142
def
int def(FILE *source, FILE *dest, int level)
Definition: zpipe.c:36