[ruby/win32ole] Undefine allocator of WIN32OLE_VARIABLE to get rid of warning
[ruby-80x24.org.git] / vm_eval.c
blob0abb4644f9d696e4a23982f54e9af91b70276d7f
1 /**********************************************************************
3 vm_eval.c -
5 $Author$
6 created at: Sat May 24 16:02:32 JST 2008
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
12 **********************************************************************/
14 struct local_var_list {
15 VALUE tbl;
18 static 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);
19 static 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);
20 static inline VALUE vm_yield(rb_execution_context_t *ec, int argc, const VALUE *argv, int kw_splat);
21 static inline VALUE vm_yield_with_block(rb_execution_context_t *ec, int argc, const VALUE *argv, VALUE block_handler, int kw_splat);
22 static 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);
24 static 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);
25 static int vm_collect_local_variables_in_heap(const VALUE *dfp, const struct local_var_list *vars);
27 static VALUE rb_eUncaughtThrow;
28 static ID id_result, id_tag, id_value;
29 #define id_mesg idMesg
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;
40 static VALUE send_internal(int argc, const VALUE *argv, VALUE recv, call_type scope);
41 static VALUE vm_call0_body(rb_execution_context_t* ec, struct rb_calling_info *calling, const VALUE *argv);
43 #ifndef MJIT_HEADER
45 MJIT_FUNC_EXPORTED VALUE
46 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)
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,
57 return vm_call0_body(ec, &calling, argv);
60 MJIT_FUNC_EXPORTED VALUE
61 rb_vm_call_with_refinements(rb_execution_context_t *ec, VALUE recv, ID id, int argc, const VALUE *argv, int kw_splat)
63 const rb_callable_method_entry_t *me =
64 rb_callable_method_entry_with_refinements(CLASS_OF(recv), id, NULL);
65 if (me) {
66 return rb_vm_call0(ec, recv, id, argc, argv, me, kw_splat);
68 else {
69 /* fallback to funcall (e.g. method_missing) */
70 return rb_funcallv(recv, id, argc, argv);
74 static inline VALUE
75 vm_call0_cc(rb_execution_context_t *ec, VALUE recv, ID id, int argc, const VALUE *argv, const struct rb_callcache *cc, int kw_splat)
77 struct rb_calling_info calling = {
78 .ci = &VM_CI_ON_STACK(id, kw_splat ? VM_CALL_KW_SPLAT : 0, argc, NULL),
79 .cc = cc,
80 .block_handler = vm_passed_block_handler(ec),
81 .recv = recv,
82 .argc = argc,
83 .kw_splat = kw_splat,
86 return vm_call0_body(ec, &calling, argv);
89 static VALUE
90 vm_call0_cme(rb_execution_context_t *ec, struct rb_calling_info *calling, const VALUE *argv, const rb_callable_method_entry_t *cme)
92 calling->cc = &VM_CC_ON_STACK(Qfalse, vm_call_general, { 0 }, cme);
93 return vm_call0_body(ec, calling, argv);
96 static VALUE
97 vm_call0_super(rb_execution_context_t *ec, struct rb_calling_info *calling, const VALUE *argv, VALUE klass, enum method_missing_reason ex)
99 ID mid = vm_ci_mid(calling->ci);
100 klass = RCLASS_SUPER(klass);
102 if (klass) {
103 const rb_callable_method_entry_t *cme = rb_callable_method_entry(klass, mid);
105 if (cme) {
106 RUBY_VM_CHECK_INTS(ec);
107 return vm_call0_cme(ec, calling, argv, cme);
111 vm_passed_block_handler_set(ec, calling->block_handler);
112 return method_missing(ec, calling->recv, mid, calling->argc, argv, ex, calling->kw_splat);
115 static VALUE
116 vm_call0_cfunc_with_frame(rb_execution_context_t* ec, struct rb_calling_info *calling, const VALUE *argv)
118 const struct rb_callinfo *ci = calling->ci;
119 VALUE val;
120 const rb_callable_method_entry_t *me = vm_cc_cme(calling->cc);
121 const rb_method_cfunc_t *cfunc = UNALIGNED_MEMBER_PTR(me->def, body.cfunc);
122 int len = cfunc->argc;
123 VALUE recv = calling->recv;
124 int argc = calling->argc;
125 ID mid = vm_ci_mid(ci);
126 VALUE block_handler = calling->block_handler;
127 int frame_flags = VM_FRAME_MAGIC_CFUNC | VM_FRAME_FLAG_CFRAME | VM_ENV_FLAG_LOCAL;
129 if (calling->kw_splat) {
130 if (argc > 0 && RB_TYPE_P(argv[argc-1], T_HASH) && RHASH_EMPTY_P(argv[argc-1])) {
131 argc--;
133 else {
134 frame_flags |= VM_FRAME_FLAG_CFRAME_KW;
138 RUBY_DTRACE_CMETHOD_ENTRY_HOOK(ec, me->owner, me->def->original_id);
139 EXEC_EVENT_HOOK(ec, RUBY_EVENT_C_CALL, recv, me->def->original_id, mid, me->owner, Qnil);
141 rb_control_frame_t *reg_cfp = ec->cfp;
143 vm_push_frame(ec, 0, frame_flags, recv,
144 block_handler, (VALUE)me,
145 0, reg_cfp->sp, 0, 0);
147 if (len >= 0) rb_check_arity(argc, len, len);
149 val = (*cfunc->invoker)(recv, argc, argv, cfunc->func);
151 CHECK_CFP_CONSISTENCY("vm_call0_cfunc_with_frame");
152 rb_vm_pop_frame(ec);
154 EXEC_EVENT_HOOK(ec, RUBY_EVENT_C_RETURN, recv, me->def->original_id, mid, me->owner, val);
155 RUBY_DTRACE_CMETHOD_RETURN_HOOK(ec, me->owner, me->def->original_id);
157 return val;
160 static VALUE
161 vm_call0_cfunc(rb_execution_context_t *ec, struct rb_calling_info *calling, const VALUE *argv)
163 return vm_call0_cfunc_with_frame(ec, calling, argv);
166 static void
167 vm_call_check_arity(struct rb_calling_info *calling, int argc, const VALUE *argv)
169 if (calling->kw_splat &&
170 calling->argc > 0 &&
171 RB_TYPE_P(argv[calling->argc-1], T_HASH) &&
172 RHASH_EMPTY_P(argv[calling->argc-1])) {
173 calling->argc--;
176 rb_check_arity(calling->argc, argc, argc);
179 /* `ci' should point temporal value (on stack value) */
180 static VALUE
181 vm_call0_body(rb_execution_context_t *ec, struct rb_calling_info *calling, const VALUE *argv)
183 const struct rb_callinfo *ci = calling->ci;
184 const struct rb_callcache *cc = calling->cc;
185 VALUE ret;
187 retry:
189 switch (vm_cc_cme(cc)->def->type) {
190 case VM_METHOD_TYPE_ISEQ:
192 rb_control_frame_t *reg_cfp = ec->cfp;
193 int i;
195 CHECK_VM_STACK_OVERFLOW(reg_cfp, calling->argc + 1);
196 vm_check_canary(ec, reg_cfp->sp);
198 *reg_cfp->sp++ = calling->recv;
199 for (i = 0; i < calling->argc; i++) {
200 *reg_cfp->sp++ = argv[i];
203 vm_call_iseq_setup(ec, reg_cfp, calling);
204 VM_ENV_FLAGS_SET(ec->cfp->ep, VM_FRAME_FLAG_FINISH);
205 return vm_exec(ec, true); /* CHECK_INTS in this function */
207 case VM_METHOD_TYPE_NOTIMPLEMENTED:
208 case VM_METHOD_TYPE_CFUNC:
209 ret = vm_call0_cfunc(ec, calling, argv);
210 goto success;
211 case VM_METHOD_TYPE_ATTRSET:
212 vm_call_check_arity(calling, 1, argv);
213 VM_CALL_METHOD_ATTR(ret,
214 rb_ivar_set(calling->recv, vm_cc_cme(cc)->def->body.attr.id, argv[0]),
215 (void)0);
216 goto success;
217 case VM_METHOD_TYPE_IVAR:
218 vm_call_check_arity(calling, 0, argv);
219 VM_CALL_METHOD_ATTR(ret,
220 rb_attr_get(calling->recv, vm_cc_cme(cc)->def->body.attr.id),
221 (void)0);
222 goto success;
223 case VM_METHOD_TYPE_BMETHOD:
224 ret = vm_call_bmethod_body(ec, calling, argv);
225 goto success;
226 case VM_METHOD_TYPE_ZSUPER:
228 VALUE klass = RCLASS_ORIGIN(vm_cc_cme(cc)->defined_class);
229 return vm_call0_super(ec, calling, argv, klass, MISSING_SUPER);
231 case VM_METHOD_TYPE_REFINED:
233 const rb_callable_method_entry_t *cme = vm_cc_cme(cc);
235 if (cme->def->body.refined.orig_me) {
236 const rb_callable_method_entry_t *orig_cme = refined_method_callable_without_refinement(cme);
237 return vm_call0_cme(ec, calling, argv, orig_cme);
240 VALUE klass = cme->defined_class;
241 return vm_call0_super(ec, calling, argv, klass, 0);
243 case VM_METHOD_TYPE_ALIAS:
245 const rb_callable_method_entry_t *cme = vm_cc_cme(cc);
246 const rb_callable_method_entry_t *orig_cme = aliased_callable_method_entry(cme);
248 if (cme == orig_cme) rb_bug("same!!");
250 if (vm_cc_markable(cc)) {
251 return vm_call0_cme(ec, calling, argv, orig_cme);
253 else {
254 *((const rb_callable_method_entry_t **)&cc->cme_) = orig_cme;
255 goto retry;
258 case VM_METHOD_TYPE_MISSING:
260 vm_passed_block_handler_set(ec, calling->block_handler);
261 return method_missing(ec, calling->recv, vm_ci_mid(ci), calling->argc,
262 argv, MISSING_NOENTRY, calling->kw_splat);
264 case VM_METHOD_TYPE_OPTIMIZED:
265 switch (vm_cc_cme(cc)->def->body.optimized.type) {
266 case OPTIMIZED_METHOD_TYPE_SEND:
267 ret = send_internal(calling->argc, argv, calling->recv, calling->kw_splat ? CALL_FCALL_KW : CALL_FCALL);
268 goto success;
269 case OPTIMIZED_METHOD_TYPE_CALL:
271 rb_proc_t *proc;
272 GetProcPtr(calling->recv, proc);
273 ret = rb_vm_invoke_proc(ec, proc, calling->argc, argv, calling->kw_splat, calling->block_handler);
274 goto success;
276 case OPTIMIZED_METHOD_TYPE_STRUCT_AREF:
277 vm_call_check_arity(calling, 0, argv);
278 ret = vm_call_opt_struct_aref0(ec, calling);
279 goto success;
280 case OPTIMIZED_METHOD_TYPE_STRUCT_ASET:
281 vm_call_check_arity(calling, 1, argv);
282 ret = vm_call_opt_struct_aset0(ec, calling, argv[0]);
283 goto success;
284 default:
285 rb_bug("vm_call0: unsupported optimized method type (%d)", vm_cc_cme(cc)->def->body.optimized.type);
287 break;
288 case VM_METHOD_TYPE_UNDEF:
289 break;
291 rb_bug("vm_call0: unsupported method type (%d)", vm_cc_cme(cc)->def->type);
292 return Qundef;
294 success:
295 RUBY_VM_CHECK_INTS(ec);
296 return ret;
299 MJIT_FUNC_EXPORTED VALUE
300 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)
302 return rb_vm_call0(ec, recv, id, argc, argv, me, kw_splat);
305 static inline VALUE
306 vm_call_super(rb_execution_context_t *ec, int argc, const VALUE *argv, int kw_splat)
308 VALUE recv = ec->cfp->self;
309 VALUE klass;
310 ID id;
311 rb_control_frame_t *cfp = ec->cfp;
312 const rb_callable_method_entry_t *me = rb_vm_frame_method_entry(cfp);
314 if (VM_FRAME_RUBYFRAME_P(cfp)) {
315 rb_bug("vm_call_super: should not be reached");
318 klass = RCLASS_ORIGIN(me->defined_class);
319 klass = RCLASS_SUPER(klass);
320 id = me->def->original_id;
321 me = rb_callable_method_entry(klass, id);
323 if (!me) {
324 return method_missing(ec, recv, id, argc, argv, MISSING_SUPER, kw_splat);
326 return rb_vm_call_kw(ec, recv, id, argc, argv, me, kw_splat);
329 VALUE
330 rb_call_super_kw(int argc, const VALUE *argv, int kw_splat)
332 rb_execution_context_t *ec = GET_EC();
333 PASS_PASSED_BLOCK_HANDLER_EC(ec);
334 return vm_call_super(ec, argc, argv, kw_splat);
337 VALUE
338 rb_call_super(int argc, const VALUE *argv)
340 return rb_call_super_kw(argc, argv, RB_NO_KEYWORDS);
343 VALUE
344 rb_current_receiver(void)
346 const rb_execution_context_t *ec = GET_EC();
347 rb_control_frame_t *cfp;
348 if (!ec || !(cfp = ec->cfp)) {
349 rb_raise(rb_eRuntimeError, "no self, no life");
351 return cfp->self;
354 #endif /* #ifndef MJIT_HEADER */
356 static inline void
357 stack_check(rb_execution_context_t *ec)
359 if (!rb_ec_raised_p(ec, RAISED_STACKOVERFLOW) &&
360 rb_ec_stack_check(ec)) {
361 rb_ec_raised_set(ec, RAISED_STACKOVERFLOW);
362 rb_ec_stack_overflow(ec, FALSE);
366 #ifndef MJIT_HEADER
368 void
369 rb_check_stack_overflow(void)
371 #ifndef RB_THREAD_LOCAL_SPECIFIER
372 if (!ruby_current_ec_key) return;
373 #endif
374 rb_execution_context_t *ec = GET_EC();
375 if (ec) stack_check(ec);
378 NORETURN(static void uncallable_object(VALUE recv, ID mid));
379 static inline const rb_callable_method_entry_t *rb_search_method_entry(VALUE recv, ID mid);
380 static 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);
382 static const struct rb_callcache *
383 cc_new(VALUE klass, ID mid, int argc, const rb_callable_method_entry_t *cme)
385 const struct rb_callcache *cc = NULL;
387 RB_VM_LOCK_ENTER();
389 struct rb_class_cc_entries *ccs;
390 struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
391 VALUE ccs_data;
393 if (rb_id_table_lookup(cc_tbl, mid, &ccs_data)) {
394 // ok
395 ccs = (struct rb_class_cc_entries *)ccs_data;
397 else {
398 ccs = vm_ccs_create(klass, cme);
399 rb_id_table_insert(cc_tbl, mid, (VALUE)ccs);
402 for (int i=0; i<ccs->len; i++) {
403 cc = ccs->entries[i].cc;
404 if (vm_cc_cme(cc) == cme) {
405 break;
407 cc = NULL;
410 if (cc == NULL) {
411 const struct rb_callinfo *ci = vm_ci_new(mid, 0, argc, false); // TODO: proper ci
412 cc = vm_cc_new(klass, cme, vm_call_general);
413 METHOD_ENTRY_CACHED_SET((struct rb_callable_method_entry_struct *)cme);
414 vm_ccs_push(klass, ccs, ci, cc);
417 RB_VM_LOCK_LEAVE();
419 return cc;
422 static VALUE
423 gccct_hash(VALUE klass, ID mid)
425 return (klass >> 3) ^ (VALUE)mid;
428 NOINLINE(static const struct rb_callcache *gccct_method_search_slowpath(rb_vm_t *vm, VALUE klass, ID mid, int argc, unsigned int index));
430 static const struct rb_callcache *
431 gccct_method_search_slowpath(rb_vm_t *vm, VALUE klass, ID mid, int argc, unsigned int index)
433 const rb_callable_method_entry_t *cme = rb_callable_method_entry(klass, mid);
434 const struct rb_callcache *cc;
436 if (cme != NULL) {
437 cc = cc_new(klass, mid, argc, cme);
439 else {
440 cc = NULL;
443 return vm->global_cc_cache_table[index] = cc;
446 static inline const struct rb_callcache *
447 gccct_method_search(rb_execution_context_t *ec, VALUE recv, ID mid, int argc)
449 VALUE klass;
451 if (!SPECIAL_CONST_P(recv)) {
452 klass = RBASIC_CLASS(recv);
453 if (UNLIKELY(!klass)) uncallable_object(recv, mid);
455 else {
456 klass = CLASS_OF(recv);
459 // search global method cache
460 unsigned int index = (unsigned int)(gccct_hash(klass, mid) % VM_GLOBAL_CC_CACHE_TABLE_SIZE);
461 rb_vm_t *vm = rb_ec_vm_ptr(ec);
462 const struct rb_callcache *cc = vm->global_cc_cache_table[index];
464 if (LIKELY(cc)) {
465 if (LIKELY(vm_cc_class_check(cc, klass))) {
466 const rb_callable_method_entry_t *cme = vm_cc_cme(cc);
467 if (LIKELY(!METHOD_ENTRY_INVALIDATED(cme) &&
468 cme->called_id == mid)) {
470 VM_ASSERT(vm_cc_check_cme(cc, rb_callable_method_entry(klass, mid)));
471 RB_DEBUG_COUNTER_INC(gccct_hit);
473 return cc;
477 else {
478 RB_DEBUG_COUNTER_INC(gccct_null);
481 RB_DEBUG_COUNTER_INC(gccct_miss);
482 return gccct_method_search_slowpath(vm, klass, mid, argc, index);
486 * \internal
487 * calls the specified method.
489 * This function is called by functions in rb_call* family.
490 * \param ec current execution context
491 * \param recv receiver of the method
492 * \param mid an ID that represents the name of the method
493 * \param argc the number of method arguments
494 * \param argv a pointer to an array of method arguments
495 * \param scope
496 * \param self self in the caller. Qundef means no self is considered and
497 * protected methods cannot be called
499 * \note \a self is used in order to controlling access to protected methods.
501 static inline VALUE
502 rb_call0(rb_execution_context_t *ec,
503 VALUE recv, ID mid, int argc, const VALUE *argv,
504 call_type call_scope, VALUE self)
506 enum method_missing_reason call_status;
507 call_type scope = call_scope;
508 int kw_splat = RB_NO_KEYWORDS;
510 switch (scope) {
511 case CALL_PUBLIC_KW:
512 scope = CALL_PUBLIC;
513 kw_splat = 1;
514 break;
515 case CALL_FCALL_KW:
516 scope = CALL_FCALL;
517 kw_splat = 1;
518 break;
519 default:
520 break;
523 const struct rb_callcache *cc = gccct_method_search(ec, recv, mid, argc);
525 if (scope == CALL_PUBLIC) {
526 RB_DEBUG_COUNTER_INC(call0_public);
528 const rb_callable_method_entry_t *cc_cme = cc ? vm_cc_cme(cc) : NULL;
529 const rb_callable_method_entry_t *cme = callable_method_entry_refeinements0(CLASS_OF(recv), mid, NULL, true, cc_cme);
530 call_status = rb_method_call_status(ec, cme, scope, self);
532 if (UNLIKELY(call_status != MISSING_NONE)) {
533 return method_missing(ec, recv, mid, argc, argv, call_status, kw_splat);
535 else if (UNLIKELY(cc_cme != cme)) { // refinement is solved
536 stack_check(ec);
537 return rb_vm_call_kw(ec, recv, mid, argc, argv, cme, kw_splat);
540 else {
541 RB_DEBUG_COUNTER_INC(call0_other);
542 call_status = rb_method_call_status(ec, cc ? vm_cc_cme(cc) : NULL, scope, self);
544 if (UNLIKELY(call_status != MISSING_NONE)) {
545 return method_missing(ec, recv, mid, argc, argv, call_status, kw_splat);
549 stack_check(ec);
550 return vm_call0_cc(ec, recv, mid, argc, argv, cc, kw_splat);
553 struct rescue_funcall_args {
554 VALUE defined_class;
555 VALUE recv;
556 ID mid;
557 rb_execution_context_t *ec;
558 const rb_callable_method_entry_t *cme;
559 unsigned int respond: 1;
560 unsigned int respond_to_missing: 1;
561 int argc;
562 const VALUE *argv;
563 int kw_splat;
566 static VALUE
567 check_funcall_exec(VALUE v)
569 struct rescue_funcall_args *args = (void *)v;
570 return call_method_entry(args->ec, args->defined_class,
571 args->recv, idMethodMissing,
572 args->cme, args->argc, args->argv, args->kw_splat);
575 static VALUE
576 check_funcall_failed(VALUE v, VALUE e)
578 struct rescue_funcall_args *args = (void *)v;
579 int ret = args->respond;
580 if (!ret) {
581 switch (method_boundp(args->defined_class, args->mid,
582 BOUND_PRIVATE|BOUND_RESPONDS)) {
583 case 2:
584 ret = TRUE;
585 break;
586 case 0:
587 ret = args->respond_to_missing;
588 break;
589 default:
590 ret = FALSE;
591 break;
594 if (ret) {
595 rb_exc_raise(e);
597 return Qundef;
600 static int
601 check_funcall_respond_to(rb_execution_context_t *ec, VALUE klass, VALUE recv, ID mid)
603 return vm_respond_to(ec, klass, recv, mid, TRUE);
606 static int
607 check_funcall_callable(rb_execution_context_t *ec, const rb_callable_method_entry_t *me)
609 return rb_method_call_status(ec, me, CALL_FCALL, ec->cfp->self) == MISSING_NONE;
612 static VALUE
613 check_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)
615 struct rescue_funcall_args args;
616 const rb_callable_method_entry_t *cme;
617 VALUE ret = Qundef;
619 ret = basic_obj_respond_to_missing(ec, klass, recv,
620 ID2SYM(mid), Qtrue);
621 if (!RTEST(ret)) return def;
622 args.respond = respond > 0;
623 args.respond_to_missing = (ret != Qundef);
624 ret = def;
625 cme = callable_method_entry(klass, idMethodMissing, &args.defined_class);
627 if (cme && !METHOD_ENTRY_BASIC(cme)) {
628 VALUE argbuf, *new_args = ALLOCV_N(VALUE, argbuf, argc+1);
630 new_args[0] = ID2SYM(mid);
631 #ifdef __GLIBC__
632 if (!argv) {
633 static const VALUE buf = Qfalse;
634 VM_ASSERT(argc == 0);
635 argv = &buf;
637 #endif
638 MEMCPY(new_args+1, argv, VALUE, argc);
639 ec->method_missing_reason = MISSING_NOENTRY;
640 args.ec = ec;
641 args.recv = recv;
642 args.cme = cme;
643 args.mid = mid;
644 args.argc = argc + 1;
645 args.argv = new_args;
646 args.kw_splat = kw_splat;
647 ret = rb_rescue2(check_funcall_exec, (VALUE)&args,
648 check_funcall_failed, (VALUE)&args,
649 rb_eNoMethodError, (VALUE)0);
650 ALLOCV_END(argbuf);
652 return ret;
655 static VALUE rb_check_funcall_default_kw(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE def, int kw_splat);
657 VALUE
658 rb_check_funcall_kw(VALUE recv, ID mid, int argc, const VALUE *argv, int kw_splat)
660 return rb_check_funcall_default_kw(recv, mid, argc, argv, Qundef, kw_splat);
663 VALUE
664 rb_check_funcall(VALUE recv, ID mid, int argc, const VALUE *argv)
666 return rb_check_funcall_default_kw(recv, mid, argc, argv, Qundef, RB_NO_KEYWORDS);
669 static VALUE
670 rb_check_funcall_default_kw(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE def, int kw_splat)
672 VM_ASSERT(ruby_thread_has_gvl_p());
674 VALUE klass = CLASS_OF(recv);
675 const rb_callable_method_entry_t *me;
676 rb_execution_context_t *ec = GET_EC();
677 int respond = check_funcall_respond_to(ec, klass, recv, mid);
679 if (!respond)
680 return def;
682 me = rb_search_method_entry(recv, mid);
683 if (!check_funcall_callable(ec, me)) {
684 VALUE ret = check_funcall_missing(ec, klass, recv, mid, argc, argv,
685 respond, def, kw_splat);
686 if (ret == Qundef) ret = def;
687 return ret;
689 stack_check(ec);
690 return rb_vm_call_kw(ec, recv, mid, argc, argv, me, kw_splat);
693 VALUE
694 rb_check_funcall_default(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE def)
696 return rb_check_funcall_default_kw(recv, mid, argc, argv, def, RB_NO_KEYWORDS);
699 VALUE
700 rb_check_funcall_with_hook_kw(VALUE recv, ID mid, int argc, const VALUE *argv,
701 rb_check_funcall_hook *hook, VALUE arg, int kw_splat)
703 VALUE klass = CLASS_OF(recv);
704 const rb_callable_method_entry_t *me;
705 rb_execution_context_t *ec = GET_EC();
706 int respond = check_funcall_respond_to(ec, klass, recv, mid);
708 if (!respond) {
709 (*hook)(FALSE, recv, mid, argc, argv, arg);
710 return Qundef;
713 me = rb_search_method_entry(recv, mid);
714 if (!check_funcall_callable(ec, me)) {
715 VALUE ret = check_funcall_missing(ec, klass, recv, mid, argc, argv,
716 respond, Qundef, kw_splat);
717 (*hook)(ret != Qundef, recv, mid, argc, argv, arg);
718 return ret;
720 stack_check(ec);
721 (*hook)(TRUE, recv, mid, argc, argv, arg);
722 return rb_vm_call_kw(ec, recv, mid, argc, argv, me, kw_splat);
725 VALUE
726 rb_check_funcall_with_hook(VALUE recv, ID mid, int argc, const VALUE *argv,
727 rb_check_funcall_hook *hook, VALUE arg)
729 return rb_check_funcall_with_hook_kw(recv, mid, argc, argv, hook, arg, RB_NO_KEYWORDS);
732 const char *
733 rb_type_str(enum ruby_value_type type)
735 #define type_case(t) t: return #t
736 switch (type) {
737 case type_case(T_NONE);
738 case type_case(T_OBJECT);
739 case type_case(T_CLASS);
740 case type_case(T_MODULE);
741 case type_case(T_FLOAT);
742 case type_case(T_STRING);
743 case type_case(T_REGEXP);
744 case type_case(T_ARRAY);
745 case type_case(T_HASH);
746 case type_case(T_STRUCT);
747 case type_case(T_BIGNUM);
748 case type_case(T_FILE);
749 case type_case(T_DATA);
750 case type_case(T_MATCH);
751 case type_case(T_COMPLEX);
752 case type_case(T_RATIONAL);
753 case type_case(T_NIL);
754 case type_case(T_TRUE);
755 case type_case(T_FALSE);
756 case type_case(T_SYMBOL);
757 case type_case(T_FIXNUM);
758 case type_case(T_IMEMO);
759 case type_case(T_UNDEF);
760 case type_case(T_NODE);
761 case type_case(T_ICLASS);
762 case type_case(T_ZOMBIE);
763 case type_case(T_MOVED);
764 case T_MASK: break;
766 #undef type_case
767 return NULL;
770 static void
771 uncallable_object(VALUE recv, ID mid)
773 VALUE flags;
774 int type;
775 const char *typestr;
776 VALUE mname = rb_id2str(mid);
778 if (SPECIAL_CONST_P(recv)) {
779 rb_raise(rb_eNotImpError,
780 "method `%"PRIsVALUE"' called on unexpected immediate object (%p)",
781 mname, (void *)recv);
783 else if ((flags = RBASIC(recv)->flags) == 0) {
784 rb_raise(rb_eNotImpError,
785 "method `%"PRIsVALUE"' called on terminated object (%p)",
786 mname, (void *)recv);
788 else if (!(typestr = rb_type_str(type = BUILTIN_TYPE(recv)))) {
789 rb_raise(rb_eNotImpError,
790 "method `%"PRIsVALUE"' called on broken T_?""?""?(0x%02x) object"
791 " (%p flags=0x%"PRIxVALUE")",
792 mname, type, (void *)recv, flags);
794 else if (T_OBJECT <= type && type < T_NIL) {
795 rb_raise(rb_eNotImpError,
796 "method `%"PRIsVALUE"' called on hidden %s object"
797 " (%p flags=0x%"PRIxVALUE")",
798 mname, typestr, (void *)recv, flags);
800 else {
801 rb_raise(rb_eNotImpError,
802 "method `%"PRIsVALUE"' called on unexpected %s object"
803 " (%p flags=0x%"PRIxVALUE")",
804 mname, typestr, (void *)recv, flags);
808 static inline const rb_callable_method_entry_t *
809 rb_search_method_entry(VALUE recv, ID mid)
811 VALUE klass = CLASS_OF(recv);
813 if (!klass) uncallable_object(recv, mid);
814 return rb_callable_method_entry(klass, mid);
817 static inline enum method_missing_reason
818 rb_method_call_status(rb_execution_context_t *ec, const rb_callable_method_entry_t *me, call_type scope, VALUE self)
820 if (UNLIKELY(UNDEFINED_METHOD_ENTRY_P(me))) {
821 goto undefined;
823 else if (UNLIKELY(me->def->type == VM_METHOD_TYPE_REFINED)) {
824 me = rb_resolve_refined_method_callable(Qnil, me);
825 if (UNDEFINED_METHOD_ENTRY_P(me)) goto undefined;
828 rb_method_visibility_t visi = METHOD_ENTRY_VISI(me);
830 /* receiver specified form for private method */
831 if (UNLIKELY(visi != METHOD_VISI_PUBLIC)) {
832 if (me->def->original_id == idMethodMissing) {
833 return MISSING_NONE;
835 else if (visi == METHOD_VISI_PRIVATE &&
836 scope == CALL_PUBLIC) {
837 return MISSING_PRIVATE;
839 /* self must be kind of a specified form for protected method */
840 else if (visi == METHOD_VISI_PROTECTED &&
841 scope == CALL_PUBLIC) {
843 VALUE defined_class = me->owner;
844 if (RB_TYPE_P(defined_class, T_ICLASS)) {
845 defined_class = RBASIC(defined_class)->klass;
848 if (self == Qundef || !rb_obj_is_kind_of(self, defined_class)) {
849 return MISSING_PROTECTED;
854 return MISSING_NONE;
856 undefined:
857 return scope == CALL_VCALL ? MISSING_VCALL : MISSING_NOENTRY;
862 * \internal
863 * calls the specified method.
865 * This function is called by functions in rb_call* family.
866 * \param recv receiver
867 * \param mid an ID that represents the name of the method
868 * \param argc the number of method arguments
869 * \param argv a pointer to an array of method arguments
870 * \param scope
872 static inline VALUE
873 rb_call(VALUE recv, ID mid, int argc, const VALUE *argv, call_type scope)
875 rb_execution_context_t *ec = GET_EC();
876 return rb_call0(ec, recv, mid, argc, argv, scope, ec->cfp->self);
879 NORETURN(static void raise_method_missing(rb_execution_context_t *ec, int argc, const VALUE *argv,
880 VALUE obj, enum method_missing_reason call_status));
883 * call-seq:
884 * obj.method_missing(symbol [, *args] ) -> result
886 * Invoked by Ruby when <i>obj</i> is sent a message it cannot handle.
887 * <i>symbol</i> is the symbol for the method called, and <i>args</i>
888 * are any arguments that were passed to it. By default, the interpreter
889 * raises an error when this method is called. However, it is possible
890 * to override the method to provide more dynamic behavior.
891 * If it is decided that a particular method should not be handled, then
892 * <i>super</i> should be called, so that ancestors can pick up the
893 * missing method.
894 * The example below creates
895 * a class <code>Roman</code>, which responds to methods with names
896 * consisting of roman numerals, returning the corresponding integer
897 * values.
899 * class Roman
900 * def roman_to_int(str)
901 * # ...
902 * end
904 * def method_missing(symbol, *args)
905 * str = symbol.id2name
906 * begin
907 * roman_to_int(str)
908 * rescue
909 * super(symbol, *args)
910 * end
911 * end
912 * end
914 * r = Roman.new
915 * r.iv #=> 4
916 * r.xxiii #=> 23
917 * r.mm #=> 2000
918 * r.foo #=> NoMethodError
921 static VALUE
922 rb_method_missing(int argc, const VALUE *argv, VALUE obj)
924 rb_execution_context_t *ec = GET_EC();
925 raise_method_missing(ec, argc, argv, obj, ec->method_missing_reason);
926 UNREACHABLE_RETURN(Qnil);
929 MJIT_FUNC_EXPORTED VALUE
930 rb_make_no_method_exception(VALUE exc, VALUE format, VALUE obj,
931 int argc, const VALUE *argv, int priv)
933 VALUE name = argv[0];
935 if (!format) {
936 format = rb_fstring_lit("undefined method `%s' for %s%s%s");
938 if (exc == rb_eNoMethodError) {
939 VALUE args = rb_ary_new4(argc - 1, argv + 1);
940 return rb_nomethod_err_new(format, obj, name, args, priv);
942 else {
943 return rb_name_err_new(format, obj, name);
947 #endif /* #ifndef MJIT_HEADER */
949 static void
950 raise_method_missing(rb_execution_context_t *ec, int argc, const VALUE *argv, VALUE obj,
951 enum method_missing_reason last_call_status)
953 VALUE exc = rb_eNoMethodError;
954 VALUE format = 0;
956 if (UNLIKELY(argc == 0)) {
957 rb_raise(rb_eArgError, "no method name given");
959 else if (UNLIKELY(!SYMBOL_P(argv[0]))) {
960 const VALUE e = rb_eArgError; /* TODO: TypeError? */
961 rb_raise(e, "method name must be a Symbol but %"PRIsVALUE" is given",
962 rb_obj_class(argv[0]));
965 stack_check(ec);
967 if (last_call_status & MISSING_PRIVATE) {
968 format = rb_fstring_lit("private method `%s' called for %s%s%s");
970 else if (last_call_status & MISSING_PROTECTED) {
971 format = rb_fstring_lit("protected method `%s' called for %s%s%s");
973 else if (last_call_status & MISSING_VCALL) {
974 format = rb_fstring_lit("undefined local variable or method `%s' for %s%s%s");
975 exc = rb_eNameError;
977 else if (last_call_status & MISSING_SUPER) {
978 format = rb_fstring_lit("super: no superclass method `%s' for %s%s%s");
982 exc = rb_make_no_method_exception(exc, format, obj, argc, argv,
983 last_call_status & (MISSING_FCALL|MISSING_VCALL));
984 if (!(last_call_status & MISSING_MISSING)) {
985 rb_vm_pop_cfunc_frame();
987 rb_exc_raise(exc);
991 static void
992 vm_raise_method_missing(rb_execution_context_t *ec, int argc, const VALUE *argv,
993 VALUE obj, int call_status)
995 vm_passed_block_handler_set(ec, VM_BLOCK_HANDLER_NONE);
996 raise_method_missing(ec, argc, argv, obj, call_status | MISSING_MISSING);
999 static inline VALUE
1000 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)
1002 VALUE *nargv, result, work, klass;
1003 VALUE block_handler = vm_passed_block_handler(ec);
1004 const rb_callable_method_entry_t *me;
1006 ec->method_missing_reason = call_status;
1008 if (id == idMethodMissing) {
1009 goto missing;
1012 nargv = ALLOCV_N(VALUE, work, argc + 1);
1013 nargv[0] = ID2SYM(id);
1014 #ifdef __GLIBC__
1015 if (!argv) {
1016 static const VALUE buf = Qfalse;
1017 VM_ASSERT(argc == 0);
1018 argv = &buf;
1020 #endif
1021 MEMCPY(nargv + 1, argv, VALUE, argc);
1022 ++argc;
1023 argv = nargv;
1025 klass = CLASS_OF(obj);
1026 if (!klass) goto missing;
1027 me = rb_callable_method_entry(klass, idMethodMissing);
1028 if (!me || METHOD_ENTRY_BASIC(me)) goto missing;
1029 vm_passed_block_handler_set(ec, block_handler);
1030 result = rb_vm_call_kw(ec, obj, idMethodMissing, argc, argv, me, kw_splat);
1031 if (work) ALLOCV_END(work);
1032 return result;
1033 missing:
1034 raise_method_missing(ec, argc, argv, obj, call_status | MISSING_MISSING);
1035 UNREACHABLE_RETURN(Qundef);
1038 #ifndef MJIT_HEADER
1040 static inline VALUE
1041 rb_funcallv_scope(VALUE recv, ID mid, int argc, const VALUE *argv, call_type scope)
1043 rb_execution_context_t *ec = GET_EC();
1044 const struct rb_callcache *cc = gccct_method_search(ec, recv, mid, argc);
1045 VALUE self = ec->cfp->self;
1047 if (LIKELY(cc) &&
1048 LIKELY(rb_method_call_status(ec, vm_cc_cme(cc), scope, self) == MISSING_NONE)) {
1049 // fastpath
1050 return vm_call0_cc(ec, recv, mid, argc, argv, cc, false);
1052 else {
1053 return rb_call0(ec, recv, mid, argc, argv, scope, self);
1057 #ifdef rb_funcallv
1058 #undef rb_funcallv
1059 #endif
1060 VALUE
1061 rb_funcallv(VALUE recv, ID mid, int argc, const VALUE *argv)
1063 VM_ASSERT(ruby_thread_has_gvl_p());
1065 return rb_funcallv_scope(recv, mid, argc, argv, CALL_FCALL);
1068 VALUE
1069 rb_funcallv_kw(VALUE recv, ID mid, int argc, const VALUE *argv, int kw_splat)
1071 VM_ASSERT(ruby_thread_has_gvl_p());
1073 return rb_call(recv, mid, argc, argv, kw_splat ? CALL_FCALL_KW : CALL_FCALL);
1076 VALUE
1077 rb_apply(VALUE recv, ID mid, VALUE args)
1079 int argc;
1080 VALUE *argv, ret;
1082 argc = RARRAY_LENINT(args);
1083 if (argc >= 0x100) {
1084 args = rb_ary_subseq(args, 0, argc);
1085 RBASIC_CLEAR_CLASS(args);
1086 OBJ_FREEZE(args);
1087 ret = rb_call(recv, mid, argc, RARRAY_CONST_PTR(args), CALL_FCALL);
1088 RB_GC_GUARD(args);
1089 return ret;
1091 argv = ALLOCA_N(VALUE, argc);
1092 MEMCPY(argv, RARRAY_CONST_PTR_TRANSIENT(args), VALUE, argc);
1094 return rb_funcallv(recv, mid, argc, argv);
1097 #ifdef rb_funcall
1098 #undef rb_funcall
1099 #endif
1101 VALUE
1102 rb_funcall(VALUE recv, ID mid, int n, ...)
1104 VALUE *argv;
1105 va_list ar;
1107 if (n > 0) {
1108 long i;
1110 va_start(ar, n);
1112 argv = ALLOCA_N(VALUE, n);
1114 for (i = 0; i < n; i++) {
1115 argv[i] = va_arg(ar, VALUE);
1117 va_end(ar);
1119 else {
1120 argv = 0;
1122 return rb_funcallv(recv, mid, n, argv);
1126 * Calls a method only if it is the basic method of `ancestor`
1127 * otherwise returns Qundef;
1128 * \param recv receiver of the method
1129 * \param mid an ID that represents the name of the method
1130 * \param ancestor the Class that defined the basic method
1131 * \param argc the number of arguments
1132 * \param argv pointer to an array of method arguments
1133 * \param kw_splat bool
1135 VALUE
1136 rb_check_funcall_basic_kw(VALUE recv, ID mid, VALUE ancestor, int argc, const VALUE *argv, int kw_splat)
1138 const rb_callable_method_entry_t *cme;
1139 rb_execution_context_t *ec;
1140 VALUE klass = CLASS_OF(recv);
1141 if (!klass) return Qundef; /* hidden object */
1143 cme = rb_callable_method_entry(klass, mid);
1144 if (cme && METHOD_ENTRY_BASIC(cme) && RBASIC_CLASS(cme->defined_class) == ancestor) {
1145 ec = GET_EC();
1146 return rb_vm_call0(ec, recv, mid, argc, argv, cme, kw_splat);
1149 return Qundef;
1152 VALUE
1153 rb_funcallv_public(VALUE recv, ID mid, int argc, const VALUE *argv)
1155 return rb_funcallv_scope(recv, mid, argc, argv, CALL_PUBLIC);
1158 VALUE
1159 rb_funcallv_public_kw(VALUE recv, ID mid, int argc, const VALUE *argv, int kw_splat)
1161 return rb_call(recv, mid, argc, argv, kw_splat ? CALL_PUBLIC_KW : CALL_PUBLIC);
1164 VALUE
1165 rb_funcall_passing_block(VALUE recv, ID mid, int argc, const VALUE *argv)
1167 PASS_PASSED_BLOCK_HANDLER();
1168 return rb_funcallv_public(recv, mid, argc, argv);
1171 VALUE
1172 rb_funcall_passing_block_kw(VALUE recv, ID mid, int argc, const VALUE *argv, int kw_splat)
1174 PASS_PASSED_BLOCK_HANDLER();
1175 return rb_call(recv, mid, argc, argv, kw_splat ? CALL_PUBLIC_KW : CALL_PUBLIC);
1178 VALUE
1179 rb_funcall_with_block(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE passed_procval)
1181 if (!NIL_P(passed_procval)) {
1182 vm_passed_block_handler_set(GET_EC(), passed_procval);
1185 return rb_funcallv_public(recv, mid, argc, argv);
1188 VALUE
1189 rb_funcall_with_block_kw(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE passed_procval, int kw_splat)
1191 if (!NIL_P(passed_procval)) {
1192 vm_passed_block_handler_set(GET_EC(), passed_procval);
1195 return rb_call(recv, mid, argc, argv, kw_splat ? CALL_PUBLIC_KW : CALL_PUBLIC);
1198 static VALUE *
1199 current_vm_stack_arg(const rb_execution_context_t *ec, const VALUE *argv)
1201 rb_control_frame_t *prev_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(ec->cfp);
1202 if (RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(ec, prev_cfp)) return NULL;
1203 if (prev_cfp->sp + 1 != argv) return NULL;
1204 return prev_cfp->sp + 1;
1207 static VALUE
1208 send_internal(int argc, const VALUE *argv, VALUE recv, call_type scope)
1210 ID id;
1211 VALUE vid;
1212 VALUE self;
1213 VALUE ret, vargv = 0;
1214 rb_execution_context_t *ec = GET_EC();
1215 int public = scope == CALL_PUBLIC || scope == CALL_PUBLIC_KW;
1217 if (public) {
1218 self = Qundef;
1220 else {
1221 self = RUBY_VM_PREVIOUS_CONTROL_FRAME(ec->cfp)->self;
1224 if (argc == 0) {
1225 rb_raise(rb_eArgError, "no method name given");
1228 vid = *argv;
1230 id = rb_check_id(&vid);
1231 if (!id) {
1232 if (rb_method_basic_definition_p(CLASS_OF(recv), idMethodMissing)) {
1233 VALUE exc = rb_make_no_method_exception(rb_eNoMethodError, 0,
1234 recv, argc, argv,
1235 !public);
1236 rb_exc_raise(exc);
1238 if (!SYMBOL_P(*argv)) {
1239 VALUE *tmp_argv = current_vm_stack_arg(ec, argv);
1240 vid = rb_str_intern(vid);
1241 if (tmp_argv) {
1242 tmp_argv[0] = vid;
1244 else if (argc > 1) {
1245 tmp_argv = ALLOCV_N(VALUE, vargv, argc);
1246 tmp_argv[0] = vid;
1247 MEMCPY(tmp_argv+1, argv+1, VALUE, argc-1);
1248 argv = tmp_argv;
1250 else {
1251 argv = &vid;
1254 id = idMethodMissing;
1255 ec->method_missing_reason = MISSING_NOENTRY;
1257 else {
1258 argv++; argc--;
1260 PASS_PASSED_BLOCK_HANDLER_EC(ec);
1261 ret = rb_call0(ec, recv, id, argc, argv, scope, self);
1262 ALLOCV_END(vargv);
1263 return ret;
1266 static VALUE
1267 send_internal_kw(int argc, const VALUE *argv, VALUE recv, call_type scope)
1269 if (rb_keyword_given_p()) {
1270 switch (scope) {
1271 case CALL_PUBLIC:
1272 scope = CALL_PUBLIC_KW;
1273 break;
1274 case CALL_FCALL:
1275 scope = CALL_FCALL_KW;
1276 break;
1277 default:
1278 break;
1281 return send_internal(argc, argv, recv, scope);
1285 * call-seq:
1286 * foo.send(symbol [, args...]) -> obj
1287 * foo.__send__(symbol [, args...]) -> obj
1288 * foo.send(string [, args...]) -> obj
1289 * foo.__send__(string [, args...]) -> obj
1291 * Invokes the method identified by _symbol_, passing it any
1292 * arguments specified.
1293 * When the method is identified by a string, the string is converted
1294 * to a symbol.
1296 * BasicObject implements +__send__+, Kernel implements +send+.
1297 * <code>__send__</code> is safer than +send+
1298 * when _obj_ has the same method name like <code>Socket</code>.
1299 * See also <code>public_send</code>.
1301 * class Klass
1302 * def hello(*args)
1303 * "Hello " + args.join(' ')
1304 * end
1305 * end
1306 * k = Klass.new
1307 * k.send :hello, "gentle", "readers" #=> "Hello gentle readers"
1310 VALUE
1311 rb_f_send(int argc, VALUE *argv, VALUE recv)
1313 return send_internal_kw(argc, argv, recv, CALL_FCALL);
1317 * call-seq:
1318 * obj.public_send(symbol [, args...]) -> obj
1319 * obj.public_send(string [, args...]) -> obj
1321 * Invokes the method identified by _symbol_, passing it any
1322 * arguments specified. Unlike send, public_send calls public
1323 * methods only.
1324 * When the method is identified by a string, the string is converted
1325 * to a symbol.
1327 * 1.public_send(:puts, "hello") # causes NoMethodError
1330 static VALUE
1331 rb_f_public_send(int argc, VALUE *argv, VALUE recv)
1333 return send_internal_kw(argc, argv, recv, CALL_PUBLIC);
1336 /* yield */
1338 static inline VALUE
1339 rb_yield_0_kw(int argc, const VALUE * argv, int kw_splat)
1341 return vm_yield(GET_EC(), argc, argv, kw_splat);
1344 static inline VALUE
1345 rb_yield_0(int argc, const VALUE * argv)
1347 return vm_yield(GET_EC(), argc, argv, RB_NO_KEYWORDS);
1350 VALUE
1351 rb_yield_1(VALUE val)
1353 return rb_yield_0(1, &val);
1356 VALUE
1357 rb_yield(VALUE val)
1359 if (val == Qundef) {
1360 return rb_yield_0(0, NULL);
1362 else {
1363 return rb_yield_0(1, &val);
1367 #undef rb_yield_values
1368 VALUE
1369 rb_yield_values(int n, ...)
1371 if (n == 0) {
1372 return rb_yield_0(0, 0);
1374 else {
1375 int i;
1376 VALUE *argv;
1377 va_list args;
1378 argv = ALLOCA_N(VALUE, n);
1380 va_start(args, n);
1381 for (i=0; i<n; i++) {
1382 argv[i] = va_arg(args, VALUE);
1384 va_end(args);
1386 return rb_yield_0(n, argv);
1390 VALUE
1391 rb_yield_values2(int argc, const VALUE *argv)
1393 return rb_yield_0(argc, argv);
1396 VALUE
1397 rb_yield_values_kw(int argc, const VALUE *argv, int kw_splat)
1399 return rb_yield_0_kw(argc, argv, kw_splat);
1402 VALUE
1403 rb_yield_splat(VALUE values)
1405 VALUE tmp = rb_check_array_type(values);
1406 VALUE v;
1407 if (NIL_P(tmp)) {
1408 rb_raise(rb_eArgError, "not an array");
1410 v = rb_yield_0(RARRAY_LENINT(tmp), RARRAY_CONST_PTR(tmp));
1411 RB_GC_GUARD(tmp);
1412 return v;
1415 VALUE
1416 rb_yield_splat_kw(VALUE values, int kw_splat)
1418 VALUE tmp = rb_check_array_type(values);
1419 VALUE v;
1420 if (NIL_P(tmp)) {
1421 rb_raise(rb_eArgError, "not an array");
1423 v = rb_yield_0_kw(RARRAY_LENINT(tmp), RARRAY_CONST_PTR(tmp), kw_splat);
1424 RB_GC_GUARD(tmp);
1425 return v;
1428 VALUE
1429 rb_yield_force_blockarg(VALUE values)
1431 return vm_yield_force_blockarg(GET_EC(), values);
1434 VALUE
1435 rb_yield_block(RB_BLOCK_CALL_FUNC_ARGLIST(val, arg))
1437 return vm_yield_with_block(GET_EC(), argc, argv,
1438 NIL_P(blockarg) ? VM_BLOCK_HANDLER_NONE : blockarg,
1439 rb_keyword_given_p());
1442 static VALUE
1443 loop_i(VALUE _)
1445 for (;;) {
1446 rb_yield_0(0, 0);
1448 return Qnil;
1451 static VALUE
1452 loop_stop(VALUE dummy, VALUE exc)
1454 return rb_attr_get(exc, id_result);
1457 static VALUE
1458 rb_f_loop_size(VALUE self, VALUE args, VALUE eobj)
1460 return DBL2NUM(HUGE_VAL);
1464 * call-seq:
1465 * loop { block }
1466 * loop -> an_enumerator
1468 * Repeatedly executes the block.
1470 * If no block is given, an enumerator is returned instead.
1472 * loop do
1473 * print "Input: "
1474 * line = gets
1475 * break if !line or line =~ /^qQ/
1476 * # ...
1477 * end
1479 * StopIteration raised in the block breaks the loop. In this case,
1480 * loop returns the "result" value stored in the exception.
1482 * enum = Enumerator.new { |y|
1483 * y << "one"
1484 * y << "two"
1485 * :ok
1488 * result = loop {
1489 * puts enum.next
1490 * } #=> :ok
1493 static VALUE
1494 rb_f_loop(VALUE self)
1496 RETURN_SIZED_ENUMERATOR(self, 0, 0, rb_f_loop_size);
1497 return rb_rescue2(loop_i, (VALUE)0, loop_stop, (VALUE)0, rb_eStopIteration, (VALUE)0);
1500 #if VMDEBUG
1501 static const char *
1502 vm_frametype_name(const rb_control_frame_t *cfp);
1503 #endif
1505 static VALUE
1506 rb_iterate0(VALUE (* it_proc) (VALUE), VALUE data1,
1507 const struct vm_ifunc *const ifunc,
1508 rb_execution_context_t *ec)
1510 enum ruby_tag_type state;
1511 volatile VALUE retval = Qnil;
1512 rb_control_frame_t *const cfp = ec->cfp;
1514 EC_PUSH_TAG(ec);
1515 state = EC_EXEC_TAG();
1516 if (state == 0) {
1517 iter_retry:
1519 VALUE block_handler;
1521 if (ifunc) {
1522 struct rb_captured_block *captured = VM_CFP_TO_CAPTURED_BLOCK(cfp);
1523 captured->code.ifunc = ifunc;
1524 block_handler = VM_BH_FROM_IFUNC_BLOCK(captured);
1526 else {
1527 block_handler = VM_CF_BLOCK_HANDLER(cfp);
1529 vm_passed_block_handler_set(ec, block_handler);
1531 retval = (*it_proc) (data1);
1533 else if (state == TAG_BREAK || state == TAG_RETRY) {
1534 const struct vm_throw_data *const err = (struct vm_throw_data *)ec->errinfo;
1535 const rb_control_frame_t *const escape_cfp = THROW_DATA_CATCH_FRAME(err);
1537 if (cfp == escape_cfp) {
1538 rb_vm_rewind_cfp(ec, cfp);
1540 state = 0;
1541 ec->tag->state = TAG_NONE;
1542 ec->errinfo = Qnil;
1544 if (state == TAG_RETRY) goto iter_retry;
1545 retval = THROW_DATA_VAL(err);
1547 else if (0) {
1548 SDR(); fprintf(stderr, "%p, %p\n", (void *)cfp, (void *)escape_cfp);
1551 EC_POP_TAG();
1553 if (state) {
1554 EC_JUMP_TAG(ec, state);
1556 return retval;
1559 static VALUE
1560 rb_iterate_internal(VALUE (* it_proc)(VALUE), VALUE data1,
1561 rb_block_call_func_t bl_proc, VALUE data2)
1563 return rb_iterate0(it_proc, data1,
1564 bl_proc ? rb_vm_ifunc_proc_new(bl_proc, (void *)data2) : 0,
1565 GET_EC());
1568 VALUE
1569 rb_iterate(VALUE (* it_proc)(VALUE), VALUE data1,
1570 rb_block_call_func_t bl_proc, VALUE data2)
1572 return rb_iterate_internal(it_proc, data1, bl_proc, data2);
1575 struct iter_method_arg {
1576 VALUE obj;
1577 ID mid;
1578 int argc;
1579 const VALUE *argv;
1580 int kw_splat;
1583 static VALUE
1584 iterate_method(VALUE obj)
1586 const struct iter_method_arg * arg =
1587 (struct iter_method_arg *) obj;
1589 return rb_call(arg->obj, arg->mid, arg->argc, arg->argv, arg->kw_splat ? CALL_FCALL_KW : CALL_FCALL);
1592 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);
1594 VALUE
1595 rb_block_call(VALUE obj, ID mid, int argc, const VALUE * argv,
1596 rb_block_call_func_t bl_proc, VALUE data2)
1598 return rb_block_call_kw(obj, mid, argc, argv, bl_proc, data2, RB_NO_KEYWORDS);
1601 VALUE
1602 rb_block_call_kw(VALUE obj, ID mid, int argc, const VALUE * argv,
1603 rb_block_call_func_t bl_proc, VALUE data2, int kw_splat)
1605 struct iter_method_arg arg;
1607 arg.obj = obj;
1608 arg.mid = mid;
1609 arg.argc = argc;
1610 arg.argv = argv;
1611 arg.kw_splat = kw_splat;
1612 return rb_iterate_internal(iterate_method, (VALUE)&arg, bl_proc, data2);
1615 VALUE
1616 rb_lambda_call(VALUE obj, ID mid, int argc, const VALUE *argv,
1617 rb_block_call_func_t bl_proc, int min_argc, int max_argc,
1618 VALUE data2)
1620 struct iter_method_arg arg;
1621 struct vm_ifunc *block;
1623 if (!bl_proc) rb_raise(rb_eArgError, "NULL lambda function");
1624 arg.obj = obj;
1625 arg.mid = mid;
1626 arg.argc = argc;
1627 arg.argv = argv;
1628 arg.kw_splat = 0;
1629 block = rb_vm_ifunc_new(bl_proc, (void *)data2, min_argc, max_argc);
1630 return rb_iterate0(iterate_method, (VALUE)&arg, block, GET_EC());
1633 static VALUE
1634 iterate_check_method(VALUE obj)
1636 const struct iter_method_arg * arg =
1637 (struct iter_method_arg *) obj;
1639 return rb_check_funcall(arg->obj, arg->mid, arg->argc, arg->argv);
1642 VALUE
1643 rb_check_block_call(VALUE obj, ID mid, int argc, const VALUE *argv,
1644 rb_block_call_func_t bl_proc, VALUE data2)
1646 struct iter_method_arg arg;
1648 arg.obj = obj;
1649 arg.mid = mid;
1650 arg.argc = argc;
1651 arg.argv = argv;
1652 arg.kw_splat = 0;
1653 return rb_iterate_internal(iterate_check_method, (VALUE)&arg, bl_proc, data2);
1656 VALUE
1657 rb_each(VALUE obj)
1659 return rb_call(obj, idEach, 0, 0, CALL_FCALL);
1662 void rb_parser_warn_location(VALUE, int);
1664 static VALUE eval_default_path;
1666 static const rb_iseq_t *
1667 eval_make_iseq(VALUE src, VALUE fname, int line, const rb_binding_t *bind,
1668 const struct rb_block *base_block)
1670 const VALUE parser = rb_parser_new();
1671 const rb_iseq_t *const parent = vm_block_iseq(base_block);
1672 rb_iseq_t *iseq = NULL;
1673 rb_ast_t *ast;
1674 int isolated_depth = 0;
1676 int depth = 1;
1677 const VALUE *ep = vm_block_ep(base_block);
1679 while (1) {
1680 if (VM_ENV_FLAGS(ep, VM_ENV_FLAG_ISOLATED)) {
1681 isolated_depth = depth;
1682 break;
1684 else if (VM_ENV_LOCAL_P(ep)) {
1685 break;
1687 ep = VM_ENV_PREV_EP(ep);
1688 depth++;
1692 if (!fname) {
1693 fname = rb_source_location(&line);
1696 if (fname != Qundef) {
1697 if (!NIL_P(fname)) fname = rb_fstring(fname);
1699 else {
1700 fname = rb_fstring_lit("(eval)");
1701 if (!eval_default_path) {
1702 eval_default_path = rb_fstring_lit("(eval)");
1703 rb_gc_register_mark_object(eval_default_path);
1705 fname = eval_default_path;
1708 rb_parser_set_context(parser, parent, FALSE);
1709 ast = rb_parser_compile_string_path(parser, fname, src, line);
1710 if (ast->body.root) {
1711 iseq = rb_iseq_new_eval(&ast->body,
1712 parent->body->location.label,
1713 fname, Qnil, INT2FIX(line),
1714 parent, isolated_depth);
1716 rb_ast_dispose(ast);
1718 if (iseq != NULL) {
1719 if (0 && iseq) { /* for debug */
1720 VALUE disasm = rb_iseq_disasm(iseq);
1721 printf("%s\n", StringValuePtr(disasm));
1724 rb_exec_event_hook_script_compiled(GET_EC(), iseq, src);
1727 return iseq;
1730 static VALUE
1731 eval_string_with_cref(VALUE self, VALUE src, rb_cref_t *cref, VALUE file, int line)
1733 rb_execution_context_t *ec = GET_EC();
1734 struct rb_block block;
1735 const rb_iseq_t *iseq;
1736 rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(ec, ec->cfp);
1737 if (!cfp) {
1738 rb_raise(rb_eRuntimeError, "Can't eval on top of Fiber or Thread");
1741 block.as.captured = *VM_CFP_TO_CAPTURED_BLOCK(cfp);
1742 block.as.captured.self = self;
1743 block.as.captured.code.iseq = cfp->iseq;
1744 block.type = block_type_iseq;
1746 iseq = eval_make_iseq(src, file, line, NULL, &block);
1747 if (!iseq) {
1748 rb_exc_raise(ec->errinfo);
1751 /* TODO: what the code checking? */
1752 if (!cref && block.as.captured.code.val) {
1753 rb_cref_t *orig_cref = vm_get_cref(vm_block_ep(&block));
1754 cref = vm_cref_dup(orig_cref);
1756 vm_set_eval_stack(ec, iseq, cref, &block);
1758 /* kick */
1759 return vm_exec(ec, true);
1762 static VALUE
1763 eval_string_with_scope(VALUE scope, VALUE src, VALUE file, int line)
1765 rb_execution_context_t *ec = GET_EC();
1766 rb_binding_t *bind = Check_TypedStruct(scope, &ruby_binding_data_type);
1767 const rb_iseq_t *iseq = eval_make_iseq(src, file, line, bind, &bind->block);
1768 if (!iseq) {
1769 rb_exc_raise(ec->errinfo);
1772 vm_set_eval_stack(ec, iseq, NULL, &bind->block);
1774 /* save new env */
1775 if (iseq->body->local_table_size > 0) {
1776 vm_bind_update_env(scope, bind, vm_make_env_object(ec, ec->cfp));
1779 /* kick */
1780 return vm_exec(ec, true);
1784 * call-seq:
1785 * eval(string [, binding [, filename [,lineno]]]) -> obj
1787 * Evaluates the Ruby expression(s) in <em>string</em>. If
1788 * <em>binding</em> is given, which must be a Binding object, the
1789 * evaluation is performed in its context. If the optional
1790 * <em>filename</em> and <em>lineno</em> parameters are present, they
1791 * will be used when reporting syntax errors.
1793 * def get_binding(str)
1794 * return binding
1795 * end
1796 * str = "hello"
1797 * eval "str + ' Fred'" #=> "hello Fred"
1798 * eval "str + ' Fred'", get_binding("bye") #=> "bye Fred"
1801 VALUE
1802 rb_f_eval(int argc, const VALUE *argv, VALUE self)
1804 VALUE src, scope, vfile, vline;
1805 VALUE file = Qundef;
1806 int line = 1;
1808 rb_scan_args(argc, argv, "13", &src, &scope, &vfile, &vline);
1809 SafeStringValue(src);
1810 if (argc >= 3) {
1811 StringValue(vfile);
1813 if (argc >= 4) {
1814 line = NUM2INT(vline);
1817 if (!NIL_P(vfile))
1818 file = vfile;
1820 if (NIL_P(scope))
1821 return eval_string_with_cref(self, src, NULL, file, line);
1822 else
1823 return eval_string_with_scope(scope, src, file, line);
1826 /** @note This function name is not stable. */
1827 VALUE
1828 ruby_eval_string_from_file(const char *str, const char *filename)
1830 VALUE file = filename ? rb_str_new_cstr(filename) : 0;
1831 return eval_string_with_cref(rb_vm_top_self(), rb_str_new2(str), NULL, file, 1);
1834 VALUE
1835 rb_eval_string(const char *str)
1837 return ruby_eval_string_from_file(str, "eval");
1840 static VALUE
1841 eval_string_protect(VALUE str)
1843 return rb_eval_string((char *)str);
1846 VALUE
1847 rb_eval_string_protect(const char *str, int *pstate)
1849 return rb_protect(eval_string_protect, (VALUE)str, pstate);
1852 struct eval_string_wrap_arg {
1853 VALUE top_self;
1854 VALUE klass;
1855 const char *str;
1858 static VALUE
1859 eval_string_wrap_protect(VALUE data)
1861 const struct eval_string_wrap_arg *const arg = (struct eval_string_wrap_arg*)data;
1862 rb_cref_t *cref = rb_vm_cref_new_toplevel();
1863 cref->klass_or_self = arg->klass;
1864 return eval_string_with_cref(arg->top_self, rb_str_new_cstr(arg->str), cref, rb_str_new_cstr("eval"), 1);
1867 VALUE
1868 rb_eval_string_wrap(const char *str, int *pstate)
1870 int state;
1871 rb_thread_t *th = GET_THREAD();
1872 VALUE self = th->top_self;
1873 VALUE wrapper = th->top_wrapper;
1874 VALUE val;
1875 struct eval_string_wrap_arg data;
1877 th->top_wrapper = rb_module_new();
1878 th->top_self = rb_obj_clone(rb_vm_top_self());
1879 rb_extend_object(th->top_self, th->top_wrapper);
1881 data.top_self = th->top_self;
1882 data.klass = th->top_wrapper;
1883 data.str = str;
1885 val = rb_protect(eval_string_wrap_protect, (VALUE)&data, &state);
1887 th->top_self = self;
1888 th->top_wrapper = wrapper;
1890 if (pstate) {
1891 *pstate = state;
1893 else if (state != TAG_NONE) {
1894 EC_JUMP_TAG(th->ec, state);
1896 return val;
1899 VALUE
1900 rb_eval_cmd_kw(VALUE cmd, VALUE arg, int kw_splat)
1902 enum ruby_tag_type state;
1903 volatile VALUE val = Qnil; /* OK */
1904 rb_execution_context_t * volatile ec = GET_EC();
1906 EC_PUSH_TAG(ec);
1907 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
1908 if (!RB_TYPE_P(cmd, T_STRING)) {
1909 val = rb_funcallv_kw(cmd, idCall, RARRAY_LENINT(arg),
1910 RARRAY_CONST_PTR(arg), kw_splat);
1912 else {
1913 val = eval_string_with_cref(rb_vm_top_self(), cmd, NULL, 0, 0);
1916 EC_POP_TAG();
1918 if (state) EC_JUMP_TAG(ec, state);
1919 return val;
1922 /* block eval under the class/module context */
1924 static VALUE
1925 yield_under(VALUE self, int singleton, int argc, const VALUE *argv, int kw_splat)
1927 rb_execution_context_t *ec = GET_EC();
1928 rb_control_frame_t *cfp = ec->cfp;
1929 VALUE block_handler = VM_CF_BLOCK_HANDLER(cfp);
1930 VALUE new_block_handler = 0;
1931 const struct rb_captured_block *captured = NULL;
1932 struct rb_captured_block new_captured;
1933 const VALUE *ep = NULL;
1934 rb_cref_t *cref;
1935 int is_lambda = FALSE;
1937 if (block_handler != VM_BLOCK_HANDLER_NONE) {
1938 again:
1939 switch (vm_block_handler_type(block_handler)) {
1940 case block_handler_type_iseq:
1941 captured = VM_BH_TO_CAPT_BLOCK(block_handler);
1942 new_captured = *captured;
1943 new_block_handler = VM_BH_FROM_ISEQ_BLOCK(&new_captured);
1944 break;
1945 case block_handler_type_ifunc:
1946 captured = VM_BH_TO_CAPT_BLOCK(block_handler);
1947 new_captured = *captured;
1948 new_block_handler = VM_BH_FROM_IFUNC_BLOCK(&new_captured);
1949 break;
1950 case block_handler_type_proc:
1951 is_lambda = rb_proc_lambda_p(block_handler) != Qfalse;
1952 block_handler = vm_proc_to_block_handler(VM_BH_TO_PROC(block_handler));
1953 goto again;
1954 case block_handler_type_symbol:
1955 return rb_sym_proc_call(SYM2ID(VM_BH_TO_SYMBOL(block_handler)),
1956 argc, argv, kw_splat,
1957 VM_BLOCK_HANDLER_NONE);
1960 new_captured.self = self;
1961 ep = captured->ep;
1963 VM_FORCE_WRITE_SPECIAL_CONST(&VM_CF_LEP(ec->cfp)[VM_ENV_DATA_INDEX_SPECVAL], new_block_handler);
1966 VM_ASSERT(singleton || RB_TYPE_P(self, T_MODULE) || RB_TYPE_P(self, T_CLASS));
1967 cref = vm_cref_push(ec, self, ep, TRUE, singleton);
1969 return vm_yield_with_cref(ec, argc, argv, kw_splat, cref, is_lambda);
1972 VALUE
1973 rb_yield_refine_block(VALUE refinement, VALUE refinements)
1975 rb_execution_context_t *ec = GET_EC();
1976 VALUE block_handler = VM_CF_BLOCK_HANDLER(ec->cfp);
1978 if (vm_block_handler_type(block_handler) != block_handler_type_iseq) {
1979 rb_bug("rb_yield_refine_block: an iseq block is required");
1981 else {
1982 const struct rb_captured_block *captured = VM_BH_TO_ISEQ_BLOCK(block_handler);
1983 struct rb_captured_block new_captured = *captured;
1984 VALUE new_block_handler = VM_BH_FROM_ISEQ_BLOCK(&new_captured);
1985 const VALUE *ep = captured->ep;
1986 rb_cref_t *cref = vm_cref_push(ec, refinement, ep, TRUE, FALSE);
1987 CREF_REFINEMENTS_SET(cref, refinements);
1988 VM_FORCE_WRITE_SPECIAL_CONST(&VM_CF_LEP(ec->cfp)[VM_ENV_DATA_INDEX_SPECVAL], new_block_handler);
1989 new_captured.self = refinement;
1990 return vm_yield_with_cref(ec, 0, NULL, RB_NO_KEYWORDS, cref, FALSE);
1994 /* string eval under the class/module context */
1995 static VALUE
1996 eval_under(VALUE self, int singleton, VALUE src, VALUE file, int line)
1998 rb_cref_t *cref = vm_cref_push(GET_EC(), self, NULL, FALSE, singleton);
1999 SafeStringValue(src);
2001 return eval_string_with_cref(self, src, cref, file, line);
2004 static VALUE
2005 specific_eval(int argc, const VALUE *argv, VALUE self, int singleton, int kw_splat)
2007 if (rb_block_given_p()) {
2008 rb_check_arity(argc, 0, 0);
2009 return yield_under(self, singleton, 1, &self, kw_splat);
2011 else {
2012 VALUE file = Qundef;
2013 int line = 1;
2014 VALUE code;
2016 rb_check_arity(argc, 1, 3);
2017 code = argv[0];
2018 SafeStringValue(code);
2019 if (argc > 2)
2020 line = NUM2INT(argv[2]);
2021 if (argc > 1) {
2022 file = argv[1];
2023 if (!NIL_P(file)) StringValue(file);
2025 return eval_under(self, singleton, code, file, line);
2030 * call-seq:
2031 * obj.instance_eval(string [, filename [, lineno]] ) -> obj
2032 * obj.instance_eval {|obj| block } -> obj
2034 * Evaluates a string containing Ruby source code, or the given block,
2035 * within the context of the receiver (_obj_). In order to set the
2036 * context, the variable +self+ is set to _obj_ while
2037 * the code is executing, giving the code access to _obj_'s
2038 * instance variables and private methods.
2040 * When <code>instance_eval</code> is given a block, _obj_ is also
2041 * passed in as the block's only argument.
2043 * When <code>instance_eval</code> is given a +String+, the optional
2044 * second and third parameters supply a filename and starting line number
2045 * that are used when reporting compilation errors.
2047 * class KlassWithSecret
2048 * def initialize
2049 * @secret = 99
2050 * end
2051 * private
2052 * def the_secret
2053 * "Ssssh! The secret is #{@secret}."
2054 * end
2055 * end
2056 * k = KlassWithSecret.new
2057 * k.instance_eval { @secret } #=> 99
2058 * k.instance_eval { the_secret } #=> "Ssssh! The secret is 99."
2059 * k.instance_eval {|obj| obj == self } #=> true
2062 static VALUE
2063 rb_obj_instance_eval_internal(int argc, const VALUE *argv, VALUE self)
2065 return specific_eval(argc, argv, self, TRUE, RB_PASS_CALLED_KEYWORDS);
2068 VALUE
2069 rb_obj_instance_eval(int argc, const VALUE *argv, VALUE self)
2071 return specific_eval(argc, argv, self, TRUE, RB_NO_KEYWORDS);
2075 * call-seq:
2076 * obj.instance_exec(arg...) {|var...| block } -> obj
2078 * Executes the given block within the context of the receiver
2079 * (_obj_). In order to set the context, the variable +self+ is set
2080 * to _obj_ while the code is executing, giving the code access to
2081 * _obj_'s instance variables. Arguments are passed as block parameters.
2083 * class KlassWithSecret
2084 * def initialize
2085 * @secret = 99
2086 * end
2087 * end
2088 * k = KlassWithSecret.new
2089 * k.instance_exec(5) {|x| @secret+x } #=> 104
2092 static VALUE
2093 rb_obj_instance_exec_internal(int argc, const VALUE *argv, VALUE self)
2095 return yield_under(self, TRUE, argc, argv, RB_PASS_CALLED_KEYWORDS);
2098 VALUE
2099 rb_obj_instance_exec(int argc, const VALUE *argv, VALUE self)
2101 return yield_under(self, TRUE, argc, argv, RB_NO_KEYWORDS);
2105 * call-seq:
2106 * mod.class_eval(string [, filename [, lineno]]) -> obj
2107 * mod.class_eval {|mod| block } -> obj
2108 * mod.module_eval(string [, filename [, lineno]]) -> obj
2109 * mod.module_eval {|mod| block } -> obj
2111 * Evaluates the string or block in the context of _mod_, except that when
2112 * a block is given, constant/class variable lookup is not affected. This
2113 * can be used to add methods to a class. <code>module_eval</code> returns
2114 * the result of evaluating its argument. The optional _filename_ and
2115 * _lineno_ parameters set the text for error messages.
2117 * class Thing
2118 * end
2119 * a = %q{def hello() "Hello there!" end}
2120 * Thing.module_eval(a)
2121 * puts Thing.new.hello()
2122 * Thing.module_eval("invalid code", "dummy", 123)
2124 * <em>produces:</em>
2126 * Hello there!
2127 * dummy:123:in `module_eval': undefined local variable
2128 * or method `code' for Thing:Class
2131 static VALUE
2132 rb_mod_module_eval_internal(int argc, const VALUE *argv, VALUE mod)
2134 return specific_eval(argc, argv, mod, FALSE, RB_PASS_CALLED_KEYWORDS);
2137 VALUE
2138 rb_mod_module_eval(int argc, const VALUE *argv, VALUE mod)
2140 return specific_eval(argc, argv, mod, FALSE, RB_NO_KEYWORDS);
2144 * call-seq:
2145 * mod.module_exec(arg...) {|var...| block } -> obj
2146 * mod.class_exec(arg...) {|var...| block } -> obj
2148 * Evaluates the given block in the context of the class/module.
2149 * The method defined in the block will belong to the receiver.
2150 * Any arguments passed to the method will be passed to the block.
2151 * This can be used if the block needs to access instance variables.
2153 * class Thing
2154 * end
2155 * Thing.class_exec{
2156 * def hello() "Hello there!" end
2158 * puts Thing.new.hello()
2160 * <em>produces:</em>
2162 * Hello there!
2165 static VALUE
2166 rb_mod_module_exec_internal(int argc, const VALUE *argv, VALUE mod)
2168 return yield_under(mod, FALSE, argc, argv, RB_PASS_CALLED_KEYWORDS);
2171 VALUE
2172 rb_mod_module_exec(int argc, const VALUE *argv, VALUE mod)
2174 return yield_under(mod, FALSE, argc, argv, RB_NO_KEYWORDS);
2178 * Document-class: UncaughtThrowError
2180 * Raised when +throw+ is called with a _tag_ which does not have
2181 * corresponding +catch+ block.
2183 * throw "foo", "bar"
2185 * <em>raises the exception:</em>
2187 * UncaughtThrowError: uncaught throw "foo"
2190 static VALUE
2191 uncaught_throw_init(int argc, const VALUE *argv, VALUE exc)
2193 rb_check_arity(argc, 2, UNLIMITED_ARGUMENTS);
2194 rb_call_super(argc - 2, argv + 2);
2195 rb_ivar_set(exc, id_tag, argv[0]);
2196 rb_ivar_set(exc, id_value, argv[1]);
2197 return exc;
2201 * call-seq:
2202 * uncaught_throw.tag -> obj
2204 * Return the tag object which was called for.
2207 static VALUE
2208 uncaught_throw_tag(VALUE exc)
2210 return rb_ivar_get(exc, id_tag);
2214 * call-seq:
2215 * uncaught_throw.value -> obj
2217 * Return the return value which was called for.
2220 static VALUE
2221 uncaught_throw_value(VALUE exc)
2223 return rb_ivar_get(exc, id_value);
2227 * call-seq:
2228 * uncaught_throw.to_s -> string
2230 * Returns formatted message with the inspected tag.
2233 static VALUE
2234 uncaught_throw_to_s(VALUE exc)
2236 VALUE mesg = rb_attr_get(exc, id_mesg);
2237 VALUE tag = uncaught_throw_tag(exc);
2238 return rb_str_format(1, &tag, mesg);
2242 * call-seq:
2243 * throw(tag [, obj])
2245 * Transfers control to the end of the active +catch+ block
2246 * waiting for _tag_. Raises +UncaughtThrowError+ if there
2247 * is no +catch+ block for the _tag_. The optional second
2248 * parameter supplies a return value for the +catch+ block,
2249 * which otherwise defaults to +nil+. For examples, see
2250 * Kernel::catch.
2253 static VALUE
2254 rb_f_throw(int argc, VALUE *argv, VALUE _)
2256 VALUE tag, value;
2258 rb_scan_args(argc, argv, "11", &tag, &value);
2259 rb_throw_obj(tag, value);
2260 UNREACHABLE_RETURN(Qnil);
2263 void
2264 rb_throw_obj(VALUE tag, VALUE value)
2266 rb_execution_context_t *ec = GET_EC();
2267 struct rb_vm_tag *tt = ec->tag;
2269 while (tt) {
2270 if (tt->tag == tag) {
2271 tt->retval = value;
2272 break;
2274 tt = tt->prev;
2276 if (!tt) {
2277 VALUE desc[3];
2278 desc[0] = tag;
2279 desc[1] = value;
2280 desc[2] = rb_str_new_cstr("uncaught throw %p");
2281 rb_exc_raise(rb_class_new_instance(numberof(desc), desc, rb_eUncaughtThrow));
2284 ec->errinfo = (VALUE)THROW_DATA_NEW(tag, NULL, TAG_THROW);
2285 EC_JUMP_TAG(ec, TAG_THROW);
2288 void
2289 rb_throw(const char *tag, VALUE val)
2291 rb_throw_obj(rb_sym_intern_ascii_cstr(tag), val);
2294 static VALUE
2295 catch_i(RB_BLOCK_CALL_FUNC_ARGLIST(tag, _))
2297 return rb_yield_0(1, &tag);
2301 * call-seq:
2302 * catch([tag]) {|tag| block } -> obj
2304 * +catch+ executes its block. If +throw+ is not called, the block executes
2305 * normally, and +catch+ returns the value of the last expression evaluated.
2307 * catch(1) { 123 } # => 123
2309 * If <code>throw(tag2, val)</code> is called, Ruby searches up its stack for
2310 * a +catch+ block whose +tag+ has the same +object_id+ as _tag2_. When found,
2311 * the block stops executing and returns _val_ (or +nil+ if no second argument
2312 * was given to +throw+).
2314 * catch(1) { throw(1, 456) } # => 456
2315 * catch(1) { throw(1) } # => nil
2317 * When +tag+ is passed as the first argument, +catch+ yields it as the
2318 * parameter of the block.
2320 * catch(1) {|x| x + 2 } # => 3
2322 * When no +tag+ is given, +catch+ yields a new unique object (as from
2323 * +Object.new+) as the block parameter. This object can then be used as the
2324 * argument to +throw+, and will match the correct +catch+ block.
2326 * catch do |obj_A|
2327 * catch do |obj_B|
2328 * throw(obj_B, 123)
2329 * puts "This puts is not reached"
2330 * end
2332 * puts "This puts is displayed"
2333 * 456
2334 * end
2336 * # => 456
2338 * catch do |obj_A|
2339 * catch do |obj_B|
2340 * throw(obj_A, 123)
2341 * puts "This puts is still not reached"
2342 * end
2344 * puts "Now this puts is also not reached"
2345 * 456
2346 * end
2348 * # => 123
2351 static VALUE
2352 rb_f_catch(int argc, VALUE *argv, VALUE self)
2354 VALUE tag = rb_check_arity(argc, 0, 1) ? argv[0] : rb_obj_alloc(rb_cObject);
2355 return rb_catch_obj(tag, catch_i, 0);
2358 VALUE
2359 rb_catch(const char *tag, rb_block_call_func_t func, VALUE data)
2361 VALUE vtag = tag ? rb_sym_intern_ascii_cstr(tag) : rb_obj_alloc(rb_cObject);
2362 return rb_catch_obj(vtag, func, data);
2365 static VALUE
2366 vm_catch_protect(VALUE tag, rb_block_call_func *func, VALUE data,
2367 enum ruby_tag_type *stateptr, rb_execution_context_t *volatile ec)
2369 enum ruby_tag_type state;
2370 VALUE val = Qnil; /* OK */
2371 rb_control_frame_t *volatile saved_cfp = ec->cfp;
2373 EC_PUSH_TAG(ec);
2375 _tag.tag = tag;
2377 if ((state = EC_EXEC_TAG()) == TAG_NONE) {
2378 /* call with argc=1, argv = [tag], block = Qnil to insure compatibility */
2379 val = (*func)(tag, data, 1, (const VALUE *)&tag, Qnil);
2381 else if (state == TAG_THROW && THROW_DATA_VAL((struct vm_throw_data *)ec->errinfo) == tag) {
2382 rb_vm_rewind_cfp(ec, saved_cfp);
2383 val = ec->tag->retval;
2384 ec->errinfo = Qnil;
2385 state = 0;
2387 EC_POP_TAG();
2388 if (stateptr)
2389 *stateptr = state;
2391 return val;
2394 VALUE
2395 rb_catch_protect(VALUE t, rb_block_call_func *func, VALUE data, enum ruby_tag_type *stateptr)
2397 return vm_catch_protect(t, func, data, stateptr, GET_EC());
2400 VALUE
2401 rb_catch_obj(VALUE t, rb_block_call_func_t func, VALUE data)
2403 enum ruby_tag_type state;
2404 rb_execution_context_t *ec = GET_EC();
2405 VALUE val = vm_catch_protect(t, (rb_block_call_func *)func, data, &state, ec);
2406 if (state) EC_JUMP_TAG(ec, state);
2407 return val;
2410 static void
2411 local_var_list_init(struct local_var_list *vars)
2413 vars->tbl = rb_ident_hash_new();
2414 RBASIC_CLEAR_CLASS(vars->tbl);
2417 static VALUE
2418 local_var_list_finish(struct local_var_list *vars)
2420 /* TODO: not to depend on the order of st_table */
2421 VALUE ary = rb_hash_keys(vars->tbl);
2422 rb_hash_clear(vars->tbl);
2423 vars->tbl = 0;
2424 return ary;
2427 static int
2428 local_var_list_update(st_data_t *key, st_data_t *value, st_data_t arg, int existing)
2430 if (existing) return ST_STOP;
2431 *value = (st_data_t)Qtrue; /* INT2FIX(arg) */
2432 return ST_CONTINUE;
2435 static void
2436 local_var_list_add(const struct local_var_list *vars, ID lid)
2438 if (lid && rb_is_local_id(lid)) {
2439 /* should skip temporary variable */
2440 st_data_t idx = 0; /* tbl->num_entries */
2441 rb_hash_stlike_update(vars->tbl, ID2SYM(lid), local_var_list_update, idx);
2446 * call-seq:
2447 * local_variables -> array
2449 * Returns the names of the current local variables.
2451 * fred = 1
2452 * for i in 1..10
2453 * # ...
2454 * end
2455 * local_variables #=> [:fred, :i]
2458 static VALUE
2459 rb_f_local_variables(VALUE _)
2461 struct local_var_list vars;
2462 rb_execution_context_t *ec = GET_EC();
2463 rb_control_frame_t *cfp = vm_get_ruby_level_caller_cfp(ec, RUBY_VM_PREVIOUS_CONTROL_FRAME(ec->cfp));
2464 unsigned int i;
2466 local_var_list_init(&vars);
2467 while (cfp) {
2468 if (cfp->iseq) {
2469 for (i = 0; i < cfp->iseq->body->local_table_size; i++) {
2470 local_var_list_add(&vars, cfp->iseq->body->local_table[i]);
2473 if (!VM_ENV_LOCAL_P(cfp->ep)) {
2474 /* block */
2475 const VALUE *ep = VM_CF_PREV_EP(cfp);
2477 if (vm_collect_local_variables_in_heap(ep, &vars)) {
2478 break;
2480 else {
2481 while (cfp->ep != ep) {
2482 cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
2486 else {
2487 break;
2490 return local_var_list_finish(&vars);
2494 * call-seq:
2495 * block_given? -> true or false
2497 * Returns <code>true</code> if <code>yield</code> would execute a
2498 * block in the current context. The <code>iterator?</code> form
2499 * is mildly deprecated.
2501 * def try
2502 * if block_given?
2503 * yield
2504 * else
2505 * "no block"
2506 * end
2507 * end
2508 * try #=> "no block"
2509 * try { "hello" } #=> "hello"
2510 * try do "hello" end #=> "hello"
2513 static VALUE
2514 rb_f_block_given_p(VALUE _)
2516 rb_execution_context_t *ec = GET_EC();
2517 rb_control_frame_t *cfp = ec->cfp;
2518 cfp = vm_get_ruby_level_caller_cfp(ec, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
2520 return RBOOL(cfp != NULL && VM_CF_BLOCK_HANDLER(cfp) != VM_BLOCK_HANDLER_NONE);
2524 * call-seq:
2525 * iterator? -> true or false
2527 * Deprecated. Use block_given? instead.
2530 static VALUE
2531 rb_f_iterator_p(VALUE self)
2533 rb_warn_deprecated("iterator?", "block_given?");
2534 return rb_f_block_given_p(self);
2537 VALUE
2538 rb_current_realfilepath(void)
2540 const rb_execution_context_t *ec = GET_EC();
2541 rb_control_frame_t *cfp = ec->cfp;
2542 cfp = vm_get_ruby_level_caller_cfp(ec, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
2543 if (cfp != NULL) {
2544 VALUE path = rb_iseq_realpath(cfp->iseq);
2545 if (RTEST(path)) return path;
2546 // eval context
2547 path = rb_iseq_path(cfp->iseq);
2548 if (path == eval_default_path) {
2549 return Qnil;
2551 else {
2552 return path;
2555 return Qnil;
2558 void
2559 Init_vm_eval(void)
2561 rb_define_global_function("eval", rb_f_eval, -1);
2562 rb_define_global_function("local_variables", rb_f_local_variables, 0);
2563 rb_define_global_function("iterator?", rb_f_iterator_p, 0);
2564 rb_define_global_function("block_given?", rb_f_block_given_p, 0);
2566 rb_define_global_function("catch", rb_f_catch, -1);
2567 rb_define_global_function("throw", rb_f_throw, -1);
2569 rb_define_global_function("loop", rb_f_loop, 0);
2571 rb_define_method(rb_cBasicObject, "instance_eval", rb_obj_instance_eval_internal, -1);
2572 rb_define_method(rb_cBasicObject, "instance_exec", rb_obj_instance_exec_internal, -1);
2573 rb_define_private_method(rb_cBasicObject, "method_missing", rb_method_missing, -1);
2575 #if 1
2576 rb_add_method(rb_cBasicObject, id__send__,
2577 VM_METHOD_TYPE_OPTIMIZED, (void *)OPTIMIZED_METHOD_TYPE_SEND, METHOD_VISI_PUBLIC);
2578 rb_add_method(rb_mKernel, idSend,
2579 VM_METHOD_TYPE_OPTIMIZED, (void *)OPTIMIZED_METHOD_TYPE_SEND, METHOD_VISI_PUBLIC);
2580 #else
2581 rb_define_method(rb_cBasicObject, "__send__", rb_f_send, -1);
2582 rb_define_method(rb_mKernel, "send", rb_f_send, -1);
2583 #endif
2584 rb_define_method(rb_mKernel, "public_send", rb_f_public_send, -1);
2586 rb_define_method(rb_cModule, "module_exec", rb_mod_module_exec_internal, -1);
2587 rb_define_method(rb_cModule, "class_exec", rb_mod_module_exec_internal, -1);
2588 rb_define_method(rb_cModule, "module_eval", rb_mod_module_eval_internal, -1);
2589 rb_define_method(rb_cModule, "class_eval", rb_mod_module_eval_internal, -1);
2591 rb_eUncaughtThrow = rb_define_class("UncaughtThrowError", rb_eArgError);
2592 rb_define_method(rb_eUncaughtThrow, "initialize", uncaught_throw_init, -1);
2593 rb_define_method(rb_eUncaughtThrow, "tag", uncaught_throw_tag, 0);
2594 rb_define_method(rb_eUncaughtThrow, "value", uncaught_throw_value, 0);
2595 rb_define_method(rb_eUncaughtThrow, "to_s", uncaught_throw_to_s, 0);
2597 id_result = rb_intern_const("result");
2598 id_tag = rb_intern_const("tag");
2599 id_value = rb_intern_const("value");
2602 #endif /* #ifndef MJIT_HEADER */