1 /**********************************************************************
2 
3   vm_eval.c -
4 
5   $Author: nagachika $
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 
18 static inline VALUE method_missing(VALUE obj, ID id, int argc, const VALUE *argv, enum method_missing_reason call_status);
19 static inline VALUE vm_yield_with_cref(rb_execution_context_t *ec, int argc, const VALUE *argv, const rb_cref_t *cref, int is_lambda);
20 static inline VALUE vm_yield(rb_execution_context_t *ec, int argc, const VALUE *argv);
21 static inline VALUE vm_yield_with_block(rb_execution_context_t *ec, int argc, const VALUE *argv, VALUE block_handler);
22 static inline VALUE vm_yield_force_blockarg(rb_execution_context_t *ec, VALUE args);
23 VALUE vm_exec(rb_execution_context_t *ec, int 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);
26 
27 static VALUE rb_eUncaughtThrow;
28 static 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_TYPE_MAX
36 } call_type;
37 
38 static VALUE send_internal(int argc, const VALUE *argv, VALUE recv, call_type scope);
39 static VALUE vm_call0_body(rb_execution_context_t* ec, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc, const VALUE *argv);
40 
41 #ifndef MJIT_HEADER
42 
43 MJIT_FUNC_EXPORTED VALUE
rb_vm_call0(rb_execution_context_t * ec,VALUE recv,ID id,int argc,const VALUE * argv,const rb_callable_method_entry_t * me)44 rb_vm_call0(rb_execution_context_t *ec, VALUE recv, ID id, int argc, const VALUE *argv, const rb_callable_method_entry_t *me)
45 {
46     struct rb_calling_info calling_entry, *calling;
47     struct rb_call_info ci_entry;
48     struct rb_call_cache cc_entry;
49 
50     calling = &calling_entry;
51 
52     ci_entry.flag = 0;
53     ci_entry.mid = id;
54 
55     cc_entry.me = me;
56 
57     calling->recv = recv;
58     calling->argc = argc;
59 
60     return vm_call0_body(ec, calling, &ci_entry, &cc_entry, argv);
61 }
62 
63 static VALUE
vm_call0_cfunc_with_frame(rb_execution_context_t * ec,struct rb_calling_info * calling,const struct rb_call_info * ci,struct rb_call_cache * cc,const VALUE * argv)64 vm_call0_cfunc_with_frame(rb_execution_context_t* ec, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc, const VALUE *argv)
65 {
66     VALUE val;
67     const rb_callable_method_entry_t *me = cc->me;
68     const rb_method_cfunc_t *cfunc = &me->def->body.cfunc;
69     int len = cfunc->argc;
70     VALUE recv = calling->recv;
71     int argc = calling->argc;
72     ID mid = ci->mid;
73     VALUE block_handler = calling->block_handler;
74 
75     RUBY_DTRACE_CMETHOD_ENTRY_HOOK(ec, me->owner, me->def->original_id);
76     EXEC_EVENT_HOOK(ec, RUBY_EVENT_C_CALL, recv, me->def->original_id, mid, me->owner, Qnil);
77     {
78 	rb_control_frame_t *reg_cfp = ec->cfp;
79 
80 	vm_push_frame(ec, 0, VM_FRAME_MAGIC_CFUNC | VM_FRAME_FLAG_CFRAME | VM_ENV_FLAG_LOCAL, recv,
81 		      block_handler, (VALUE)me,
82 		      0, reg_cfp->sp, 0, 0);
83 
84 	if (len >= 0) rb_check_arity(argc, len, len);
85 
86 	val = (*cfunc->invoker)(cfunc->func, recv, argc, argv);
87 
88 	CHECK_CFP_CONSISTENCY("vm_call0_cfunc_with_frame");
89 	rb_vm_pop_frame(ec);
90     }
91     EXEC_EVENT_HOOK(ec, RUBY_EVENT_C_RETURN, recv, me->def->original_id, mid, me->owner, val);
92     RUBY_DTRACE_CMETHOD_RETURN_HOOK(ec, me->owner, me->def->original_id);
93 
94     return val;
95 }
96 
97 static VALUE
vm_call0_cfunc(rb_execution_context_t * ec,struct rb_calling_info * calling,const struct rb_call_info * ci,struct rb_call_cache * cc,const VALUE * argv)98 vm_call0_cfunc(rb_execution_context_t *ec, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc, const VALUE *argv)
99 {
100     return vm_call0_cfunc_with_frame(ec, calling, ci, cc, argv);
101 }
102 
103 /* `ci' should point temporal value (on stack value) */
104 static VALUE
vm_call0_body(rb_execution_context_t * ec,struct rb_calling_info * calling,const struct rb_call_info * ci,struct rb_call_cache * cc,const VALUE * argv)105 vm_call0_body(rb_execution_context_t *ec, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc, const VALUE *argv)
106 {
107     VALUE ret;
108 
109     calling->block_handler = vm_passed_block_handler(ec);
110 
111   again:
112     switch (cc->me->def->type) {
113       case VM_METHOD_TYPE_ISEQ:
114 	{
115 	    rb_control_frame_t *reg_cfp = ec->cfp;
116 	    int i;
117 
118 	    CHECK_VM_STACK_OVERFLOW(reg_cfp, calling->argc + 1);
119 
120 	    *reg_cfp->sp++ = calling->recv;
121 	    for (i = 0; i < calling->argc; i++) {
122 		*reg_cfp->sp++ = argv[i];
123 	    }
124 
125 	    vm_call_iseq_setup(ec, reg_cfp, calling, ci, cc);
126 	    VM_ENV_FLAGS_SET(ec->cfp->ep, VM_FRAME_FLAG_FINISH);
127 	    return vm_exec(ec, TRUE); /* CHECK_INTS in this function */
128 	}
129       case VM_METHOD_TYPE_NOTIMPLEMENTED:
130       case VM_METHOD_TYPE_CFUNC:
131 	ret = vm_call0_cfunc(ec, calling, ci, cc, argv);
132 	goto success;
133       case VM_METHOD_TYPE_ATTRSET:
134 	rb_check_arity(calling->argc, 1, 1);
135 	ret = rb_ivar_set(calling->recv, cc->me->def->body.attr.id, argv[0]);
136 	goto success;
137       case VM_METHOD_TYPE_IVAR:
138 	rb_check_arity(calling->argc, 0, 0);
139 	ret = rb_attr_get(calling->recv, cc->me->def->body.attr.id);
140 	goto success;
141       case VM_METHOD_TYPE_BMETHOD:
142 	ret = vm_call_bmethod_body(ec, calling, ci, cc, argv);
143 	goto success;
144       case VM_METHOD_TYPE_ZSUPER:
145       case VM_METHOD_TYPE_REFINED:
146 	{
147 	    const rb_method_type_t type = cc->me->def->type;
148 	    VALUE super_class = cc->me->defined_class;
149 
150 	    if (type == VM_METHOD_TYPE_ZSUPER) {
151 		super_class = RCLASS_ORIGIN(super_class);
152 	    }
153 	    else if (cc->me->def->body.refined.orig_me) {
154 		cc->me = refined_method_callable_without_refinement(cc->me);
155 		goto again;
156 	    }
157 
158 	    super_class = RCLASS_SUPER(super_class);
159 
160 	    if (!super_class || !(cc->me = rb_callable_method_entry(super_class, ci->mid))) {
161 		enum method_missing_reason ex = (type == VM_METHOD_TYPE_ZSUPER) ? MISSING_SUPER : 0;
162 		ret = method_missing(calling->recv, ci->mid, calling->argc, argv, ex);
163 		goto success;
164 	    }
165 	    RUBY_VM_CHECK_INTS(ec);
166 	    goto again;
167 	}
168       case VM_METHOD_TYPE_ALIAS:
169 	cc->me = aliased_callable_method_entry(cc->me);
170 	goto again;
171       case VM_METHOD_TYPE_MISSING:
172 	{
173 	    vm_passed_block_handler_set(ec, calling->block_handler);
174 	    return method_missing(calling->recv, ci->mid, calling->argc,
175 				  argv, MISSING_NOENTRY);
176 	}
177       case VM_METHOD_TYPE_OPTIMIZED:
178 	switch (cc->me->def->body.optimize_type) {
179 	  case OPTIMIZED_METHOD_TYPE_SEND:
180 	    ret = send_internal(calling->argc, argv, calling->recv, CALL_FCALL);
181 	    goto success;
182 	  case OPTIMIZED_METHOD_TYPE_CALL:
183 	    {
184 		rb_proc_t *proc;
185 		GetProcPtr(calling->recv, proc);
186 		ret = rb_vm_invoke_proc(ec, proc, calling->argc, argv, calling->block_handler);
187 		goto success;
188 	    }
189 	  default:
190 	    rb_bug("vm_call0: unsupported optimized method type (%d)", cc->me->def->body.optimize_type);
191 	}
192 	break;
193       case VM_METHOD_TYPE_UNDEF:
194 	break;
195     }
196     rb_bug("vm_call0: unsupported method type (%d)", cc->me->def->type);
197     return Qundef;
198 
199   success:
200     RUBY_VM_CHECK_INTS(ec);
201     return ret;
202 }
203 
204 VALUE
rb_vm_call(rb_execution_context_t * ec,VALUE recv,VALUE id,int argc,const VALUE * argv,const rb_callable_method_entry_t * me)205 rb_vm_call(rb_execution_context_t *ec, VALUE recv, VALUE id, int argc, const VALUE *argv, const rb_callable_method_entry_t *me)
206 {
207     return rb_vm_call0(ec, recv, id, argc, argv, me);
208 }
209 
210 static inline VALUE
vm_call_super(rb_execution_context_t * ec,int argc,const VALUE * argv)211 vm_call_super(rb_execution_context_t *ec, int argc, const VALUE *argv)
212 {
213     VALUE recv = ec->cfp->self;
214     VALUE klass;
215     ID id;
216     rb_control_frame_t *cfp = ec->cfp;
217     const rb_callable_method_entry_t *me = rb_vm_frame_method_entry(cfp);
218 
219     if (VM_FRAME_RUBYFRAME_P(cfp)) {
220 	rb_bug("vm_call_super: should not be reached");
221     }
222 
223     klass = RCLASS_ORIGIN(me->defined_class);
224     klass = RCLASS_SUPER(klass);
225     id = me->def->original_id;
226     me = rb_callable_method_entry(klass, id);
227 
228     if (!me) {
229 	return method_missing(recv, id, argc, argv, MISSING_SUPER);
230     }
231     else {
232         return rb_vm_call0(ec, recv, id, argc, argv, me);
233     }
234 }
235 
236 VALUE
rb_call_super(int argc,const VALUE * argv)237 rb_call_super(int argc, const VALUE *argv)
238 {
239     rb_execution_context_t *ec = GET_EC();
240     PASS_PASSED_BLOCK_HANDLER_EC(ec);
241     return vm_call_super(ec, argc, argv);
242 }
243 
244 VALUE
rb_current_receiver(void)245 rb_current_receiver(void)
246 {
247     const rb_execution_context_t *ec = GET_EC();
248     rb_control_frame_t *cfp;
249     if (!ec || !(cfp = ec->cfp)) {
250 	rb_raise(rb_eRuntimeError, "no self, no life");
251     }
252     return cfp->self;
253 }
254 
255 #endif /* #ifndef MJIT_HEADER */
256 
257 static inline void
stack_check(rb_execution_context_t * ec)258 stack_check(rb_execution_context_t *ec)
259 {
260     if (!rb_ec_raised_p(ec, RAISED_STACKOVERFLOW) &&
261 	rb_ec_stack_check(ec)) {
262 	rb_ec_raised_set(ec, RAISED_STACKOVERFLOW);
263 	rb_ec_stack_overflow(ec, FALSE);
264     }
265 }
266 
267 #ifndef MJIT_HEADER
268 
269 static inline const rb_callable_method_entry_t *rb_search_method_entry(VALUE recv, ID mid);
270 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);
271 
272 /*!
273  * \internal
274  * calls the specified method.
275  *
276  * This function is called by functions in rb_call* family.
277  * \param ec     current execution context
278  * \param recv   receiver of the method
279  * \param mid    an ID that represents the name of the method
280  * \param argc   the number of method arguments
281  * \param argv   a pointer to an array of method arguments
282  * \param scope
283  * \param self   self in the caller. Qundef means no self is considered and
284  *               protected methods cannot be called
285  *
286  * \note \a self is used in order to controlling access to protected methods.
287  */
288 static inline VALUE
rb_call0(rb_execution_context_t * ec,VALUE recv,ID mid,int argc,const VALUE * argv,call_type scope,VALUE self)289 rb_call0(rb_execution_context_t *ec,
290 	 VALUE recv, ID mid, int argc, const VALUE *argv,
291 	 call_type scope, VALUE self)
292 {
293     const rb_callable_method_entry_t *me;
294     enum method_missing_reason call_status;
295 
296     if (scope == CALL_PUBLIC) {
297         me = rb_callable_method_entry_with_refinements(CLASS_OF(recv), mid, NULL);
298     }
299     else {
300         me = rb_search_method_entry(recv, mid);
301     }
302     call_status = rb_method_call_status(ec, me, scope, self);
303 
304     if (call_status != MISSING_NONE) {
305 	return method_missing(recv, mid, argc, argv, call_status);
306     }
307     stack_check(ec);
308     return rb_vm_call0(ec, recv, mid, argc, argv, me);
309 }
310 
311 struct rescue_funcall_args {
312     VALUE defined_class;
313     VALUE recv;
314     ID mid;
315     rb_execution_context_t *ec;
316     const rb_method_entry_t *me;
317     unsigned int respond: 1;
318     unsigned int respond_to_missing: 1;
319     int argc;
320     const VALUE *argv;
321 };
322 
323 static VALUE
check_funcall_exec(struct rescue_funcall_args * args)324 check_funcall_exec(struct rescue_funcall_args *args)
325 {
326     return call_method_entry(args->ec, args->defined_class,
327 			     args->recv, idMethodMissing,
328 			     args->me, args->argc, args->argv);
329 }
330 
331 static VALUE
check_funcall_failed(struct rescue_funcall_args * args,VALUE e)332 check_funcall_failed(struct rescue_funcall_args *args, VALUE e)
333 {
334     int ret = args->respond;
335     if (!ret) {
336 	switch (rb_method_boundp(args->defined_class, args->mid,
337 				 BOUND_PRIVATE|BOUND_RESPONDS)) {
338 	  case 2:
339 	    ret = TRUE;
340 	    break;
341 	  case 0:
342 	    ret = args->respond_to_missing;
343 	    break;
344 	  default:
345 	    ret = FALSE;
346 	    break;
347 	}
348     }
349     if (ret) {
350 	rb_exc_raise(e);
351     }
352     return Qundef;
353 }
354 
355 static int
check_funcall_respond_to(rb_execution_context_t * ec,VALUE klass,VALUE recv,ID mid)356 check_funcall_respond_to(rb_execution_context_t *ec, VALUE klass, VALUE recv, ID mid)
357 {
358     return vm_respond_to(ec, klass, recv, mid, TRUE);
359 }
360 
361 static int
check_funcall_callable(rb_execution_context_t * ec,const rb_callable_method_entry_t * me)362 check_funcall_callable(rb_execution_context_t *ec, const rb_callable_method_entry_t *me)
363 {
364     return rb_method_call_status(ec, me, CALL_FCALL, ec->cfp->self) == MISSING_NONE;
365 }
366 
367 static VALUE
check_funcall_missing(rb_execution_context_t * ec,VALUE klass,VALUE recv,ID mid,int argc,const VALUE * argv,int respond,VALUE def)368 check_funcall_missing(rb_execution_context_t *ec, VALUE klass, VALUE recv, ID mid, int argc, const VALUE *argv, int respond, VALUE def)
369 {
370     struct rescue_funcall_args args;
371     const rb_method_entry_t *me;
372     VALUE ret = Qundef;
373 
374     ret = basic_obj_respond_to_missing(ec, klass, recv,
375 				       ID2SYM(mid), Qtrue);
376     if (!RTEST(ret)) return def;
377     args.respond = respond > 0;
378     args.respond_to_missing = (ret != Qundef);
379     ret = def;
380     me = method_entry_get(klass, idMethodMissing, &args.defined_class);
381     if (me && !METHOD_ENTRY_BASIC(me)) {
382 	VALUE argbuf, *new_args = ALLOCV_N(VALUE, argbuf, argc+1);
383 
384 	new_args[0] = ID2SYM(mid);
385 	MEMCPY(new_args+1, argv, VALUE, argc);
386 	ec->method_missing_reason = MISSING_NOENTRY;
387 	args.ec = ec;
388 	args.recv = recv;
389 	args.me = me;
390 	args.mid = mid;
391 	args.argc = argc + 1;
392 	args.argv = new_args;
393 	ret = rb_rescue2(check_funcall_exec, (VALUE)&args,
394 			 check_funcall_failed, (VALUE)&args,
395 			 rb_eNoMethodError, (VALUE)0);
396 	ALLOCV_END(argbuf);
397     }
398     return ret;
399 }
400 
401 VALUE
rb_check_funcall(VALUE recv,ID mid,int argc,const VALUE * argv)402 rb_check_funcall(VALUE recv, ID mid, int argc, const VALUE *argv)
403 {
404     return rb_check_funcall_default(recv, mid, argc, argv, Qundef);
405 }
406 
407 VALUE
rb_check_funcall_default(VALUE recv,ID mid,int argc,const VALUE * argv,VALUE def)408 rb_check_funcall_default(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE def)
409 {
410     VALUE klass = CLASS_OF(recv);
411     const rb_callable_method_entry_t *me;
412     rb_execution_context_t *ec = GET_EC();
413     int respond = check_funcall_respond_to(ec, klass, recv, mid);
414 
415     if (!respond)
416 	return def;
417 
418     me = rb_search_method_entry(recv, mid);
419     if (!check_funcall_callable(ec, me)) {
420 	VALUE ret = check_funcall_missing(ec, klass, recv, mid, argc, argv,
421 					  respond, def);
422 	if (ret == Qundef) ret = def;
423 	return ret;
424     }
425     stack_check(ec);
426     return rb_vm_call0(ec, recv, mid, argc, argv, me);
427 }
428 
429 VALUE
rb_check_funcall_with_hook(VALUE recv,ID mid,int argc,const VALUE * argv,rb_check_funcall_hook * hook,VALUE arg)430 rb_check_funcall_with_hook(VALUE recv, ID mid, int argc, const VALUE *argv,
431 			   rb_check_funcall_hook *hook, VALUE arg)
432 {
433     VALUE klass = CLASS_OF(recv);
434     const rb_callable_method_entry_t *me;
435     rb_execution_context_t *ec = GET_EC();
436     int respond = check_funcall_respond_to(ec, klass, recv, mid);
437 
438     if (!respond) {
439 	(*hook)(FALSE, recv, mid, argc, argv, arg);
440 	return Qundef;
441     }
442 
443     me = rb_search_method_entry(recv, mid);
444     if (!check_funcall_callable(ec, me)) {
445 	VALUE ret = check_funcall_missing(ec, klass, recv, mid, argc, argv,
446 					  respond, Qundef);
447 	(*hook)(ret != Qundef, recv, mid, argc, argv, arg);
448 	return ret;
449     }
450     stack_check(ec);
451     (*hook)(TRUE, recv, mid, argc, argv, arg);
452     return rb_vm_call0(ec, recv, mid, argc, argv, me);
453 }
454 
455 const char *
rb_type_str(enum ruby_value_type type)456 rb_type_str(enum ruby_value_type type)
457 {
458 #define type_case(t) t: return #t
459     switch (type) {
460       case type_case(T_NONE);
461       case type_case(T_OBJECT);
462       case type_case(T_CLASS);
463       case type_case(T_MODULE);
464       case type_case(T_FLOAT);
465       case type_case(T_STRING);
466       case type_case(T_REGEXP);
467       case type_case(T_ARRAY);
468       case type_case(T_HASH);
469       case type_case(T_STRUCT);
470       case type_case(T_BIGNUM);
471       case type_case(T_FILE);
472       case type_case(T_DATA);
473       case type_case(T_MATCH);
474       case type_case(T_COMPLEX);
475       case type_case(T_RATIONAL);
476       case type_case(T_NIL);
477       case type_case(T_TRUE);
478       case type_case(T_FALSE);
479       case type_case(T_SYMBOL);
480       case type_case(T_FIXNUM);
481       case type_case(T_IMEMO);
482       case type_case(T_UNDEF);
483       case type_case(T_NODE);
484       case type_case(T_ICLASS);
485       case type_case(T_ZOMBIE);
486       case T_MASK: break;
487     }
488 #undef type_case
489     return NULL;
490 }
491 
492 NORETURN(static void uncallable_object(VALUE recv, ID mid));
493 static void
uncallable_object(VALUE recv,ID mid)494 uncallable_object(VALUE recv, ID mid)
495 {
496     VALUE flags;
497     int type;
498     const char *typestr;
499     VALUE mname = rb_id2str(mid);
500 
501     if (SPECIAL_CONST_P(recv)) {
502 	rb_raise(rb_eNotImpError,
503 		 "method `%"PRIsVALUE"' called on unexpected immediate object (%p)",
504 		 mname, (void *)recv);
505     }
506     else if ((flags = RBASIC(recv)->flags) == 0) {
507 	rb_raise(rb_eNotImpError,
508 		 "method `%"PRIsVALUE"' called on terminated object (%p)",
509 		 mname, (void *)recv);
510     }
511     else if (!(typestr = rb_type_str(type = BUILTIN_TYPE(recv)))) {
512 	rb_raise(rb_eNotImpError,
513 		 "method `%"PRIsVALUE"' called on broken T_?""?""?(0x%02x) object"
514 		 " (%p flags=0x%"PRIxVALUE")",
515 		 mname, type, (void *)recv, flags);
516     }
517     else if (T_OBJECT <= type && type < T_NIL) {
518 	rb_raise(rb_eNotImpError,
519 		 "method `%"PRIsVALUE"' called on hidden %s object"
520 		 " (%p flags=0x%"PRIxVALUE")",
521 		 mname, typestr, (void *)recv, flags);
522     }
523     else {
524 	rb_raise(rb_eNotImpError,
525 		 "method `%"PRIsVALUE"' called on unexpected %s object"
526 		 " (%p flags=0x%"PRIxVALUE")",
527 		 mname, typestr, (void *)recv, flags);
528     }
529 }
530 
531 static inline const rb_callable_method_entry_t *
rb_search_method_entry(VALUE recv,ID mid)532 rb_search_method_entry(VALUE recv, ID mid)
533 {
534     VALUE klass = CLASS_OF(recv);
535 
536     if (!klass) uncallable_object(recv, mid);
537     return rb_callable_method_entry(klass, mid);
538 }
539 
540 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)541 rb_method_call_status(rb_execution_context_t *ec, const rb_callable_method_entry_t *me, call_type scope, VALUE self)
542 {
543     VALUE klass;
544     ID oid;
545     rb_method_visibility_t visi;
546 
547     if (UNDEFINED_METHOD_ENTRY_P(me)) {
548       undefined:
549 	return scope == CALL_VCALL ? MISSING_VCALL : MISSING_NOENTRY;
550     }
551     if (me->def->type == VM_METHOD_TYPE_REFINED) {
552 	me = rb_resolve_refined_method_callable(Qnil, me);
553 	if (UNDEFINED_METHOD_ENTRY_P(me)) goto undefined;
554     }
555 
556     klass = me->owner;
557     oid = me->def->original_id;
558     visi = METHOD_ENTRY_VISI(me);
559 
560     if (oid != idMethodMissing) {
561 	/* receiver specified form for private method */
562 	if (UNLIKELY(visi != METHOD_VISI_PUBLIC)) {
563 	    if (visi == METHOD_VISI_PRIVATE && scope == CALL_PUBLIC) {
564 		return MISSING_PRIVATE;
565 	    }
566 
567 	    /* self must be kind of a specified form for protected method */
568 	    if (visi == METHOD_VISI_PROTECTED && scope == CALL_PUBLIC) {
569 		VALUE defined_class = klass;
570 
571 		if (RB_TYPE_P(defined_class, T_ICLASS)) {
572 		    defined_class = RBASIC(defined_class)->klass;
573 		}
574 
575 		if (self == Qundef || !rb_obj_is_kind_of(self, defined_class)) {
576 		    return MISSING_PROTECTED;
577 		}
578 	    }
579 	}
580     }
581 
582     return MISSING_NONE;
583 }
584 
585 
586 /*!
587  * \internal
588  * calls the specified method.
589  *
590  * This function is called by functions in rb_call* family.
591  * \param recv   receiver
592  * \param mid    an ID that represents the name of the method
593  * \param argc   the number of method arguments
594  * \param argv   a pointer to an array of method arguments
595  * \param scope
596  */
597 static inline VALUE
rb_call(VALUE recv,ID mid,int argc,const VALUE * argv,call_type scope)598 rb_call(VALUE recv, ID mid, int argc, const VALUE *argv, call_type scope)
599 {
600     rb_execution_context_t *ec = GET_EC();
601     return rb_call0(ec, recv, mid, argc, argv, scope, ec->cfp->self);
602 }
603 
604 NORETURN(static void raise_method_missing(rb_execution_context_t *ec, int argc, const VALUE *argv,
605 					  VALUE obj, enum method_missing_reason call_status));
606 
607 /*
608  *  call-seq:
609  *     obj.method_missing(symbol [, *args] )   -> result
610  *
611  *  Invoked by Ruby when <i>obj</i> is sent a message it cannot handle.
612  *  <i>symbol</i> is the symbol for the method called, and <i>args</i>
613  *  are any arguments that were passed to it. By default, the interpreter
614  *  raises an error when this method is called. However, it is possible
615  *  to override the method to provide more dynamic behavior.
616  *  If it is decided that a particular method should not be handled, then
617  *  <i>super</i> should be called, so that ancestors can pick up the
618  *  missing method.
619  *  The example below creates
620  *  a class <code>Roman</code>, which responds to methods with names
621  *  consisting of roman numerals, returning the corresponding integer
622  *  values.
623  *
624  *     class Roman
625  *       def roman_to_int(str)
626  *         # ...
627  *       end
628  *       def method_missing(methId)
629  *         str = methId.id2name
630  *         roman_to_int(str)
631  *       end
632  *     end
633  *
634  *     r = Roman.new
635  *     r.iv      #=> 4
636  *     r.xxiii   #=> 23
637  *     r.mm      #=> 2000
638  */
639 
640 static VALUE
rb_method_missing(int argc,const VALUE * argv,VALUE obj)641 rb_method_missing(int argc, const VALUE *argv, VALUE obj)
642 {
643     rb_execution_context_t *ec = GET_EC();
644     raise_method_missing(ec, argc, argv, obj, ec->method_missing_reason);
645     UNREACHABLE_RETURN(Qnil);
646 }
647 
648 MJIT_FUNC_EXPORTED VALUE
rb_make_no_method_exception(VALUE exc,VALUE format,VALUE obj,int argc,const VALUE * argv,int priv)649 rb_make_no_method_exception(VALUE exc, VALUE format, VALUE obj,
650 			    int argc, const VALUE *argv, int priv)
651 {
652     VALUE name = argv[0];
653 
654     if (!format) {
655 	format = rb_fstring_lit("undefined method `%s' for %s%s%s");
656     }
657     if (exc == rb_eNoMethodError) {
658 	VALUE args = rb_ary_new4(argc - 1, argv + 1);
659 	return rb_nomethod_err_new(format, obj, name, args, priv);
660     }
661     else {
662 	return rb_name_err_new(format, obj, name);
663     }
664 }
665 
666 #endif /* #ifndef MJIT_HEADER */
667 
668 static void
raise_method_missing(rb_execution_context_t * ec,int argc,const VALUE * argv,VALUE obj,enum method_missing_reason last_call_status)669 raise_method_missing(rb_execution_context_t *ec, int argc, const VALUE *argv, VALUE obj,
670 		     enum method_missing_reason last_call_status)
671 {
672     VALUE exc = rb_eNoMethodError;
673     VALUE format = 0;
674 
675     if (UNLIKELY(argc == 0)) {
676 	rb_raise(rb_eArgError, "no method name given");
677     }
678     else if (UNLIKELY(!SYMBOL_P(argv[0]))) {
679 	const VALUE e = rb_eArgError; /* TODO: TypeError? */
680 	rb_raise(e, "method name must be a Symbol but %"PRIsVALUE" is given",
681 		 rb_obj_class(argv[0]));
682     }
683 
684     stack_check(ec);
685 
686     if (last_call_status & MISSING_PRIVATE) {
687 	format = rb_fstring_lit("private method `%s' called for %s%s%s");
688     }
689     else if (last_call_status & MISSING_PROTECTED) {
690 	format = rb_fstring_lit("protected method `%s' called for %s%s%s");
691     }
692     else if (last_call_status & MISSING_VCALL) {
693 	format = rb_fstring_lit("undefined local variable or method `%s' for %s%s%s");
694 	exc = rb_eNameError;
695     }
696     else if (last_call_status & MISSING_SUPER) {
697 	format = rb_fstring_lit("super: no superclass method `%s' for %s%s%s");
698     }
699 
700     {
701 	exc = rb_make_no_method_exception(exc, format, obj, argc, argv,
702 					  last_call_status & (MISSING_FCALL|MISSING_VCALL));
703 	if (!(last_call_status & MISSING_MISSING)) {
704 	    rb_vm_pop_cfunc_frame();
705 	}
706 	rb_exc_raise(exc);
707     }
708 }
709 
710 static void
vm_raise_method_missing(rb_execution_context_t * ec,int argc,const VALUE * argv,VALUE obj,int call_status)711 vm_raise_method_missing(rb_execution_context_t *ec, int argc, const VALUE *argv,
712 			VALUE obj, int call_status)
713 {
714     vm_passed_block_handler_set(ec, VM_BLOCK_HANDLER_NONE);
715     raise_method_missing(ec, argc, argv, obj, call_status | MISSING_MISSING);
716 }
717 
718 static inline VALUE
method_missing(VALUE obj,ID id,int argc,const VALUE * argv,enum method_missing_reason call_status)719 method_missing(VALUE obj, ID id, int argc, const VALUE *argv, enum method_missing_reason call_status)
720 {
721     VALUE *nargv, result, work, klass;
722     rb_execution_context_t *ec = GET_EC();
723     VALUE block_handler = vm_passed_block_handler(ec);
724     const rb_callable_method_entry_t *me;
725 
726     ec->method_missing_reason = call_status;
727 
728     if (id == idMethodMissing) {
729       missing:
730 	raise_method_missing(ec, argc, argv, obj, call_status | MISSING_MISSING);
731     }
732 
733     nargv = ALLOCV_N(VALUE, work, argc + 1);
734     nargv[0] = ID2SYM(id);
735     MEMCPY(nargv + 1, argv, VALUE, argc);
736     ++argc;
737     argv = nargv;
738 
739     klass = CLASS_OF(obj);
740     if (!klass) goto missing;
741     me = rb_callable_method_entry(klass, idMethodMissing);
742     if (!me || METHOD_ENTRY_BASIC(me)) goto missing;
743     vm_passed_block_handler_set(ec, block_handler);
744     result = rb_vm_call0(ec, obj, idMethodMissing, argc, argv, me);
745     if (work) ALLOCV_END(work);
746     return result;
747 }
748 
749 #ifndef MJIT_HEADER
750 
751 /*!
752  * Calls a method
753  * \param recv   receiver of the method
754  * \param mid    an ID that represents the name of the method
755  * \param args   an Array object which contains method arguments
756  *
757  * \pre \a args must refer an Array object.
758  */
759 VALUE
rb_apply(VALUE recv,ID mid,VALUE args)760 rb_apply(VALUE recv, ID mid, VALUE args)
761 {
762     int argc;
763     VALUE *argv, ret;
764 
765     argc = RARRAY_LENINT(args);
766     if (argc >= 0x100) {
767 	args = rb_ary_subseq(args, 0, argc);
768 	RBASIC_CLEAR_CLASS(args);
769 	OBJ_FREEZE(args);
770 	ret = rb_call(recv, mid, argc, RARRAY_CONST_PTR(args), CALL_FCALL);
771 	RB_GC_GUARD(args);
772 	return ret;
773     }
774     argv = ALLOCA_N(VALUE, argc);
775     MEMCPY(argv, RARRAY_CONST_PTR_TRANSIENT(args), VALUE, argc);
776     return rb_call(recv, mid, argc, argv, CALL_FCALL);
777 }
778 
779 #undef rb_funcall
780 /*!
781  * Calls a method
782  * \param recv   receiver of the method
783  * \param mid    an ID that represents the name of the method
784  * \param n      the number of arguments
785  * \param ...    arbitrary number of method arguments
786  *
787  * \pre each of arguments after \a n must be a VALUE.
788  */
789 VALUE
rb_funcall(VALUE recv,ID mid,int n,...)790 rb_funcall(VALUE recv, ID mid, int n, ...)
791 {
792     VALUE *argv;
793     va_list ar;
794 
795     if (n > 0) {
796 	long i;
797 
798 	va_init_list(ar, n);
799 
800 	argv = ALLOCA_N(VALUE, n);
801 
802 	for (i = 0; i < n; i++) {
803 	    argv[i] = va_arg(ar, VALUE);
804 	}
805 	va_end(ar);
806     }
807     else {
808 	argv = 0;
809     }
810     return rb_call(recv, mid, n, argv, CALL_FCALL);
811 }
812 
813 /*!
814  * Calls a method
815  * \param recv   receiver of the method
816  * \param mid    an ID that represents the name of the method
817  * \param argc   the number of arguments
818  * \param argv   pointer to an array of method arguments
819  */
820 VALUE
rb_funcallv(VALUE recv,ID mid,int argc,const VALUE * argv)821 rb_funcallv(VALUE recv, ID mid, int argc, const VALUE *argv)
822 {
823     return rb_call(recv, mid, argc, argv, CALL_FCALL);
824 }
825 
826 /*!
827  * Calls a method.
828  *
829  * Same as rb_funcallv but this function can call only public methods.
830  * \param recv   receiver of the method
831  * \param mid    an ID that represents the name of the method
832  * \param argc   the number of arguments
833  * \param argv   pointer to an array of method arguments
834  */
835 VALUE
rb_funcallv_public(VALUE recv,ID mid,int argc,const VALUE * argv)836 rb_funcallv_public(VALUE recv, ID mid, int argc, const VALUE *argv)
837 {
838     return rb_call(recv, mid, argc, argv, CALL_PUBLIC);
839 }
840 
841 VALUE
rb_funcall_passing_block(VALUE recv,ID mid,int argc,const VALUE * argv)842 rb_funcall_passing_block(VALUE recv, ID mid, int argc, const VALUE *argv)
843 {
844     PASS_PASSED_BLOCK_HANDLER();
845     return rb_call(recv, mid, argc, argv, CALL_PUBLIC);
846 }
847 
848 VALUE
rb_funcall_with_block(VALUE recv,ID mid,int argc,const VALUE * argv,VALUE passed_procval)849 rb_funcall_with_block(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE passed_procval)
850 {
851     if (!NIL_P(passed_procval)) {
852 	vm_passed_block_handler_set(GET_EC(), passed_procval);
853     }
854 
855     return rb_call(recv, mid, argc, argv, CALL_PUBLIC);
856 }
857 
858 static VALUE *
current_vm_stack_arg(const rb_execution_context_t * ec,const VALUE * argv)859 current_vm_stack_arg(const rb_execution_context_t *ec, const VALUE *argv)
860 {
861     rb_control_frame_t *prev_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(ec->cfp);
862     if (RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(ec, prev_cfp)) return NULL;
863     if (prev_cfp->sp + 1 != argv) return NULL;
864     return prev_cfp->sp + 1;
865 }
866 
867 static VALUE
send_internal(int argc,const VALUE * argv,VALUE recv,call_type scope)868 send_internal(int argc, const VALUE *argv, VALUE recv, call_type scope)
869 {
870     ID id;
871     VALUE vid;
872     VALUE self;
873     VALUE ret, vargv = 0;
874     rb_execution_context_t *ec = GET_EC();
875 
876     if (scope == CALL_PUBLIC) {
877 	self = Qundef;
878     }
879     else {
880 	self = RUBY_VM_PREVIOUS_CONTROL_FRAME(ec->cfp)->self;
881     }
882 
883     if (argc == 0) {
884 	rb_raise(rb_eArgError, "no method name given");
885     }
886 
887     vid = *argv;
888 
889     id = rb_check_id(&vid);
890     if (!id) {
891 	if (rb_method_basic_definition_p(CLASS_OF(recv), idMethodMissing)) {
892 	    VALUE exc = rb_make_no_method_exception(rb_eNoMethodError, 0,
893 						    recv, argc, argv,
894 						    scope != CALL_PUBLIC);
895 	    rb_exc_raise(exc);
896 	}
897 	if (!SYMBOL_P(*argv)) {
898 	    VALUE *tmp_argv = current_vm_stack_arg(ec, argv);
899 	    vid = rb_str_intern(vid);
900 	    if (tmp_argv) {
901 		tmp_argv[0] = vid;
902 	    }
903 	    else if (argc > 1) {
904 		tmp_argv = ALLOCV_N(VALUE, vargv, argc);
905 		tmp_argv[0] = vid;
906 		MEMCPY(tmp_argv+1, argv+1, VALUE, argc-1);
907 		argv = tmp_argv;
908 	    }
909 	    else {
910 		argv = &vid;
911 	    }
912 	}
913 	id = idMethodMissing;
914 	ec->method_missing_reason = MISSING_NOENTRY;
915     }
916     else {
917 	argv++; argc--;
918     }
919     PASS_PASSED_BLOCK_HANDLER_EC(ec);
920     ret = rb_call0(ec, recv, id, argc, argv, scope, self);
921     ALLOCV_END(vargv);
922     return ret;
923 }
924 
925 /*
926  * call-seq:
927  *    foo.send(symbol [, args...])       -> obj
928  *    foo.__send__(symbol [, args...])   -> obj
929  *    foo.send(string [, args...])       -> obj
930  *    foo.__send__(string [, args...])   -> obj
931  *
932  *  Invokes the method identified by _symbol_, passing it any
933  *  arguments specified. You can use <code>__send__</code> if the name
934  *  +send+ clashes with an existing method in _obj_.
935  *  When the method is identified by a string, the string is converted
936  *  to a symbol.
937  *
938  *     class Klass
939  *       def hello(*args)
940  *         "Hello " + args.join(' ')
941  *       end
942  *     end
943  *     k = Klass.new
944  *     k.send :hello, "gentle", "readers"   #=> "Hello gentle readers"
945  */
946 
947 VALUE
rb_f_send(int argc,VALUE * argv,VALUE recv)948 rb_f_send(int argc, VALUE *argv, VALUE recv)
949 {
950     return send_internal(argc, argv, recv, CALL_FCALL);
951 }
952 
953 /*
954  *  call-seq:
955  *     obj.public_send(symbol [, args...])  -> obj
956  *     obj.public_send(string [, args...])  -> obj
957  *
958  *  Invokes the method identified by _symbol_, passing it any
959  *  arguments specified. Unlike send, public_send calls public
960  *  methods only.
961  *  When the method is identified by a string, the string is converted
962  *  to a symbol.
963  *
964  *     1.public_send(:puts, "hello")  # causes NoMethodError
965  */
966 
967 static VALUE
rb_f_public_send(int argc,VALUE * argv,VALUE recv)968 rb_f_public_send(int argc, VALUE *argv, VALUE recv)
969 {
970     return send_internal(argc, argv, recv, CALL_PUBLIC);
971 }
972 
973 /* yield */
974 
975 static inline VALUE
rb_yield_0(int argc,const VALUE * argv)976 rb_yield_0(int argc, const VALUE * argv)
977 {
978     return vm_yield(GET_EC(), argc, argv);
979 }
980 
981 VALUE
rb_yield_1(VALUE val)982 rb_yield_1(VALUE val)
983 {
984     return rb_yield_0(1, &val);
985 }
986 
987 VALUE
rb_yield(VALUE val)988 rb_yield(VALUE val)
989 {
990     if (val == Qundef) {
991 	return rb_yield_0(0, 0);
992     }
993     else {
994 	return rb_yield_1(val);
995     }
996 }
997 
998 #undef rb_yield_values
999 VALUE
rb_yield_values(int n,...)1000 rb_yield_values(int n, ...)
1001 {
1002     if (n == 0) {
1003 	return rb_yield_0(0, 0);
1004     }
1005     else {
1006 	int i;
1007 	VALUE *argv;
1008 	va_list args;
1009 	argv = ALLOCA_N(VALUE, n);
1010 
1011 	va_init_list(args, n);
1012 	for (i=0; i<n; i++) {
1013 	    argv[i] = va_arg(args, VALUE);
1014 	}
1015 	va_end(args);
1016 
1017 	return rb_yield_0(n, argv);
1018     }
1019 }
1020 
1021 VALUE
rb_yield_values2(int argc,const VALUE * argv)1022 rb_yield_values2(int argc, const VALUE *argv)
1023 {
1024     return rb_yield_0(argc, argv);
1025 }
1026 
1027 VALUE
rb_yield_splat(VALUE values)1028 rb_yield_splat(VALUE values)
1029 {
1030     VALUE tmp = rb_check_array_type(values);
1031     VALUE v;
1032     if (NIL_P(tmp)) {
1033         rb_raise(rb_eArgError, "not an array");
1034     }
1035     v = rb_yield_0(RARRAY_LENINT(tmp), RARRAY_CONST_PTR(tmp));
1036     RB_GC_GUARD(tmp);
1037     return v;
1038 }
1039 
1040 VALUE
rb_yield_force_blockarg(VALUE values)1041 rb_yield_force_blockarg(VALUE values)
1042 {
1043     return vm_yield_force_blockarg(GET_EC(), values);
1044 }
1045 
1046 VALUE
rb_yield_block(VALUE val,VALUE arg,int argc,const VALUE * argv,VALUE blockarg)1047 rb_yield_block(VALUE val, VALUE arg, int argc, const VALUE *argv, VALUE blockarg)
1048 {
1049     return vm_yield_with_block(GET_EC(), argc, argv,
1050 			       NIL_P(blockarg) ? VM_BLOCK_HANDLER_NONE : blockarg);
1051 }
1052 
1053 static VALUE
loop_i(void)1054 loop_i(void)
1055 {
1056     for (;;) {
1057 	rb_yield_0(0, 0);
1058     }
1059     return Qnil;
1060 }
1061 
1062 static VALUE
loop_stop(VALUE dummy,VALUE exc)1063 loop_stop(VALUE dummy, VALUE exc)
1064 {
1065     return rb_attr_get(exc, id_result);
1066 }
1067 
1068 static VALUE
rb_f_loop_size(VALUE self,VALUE args,VALUE eobj)1069 rb_f_loop_size(VALUE self, VALUE args, VALUE eobj)
1070 {
1071     return DBL2NUM(HUGE_VAL);
1072 }
1073 
1074 /*
1075  *  call-seq:
1076  *     loop { block }
1077  *     loop            -> an_enumerator
1078  *
1079  *  Repeatedly executes the block.
1080  *
1081  *  If no block is given, an enumerator is returned instead.
1082  *
1083  *     loop do
1084  *       print "Input: "
1085  *       line = gets
1086  *       break if !line or line =~ /^qQ/
1087  *       # ...
1088  *     end
1089  *
1090  *  StopIteration raised in the block breaks the loop.  In this case,
1091  *  loop returns the "result" value stored in the exception.
1092  *
1093  *     enum = Enumerator.new { |y|
1094  *       y << "one"
1095  *       y << "two"
1096  *       :ok
1097  *     }
1098  *
1099  *     result = loop {
1100  *       puts enum.next
1101  *     } #=> :ok
1102  */
1103 
1104 static VALUE
rb_f_loop(VALUE self)1105 rb_f_loop(VALUE self)
1106 {
1107     RETURN_SIZED_ENUMERATOR(self, 0, 0, rb_f_loop_size);
1108     return rb_rescue2(loop_i, (VALUE)0, loop_stop, (VALUE)0, rb_eStopIteration, (VALUE)0);
1109 }
1110 
1111 #if VMDEBUG
1112 static const char *
1113 vm_frametype_name(const rb_control_frame_t *cfp);
1114 #endif
1115 
1116 static VALUE
rb_iterate0(VALUE (* it_proc)(VALUE),VALUE data1,const struct vm_ifunc * const ifunc,rb_execution_context_t * ec)1117 rb_iterate0(VALUE (* it_proc) (VALUE), VALUE data1,
1118 	    const struct vm_ifunc *const ifunc,
1119 	    rb_execution_context_t *ec)
1120 {
1121     enum ruby_tag_type state;
1122     volatile VALUE retval = Qnil;
1123     rb_control_frame_t *const cfp = ec->cfp;
1124 
1125     EC_PUSH_TAG(ec);
1126     state = EC_EXEC_TAG();
1127     if (state == 0) {
1128       iter_retry:
1129 	{
1130 	    VALUE block_handler;
1131 
1132 	    if (ifunc) {
1133 		struct rb_captured_block *captured = VM_CFP_TO_CAPTURED_BLOCK(cfp);
1134 		captured->code.ifunc = ifunc;
1135 		block_handler = VM_BH_FROM_IFUNC_BLOCK(captured);
1136 	    }
1137 	    else {
1138 		block_handler = VM_CF_BLOCK_HANDLER(cfp);
1139 	    }
1140 	    vm_passed_block_handler_set(ec, block_handler);
1141 	}
1142 	retval = (*it_proc) (data1);
1143     }
1144     else if (state == TAG_BREAK || state == TAG_RETRY) {
1145 	const struct vm_throw_data *const err = (struct vm_throw_data *)ec->errinfo;
1146 	const rb_control_frame_t *const escape_cfp = THROW_DATA_CATCH_FRAME(err);
1147 
1148 	if (cfp == escape_cfp) {
1149 	    rb_vm_rewind_cfp(ec, cfp);
1150 
1151 	    state = 0;
1152 	    ec->tag->state = TAG_NONE;
1153 	    ec->errinfo = Qnil;
1154 
1155 	    if (state == TAG_RETRY) goto iter_retry;
1156 	    retval = THROW_DATA_VAL(err);
1157 	}
1158 	else if (0) {
1159 	    SDR(); fprintf(stderr, "%p, %p\n", (void *)cfp, (void *)escape_cfp);
1160 	}
1161     }
1162     EC_POP_TAG();
1163 
1164     if (state) {
1165 	EC_JUMP_TAG(ec, state);
1166     }
1167     return retval;
1168 }
1169 
1170 VALUE
rb_iterate(VALUE (* it_proc)(VALUE),VALUE data1,VALUE (* bl_proc)(ANYARGS),VALUE data2)1171 rb_iterate(VALUE (* it_proc)(VALUE), VALUE data1,
1172 	   VALUE (* bl_proc)(ANYARGS), VALUE data2)
1173 {
1174     return rb_iterate0(it_proc, data1,
1175 		       bl_proc ? rb_vm_ifunc_proc_new(bl_proc, (void *)data2) : 0,
1176 		       GET_EC());
1177 }
1178 
1179 struct iter_method_arg {
1180     VALUE obj;
1181     ID mid;
1182     int argc;
1183     const VALUE *argv;
1184 };
1185 
1186 static VALUE
iterate_method(VALUE obj)1187 iterate_method(VALUE obj)
1188 {
1189     const struct iter_method_arg * arg =
1190       (struct iter_method_arg *) obj;
1191 
1192     return rb_call(arg->obj, arg->mid, arg->argc, arg->argv, CALL_FCALL);
1193 }
1194 
1195 VALUE
rb_block_call(VALUE obj,ID mid,int argc,const VALUE * argv,VALUE (* bl_proc)(ANYARGS),VALUE data2)1196 rb_block_call(VALUE obj, ID mid, int argc, const VALUE * argv,
1197 	      VALUE (*bl_proc) (ANYARGS), VALUE data2)
1198 {
1199     struct iter_method_arg arg;
1200 
1201     arg.obj = obj;
1202     arg.mid = mid;
1203     arg.argc = argc;
1204     arg.argv = argv;
1205     return rb_iterate(iterate_method, (VALUE)&arg, bl_proc, data2);
1206 }
1207 
1208 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)1209 rb_lambda_call(VALUE obj, ID mid, int argc, const VALUE *argv,
1210 	       rb_block_call_func_t bl_proc, int min_argc, int max_argc,
1211 	       VALUE data2)
1212 {
1213     struct iter_method_arg arg;
1214     struct vm_ifunc *block;
1215 
1216     if (!bl_proc) rb_raise(rb_eArgError, "NULL lambda function");
1217     arg.obj = obj;
1218     arg.mid = mid;
1219     arg.argc = argc;
1220     arg.argv = argv;
1221     block = rb_vm_ifunc_new(bl_proc, (void *)data2, min_argc, max_argc);
1222     return rb_iterate0(iterate_method, (VALUE)&arg, block, GET_EC());
1223 }
1224 
1225 static VALUE
iterate_check_method(VALUE obj)1226 iterate_check_method(VALUE obj)
1227 {
1228     const struct iter_method_arg * arg =
1229       (struct iter_method_arg *) obj;
1230 
1231     return rb_check_funcall(arg->obj, arg->mid, arg->argc, arg->argv);
1232 }
1233 
1234 VALUE
rb_check_block_call(VALUE obj,ID mid,int argc,const VALUE * argv,VALUE (* bl_proc)(ANYARGS),VALUE data2)1235 rb_check_block_call(VALUE obj, ID mid, int argc, const VALUE *argv,
1236 		    VALUE (*bl_proc) (ANYARGS), VALUE data2)
1237 {
1238     struct iter_method_arg arg;
1239 
1240     arg.obj = obj;
1241     arg.mid = mid;
1242     arg.argc = argc;
1243     arg.argv = argv;
1244     return rb_iterate(iterate_check_method, (VALUE)&arg, bl_proc, data2);
1245 }
1246 
1247 VALUE
rb_each(VALUE obj)1248 rb_each(VALUE obj)
1249 {
1250     return rb_call(obj, idEach, 0, 0, CALL_FCALL);
1251 }
1252 
1253 void rb_parser_warn_location(VALUE, int);
1254 static const rb_iseq_t *
eval_make_iseq(VALUE src,VALUE fname,int line,const rb_binding_t * bind,const struct rb_block * base_block)1255 eval_make_iseq(VALUE src, VALUE fname, int line, const rb_binding_t *bind,
1256 	       const struct rb_block *base_block)
1257 {
1258     const VALUE parser = rb_parser_new();
1259     const rb_iseq_t *const parent = vm_block_iseq(base_block);
1260     VALUE realpath = Qnil;
1261     rb_iseq_t *iseq = 0;
1262     rb_ast_t *ast;
1263 
1264     if (!fname) {
1265 	fname = rb_source_location(&line);
1266     }
1267 
1268     if (fname != Qundef) {
1269         if (!NIL_P(fname)) fname = rb_fstring(fname);
1270 	realpath = fname;
1271     }
1272     else if (bind) {
1273 	fname = pathobj_path(bind->pathobj);
1274 	realpath = pathobj_realpath(bind->pathobj);
1275 	line = bind->first_lineno;
1276 	rb_parser_warn_location(parser, TRUE);
1277     }
1278     else {
1279 	fname = rb_fstring_lit("(eval)");
1280     }
1281 
1282     rb_parser_set_context(parser, base_block, FALSE);
1283     ast = rb_parser_compile_string_path(parser, fname, src, line);
1284     if (ast->body.root) {
1285 	iseq = rb_iseq_new_with_opt(&ast->body,
1286 				    parent->body->location.label,
1287 				    fname, realpath, INT2FIX(line),
1288 				    parent, ISEQ_TYPE_EVAL, NULL);
1289     }
1290     rb_ast_dispose(ast);
1291 
1292     if (0 && iseq) {		/* for debug */
1293 	VALUE disasm = rb_iseq_disasm(iseq);
1294 	printf("%s\n", StringValuePtr(disasm));
1295     }
1296 
1297     rb_exec_event_hook_script_compiled(GET_EC(), iseq, src);
1298 
1299     return iseq;
1300 }
1301 
1302 static VALUE
eval_string_with_cref(VALUE self,VALUE src,rb_cref_t * cref,VALUE file,int line)1303 eval_string_with_cref(VALUE self, VALUE src, rb_cref_t *cref, VALUE file, int line)
1304 {
1305     rb_execution_context_t *ec = GET_EC();
1306     struct rb_block block;
1307     const rb_iseq_t *iseq;
1308     rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(ec, ec->cfp);
1309     if (!cfp) {
1310 	rb_raise(rb_eRuntimeError, "Can't eval on top of Fiber or Thread");
1311     }
1312 
1313     block.as.captured = *VM_CFP_TO_CAPTURED_BLOCK(cfp);
1314     block.as.captured.self = self;
1315     block.as.captured.code.iseq = cfp->iseq;
1316     block.type = block_type_iseq;
1317 
1318     iseq = eval_make_iseq(src, file, line, NULL, &block);
1319     if (!iseq) {
1320 	rb_exc_raise(ec->errinfo);
1321     }
1322 
1323     /* TODO: what the code checking? */
1324     if (!cref && block.as.captured.code.val) {
1325 	rb_cref_t *orig_cref = rb_vm_get_cref(vm_block_ep(&block));
1326 	cref = vm_cref_dup(orig_cref);
1327     }
1328     vm_set_eval_stack(ec, iseq, cref, &block);
1329 
1330     /* kick */
1331     return vm_exec(ec, TRUE);
1332 }
1333 
1334 static VALUE
eval_string_with_scope(VALUE scope,VALUE src,VALUE file,int line)1335 eval_string_with_scope(VALUE scope, VALUE src, VALUE file, int line)
1336 {
1337     rb_execution_context_t *ec = GET_EC();
1338     rb_binding_t *bind = Check_TypedStruct(scope, &ruby_binding_data_type);
1339     const rb_iseq_t *iseq = eval_make_iseq(src, file, line, bind, &bind->block);
1340     if (!iseq) {
1341 	rb_exc_raise(ec->errinfo);
1342     }
1343 
1344     vm_set_eval_stack(ec, iseq, NULL, &bind->block);
1345 
1346     /* save new env */
1347     if (iseq->body->local_table_size > 0) {
1348 	vm_bind_update_env(scope, bind, vm_make_env_object(ec, ec->cfp));
1349     }
1350 
1351     /* kick */
1352     return vm_exec(ec, TRUE);
1353 }
1354 
1355 /*
1356  *  call-seq:
1357  *     eval(string [, binding [, filename [,lineno]]])  -> obj
1358  *
1359  *  Evaluates the Ruby expression(s) in <em>string</em>. If
1360  *  <em>binding</em> is given, which must be a <code>Binding</code>
1361  *  object, the evaluation is performed in its context. If the
1362  *  optional <em>filename</em> and <em>lineno</em> parameters are
1363  *  present, they will be used when reporting syntax errors.
1364  *
1365  *     def get_binding(str)
1366  *       return binding
1367  *     end
1368  *     str = "hello"
1369  *     eval "str + ' Fred'"                      #=> "hello Fred"
1370  *     eval "str + ' Fred'", get_binding("bye")  #=> "bye Fred"
1371  */
1372 
1373 VALUE
rb_f_eval(int argc,const VALUE * argv,VALUE self)1374 rb_f_eval(int argc, const VALUE *argv, VALUE self)
1375 {
1376     VALUE src, scope, vfile, vline;
1377     VALUE file = Qundef;
1378     int line = 1;
1379 
1380     rb_scan_args(argc, argv, "13", &src, &scope, &vfile, &vline);
1381     SafeStringValue(src);
1382     if (argc >= 3) {
1383 	StringValue(vfile);
1384     }
1385     if (argc >= 4) {
1386 	line = NUM2INT(vline);
1387     }
1388 
1389     if (!NIL_P(vfile))
1390 	file = vfile;
1391 
1392     if (NIL_P(scope))
1393 	return eval_string_with_cref(self, src, NULL, file, line);
1394     else
1395 	return eval_string_with_scope(scope, src, file, line);
1396 }
1397 
1398 /** @note This function name is not stable. */
1399 VALUE
ruby_eval_string_from_file(const char * str,const char * filename)1400 ruby_eval_string_from_file(const char *str, const char *filename)
1401 {
1402     VALUE file = filename ? rb_str_new_cstr(filename) : 0;
1403     return eval_string_with_cref(rb_vm_top_self(), rb_str_new2(str), NULL, file, 1);
1404 }
1405 
1406 struct eval_string_from_file_arg {
1407     VALUE str;
1408     VALUE filename;
1409 };
1410 
1411 static VALUE
eval_string_from_file_helper(VALUE data)1412 eval_string_from_file_helper(VALUE data)
1413 {
1414     const struct eval_string_from_file_arg *const arg = (struct eval_string_from_file_arg*)data;
1415     return eval_string_with_cref(rb_vm_top_self(), arg->str, NULL, arg->filename, 1);
1416 }
1417 
1418 VALUE
ruby_eval_string_from_file_protect(const char * str,const char * filename,int * state)1419 ruby_eval_string_from_file_protect(const char *str, const char *filename, int *state)
1420 {
1421     struct eval_string_from_file_arg arg;
1422     arg.str = rb_str_new_cstr(str);
1423     arg.filename = filename ? rb_str_new_cstr(filename) : 0;
1424     return rb_protect(eval_string_from_file_helper, (VALUE)&arg, state);
1425 }
1426 
1427 /**
1428  * Evaluates the given string in an isolated binding.
1429  *
1430  * Here "isolated" means the binding does not inherit any other binding. This
1431  * behaves same as the binding for required libraries.
1432  *
1433  * __FILE__ will be "(eval)", and __LINE__ starts from 1 in the evaluation.
1434  *
1435  * @param str Ruby code to evaluate.
1436  * @return The evaluated result.
1437  * @throw Exception   Raises an exception on error.
1438  */
1439 VALUE
rb_eval_string(const char * str)1440 rb_eval_string(const char *str)
1441 {
1442     return ruby_eval_string_from_file(str, "eval");
1443 }
1444 
1445 static VALUE
eval_string_protect(VALUE str)1446 eval_string_protect(VALUE str)
1447 {
1448     return rb_eval_string((char *)str);
1449 }
1450 
1451 /**
1452  * Evaluates the given string in an isolated binding.
1453  *
1454  * __FILE__ will be "(eval)", and __LINE__ starts from 1 in the evaluation.
1455  *
1456  * @sa rb_eval_string
1457  * @param str Ruby code to evaluate.
1458  * @param state Being set to zero if succeeded. Nonzero if an error occurred.
1459  * @return The evaluated result if succeeded, an undefined value if otherwise.
1460  */
1461 VALUE
rb_eval_string_protect(const char * str,int * pstate)1462 rb_eval_string_protect(const char *str, int *pstate)
1463 {
1464     return rb_protect(eval_string_protect, (VALUE)str, pstate);
1465 }
1466 
1467 /**
1468  * Evaluates the given string under a module binding in an isolated binding.
1469  * This is same as the binding for loaded libraries on "load('foo', true)".
1470  *
1471  * __FILE__ will be "(eval)", and __LINE__ starts from 1 in the evaluation.
1472  *
1473  * @sa rb_eval_string
1474  * @param str Ruby code to evaluate.
1475  * @param state Being set to zero if succeeded. Nonzero if an error occurred.
1476  * @return The evaluated result if succeeded, an undefined value if otherwise.
1477  */
1478 VALUE
rb_eval_string_wrap(const char * str,int * pstate)1479 rb_eval_string_wrap(const char *str, int *pstate)
1480 {
1481     int state;
1482     rb_thread_t *th = GET_THREAD();
1483     VALUE self = th->top_self;
1484     VALUE wrapper = th->top_wrapper;
1485     VALUE val;
1486 
1487     th->top_wrapper = rb_module_new();
1488     th->top_self = rb_obj_clone(rb_vm_top_self());
1489     rb_extend_object(th->top_self, th->top_wrapper);
1490 
1491     val = rb_eval_string_protect(str, &state);
1492 
1493     th->top_self = self;
1494     th->top_wrapper = wrapper;
1495 
1496     if (pstate) {
1497 	*pstate = state;
1498     }
1499     else if (state != TAG_NONE) {
1500 	EC_JUMP_TAG(th->ec, state);
1501     }
1502     return val;
1503 }
1504 
1505 VALUE
rb_eval_cmd(VALUE cmd,VALUE arg,int level)1506 rb_eval_cmd(VALUE cmd, VALUE arg, int level)
1507 {
1508     enum ruby_tag_type state;
1509     volatile VALUE val = Qnil;		/* OK */
1510     const int VAR_NOCLOBBERED(current_safe_level) = rb_safe_level();
1511     rb_execution_context_t * volatile ec = GET_EC();
1512 
1513     if (OBJ_TAINTED(cmd)) {
1514 	level = RUBY_SAFE_LEVEL_MAX;
1515     }
1516 
1517     EC_PUSH_TAG(ec);
1518     rb_set_safe_level_force(level);
1519     if ((state = EC_EXEC_TAG()) == TAG_NONE) {
1520 	if (!RB_TYPE_P(cmd, T_STRING)) {
1521 	    val = rb_funcallv(cmd, idCall, RARRAY_LENINT(arg),
1522 			      RARRAY_CONST_PTR(arg));
1523 	}
1524 	else {
1525 	    val = eval_string_with_cref(rb_vm_top_self(), cmd, NULL, 0, 0);
1526 	}
1527     }
1528     EC_POP_TAG();
1529 
1530     rb_set_safe_level_force(current_safe_level);
1531     if (state) EC_JUMP_TAG(ec, state);
1532     return val;
1533 }
1534 
1535 /* block eval under the class/module context */
1536 
1537 static VALUE
yield_under(VALUE under,VALUE self,int argc,const VALUE * argv)1538 yield_under(VALUE under, VALUE self, int argc, const VALUE *argv)
1539 {
1540     rb_execution_context_t *ec = GET_EC();
1541     rb_control_frame_t *cfp = ec->cfp;
1542     VALUE block_handler = VM_CF_BLOCK_HANDLER(cfp);
1543     VALUE new_block_handler = 0;
1544     const struct rb_captured_block *captured = NULL;
1545     struct rb_captured_block new_captured;
1546     const VALUE *ep = NULL;
1547     rb_cref_t *cref;
1548     int is_lambda = FALSE;
1549 
1550     if (block_handler != VM_BLOCK_HANDLER_NONE) {
1551       again:
1552 	switch (vm_block_handler_type(block_handler)) {
1553 	  case block_handler_type_iseq:
1554 	    captured = VM_BH_TO_CAPT_BLOCK(block_handler);
1555 	    new_captured = *captured;
1556 	    new_block_handler = VM_BH_FROM_ISEQ_BLOCK(&new_captured);
1557 	    break;
1558 	  case block_handler_type_ifunc:
1559 	    captured = VM_BH_TO_CAPT_BLOCK(block_handler);
1560 	    new_captured = *captured;
1561 	    new_block_handler = VM_BH_FROM_IFUNC_BLOCK(&new_captured);
1562 	    break;
1563 	  case block_handler_type_proc:
1564 	    is_lambda = rb_proc_lambda_p(block_handler) != Qfalse;
1565 	    block_handler = vm_proc_to_block_handler(VM_BH_TO_PROC(block_handler));
1566 	    goto again;
1567 	  case block_handler_type_symbol:
1568 	    return rb_sym_proc_call(SYM2ID(VM_BH_TO_SYMBOL(block_handler)),
1569 				    argc, argv, VM_BLOCK_HANDLER_NONE);
1570 	}
1571 
1572 	new_captured.self = self;
1573 	ep = captured->ep;
1574 
1575 	VM_FORCE_WRITE_SPECIAL_CONST(&VM_CF_LEP(ec->cfp)[VM_ENV_DATA_INDEX_SPECVAL], new_block_handler);
1576     }
1577 
1578     cref = vm_cref_push(ec, under, ep, TRUE);
1579     return vm_yield_with_cref(ec, argc, argv, cref, is_lambda);
1580 }
1581 
1582 VALUE
rb_yield_refine_block(VALUE refinement,VALUE refinements)1583 rb_yield_refine_block(VALUE refinement, VALUE refinements)
1584 {
1585     rb_execution_context_t *ec = GET_EC();
1586     VALUE block_handler = VM_CF_BLOCK_HANDLER(ec->cfp);
1587 
1588     if (vm_block_handler_type(block_handler) != block_handler_type_iseq) {
1589 	rb_bug("rb_yield_refine_block: an iseq block is required");
1590     }
1591     else {
1592 	const struct rb_captured_block *captured = VM_BH_TO_ISEQ_BLOCK(block_handler);
1593 	struct rb_captured_block new_captured = *captured;
1594 	VALUE new_block_handler = VM_BH_FROM_ISEQ_BLOCK(&new_captured);
1595 	const VALUE *ep = captured->ep;
1596 	rb_cref_t *cref = vm_cref_push(ec, refinement, ep, TRUE);
1597 	CREF_REFINEMENTS_SET(cref, refinements);
1598 	VM_FORCE_WRITE_SPECIAL_CONST(&VM_CF_LEP(ec->cfp)[VM_ENV_DATA_INDEX_SPECVAL], new_block_handler);
1599 	new_captured.self = refinement;
1600 	return vm_yield_with_cref(ec, 0, NULL, cref, FALSE);
1601     }
1602 }
1603 
1604 /* string eval under the class/module context */
1605 static VALUE
eval_under(VALUE under,VALUE self,VALUE src,VALUE file,int line)1606 eval_under(VALUE under, VALUE self, VALUE src, VALUE file, int line)
1607 {
1608     rb_cref_t *cref = vm_cref_push(GET_EC(), under, NULL, SPECIAL_CONST_P(self) && !NIL_P(under));
1609     SafeStringValue(src);
1610     return eval_string_with_cref(self, src, cref, file, line);
1611 }
1612 
1613 static VALUE
specific_eval(int argc,const VALUE * argv,VALUE klass,VALUE self)1614 specific_eval(int argc, const VALUE *argv, VALUE klass, VALUE self)
1615 {
1616     if (rb_block_given_p()) {
1617 	rb_check_arity(argc, 0, 0);
1618 	return yield_under(klass, self, 1, &self);
1619     }
1620     else {
1621 	VALUE file = Qundef;
1622 	int line = 1;
1623 	VALUE code;
1624 
1625 	rb_check_arity(argc, 1, 3);
1626 	code = argv[0];
1627 	SafeStringValue(code);
1628 	if (argc > 2)
1629 	    line = NUM2INT(argv[2]);
1630 	if (argc > 1) {
1631 	    file = argv[1];
1632 	    if (!NIL_P(file)) StringValue(file);
1633 	}
1634 	return eval_under(klass, self, code, file, line);
1635     }
1636 }
1637 
1638 static VALUE
singleton_class_for_eval(VALUE self)1639 singleton_class_for_eval(VALUE self)
1640 {
1641     if (SPECIAL_CONST_P(self)) {
1642 	return rb_special_singleton_class(self);
1643     }
1644     switch (BUILTIN_TYPE(self)) {
1645       case T_FLOAT: case T_BIGNUM: case T_SYMBOL:
1646 	return Qnil;
1647       case T_STRING:
1648 	if (FL_TEST_RAW(self, RSTRING_FSTR)) return Qnil;
1649       default:
1650 	return rb_singleton_class(self);
1651     }
1652 }
1653 
1654 /*
1655  *  call-seq:
1656  *     obj.instance_eval(string [, filename [, lineno]] )   -> obj
1657  *     obj.instance_eval {|obj| block }                     -> obj
1658  *
1659  *  Evaluates a string containing Ruby source code, or the given block,
1660  *  within the context of the receiver (_obj_). In order to set the
1661  *  context, the variable +self+ is set to _obj_ while
1662  *  the code is executing, giving the code access to _obj_'s
1663  *  instance variables and private methods.
1664  *
1665  *  When <code>instance_eval</code> is given a block, _obj_ is also
1666  *  passed in as the block's only argument.
1667  *
1668  *  When <code>instance_eval</code> is given a +String+, the optional
1669  *  second and third parameters supply a filename and starting line number
1670  *  that are used when reporting compilation errors.
1671  *
1672  *     class KlassWithSecret
1673  *       def initialize
1674  *         @secret = 99
1675  *       end
1676  *       private
1677  *       def the_secret
1678  *         "Ssssh! The secret is #{@secret}."
1679  *       end
1680  *     end
1681  *     k = KlassWithSecret.new
1682  *     k.instance_eval { @secret }          #=> 99
1683  *     k.instance_eval { the_secret }       #=> "Ssssh! The secret is 99."
1684  *     k.instance_eval {|obj| obj == self } #=> true
1685  */
1686 
1687 VALUE
rb_obj_instance_eval(int argc,const VALUE * argv,VALUE self)1688 rb_obj_instance_eval(int argc, const VALUE *argv, VALUE self)
1689 {
1690     VALUE klass = singleton_class_for_eval(self);
1691     return specific_eval(argc, argv, klass, self);
1692 }
1693 
1694 /*
1695  *  call-seq:
1696  *     obj.instance_exec(arg...) {|var...| block }                       -> obj
1697  *
1698  *  Executes the given block within the context of the receiver
1699  *  (_obj_). In order to set the context, the variable +self+ is set
1700  *  to _obj_ while the code is executing, giving the code access to
1701  *  _obj_'s instance variables.  Arguments are passed as block parameters.
1702  *
1703  *     class KlassWithSecret
1704  *       def initialize
1705  *         @secret = 99
1706  *       end
1707  *     end
1708  *     k = KlassWithSecret.new
1709  *     k.instance_exec(5) {|x| @secret+x }   #=> 104
1710  */
1711 
1712 VALUE
rb_obj_instance_exec(int argc,const VALUE * argv,VALUE self)1713 rb_obj_instance_exec(int argc, const VALUE *argv, VALUE self)
1714 {
1715     VALUE klass = singleton_class_for_eval(self);
1716     return yield_under(klass, self, argc, argv);
1717 }
1718 
1719 /*
1720  *  call-seq:
1721  *     mod.class_eval(string [, filename [, lineno]])  -> obj
1722  *     mod.class_eval {|mod| block }                   -> obj
1723  *     mod.module_eval(string [, filename [, lineno]]) -> obj
1724  *     mod.module_eval {|mod| block }                  -> obj
1725  *
1726  *  Evaluates the string or block in the context of _mod_, except that when
1727  *  a block is given, constant/class variable lookup is not affected. This
1728  *  can be used to add methods to a class. <code>module_eval</code> returns
1729  *  the result of evaluating its argument. The optional _filename_ and
1730  *  _lineno_ parameters set the text for error messages.
1731  *
1732  *     class Thing
1733  *     end
1734  *     a = %q{def hello() "Hello there!" end}
1735  *     Thing.module_eval(a)
1736  *     puts Thing.new.hello()
1737  *     Thing.module_eval("invalid code", "dummy", 123)
1738  *
1739  *  <em>produces:</em>
1740  *
1741  *     Hello there!
1742  *     dummy:123:in `module_eval': undefined local variable
1743  *         or method `code' for Thing:Class
1744  */
1745 
1746 VALUE
rb_mod_module_eval(int argc,const VALUE * argv,VALUE mod)1747 rb_mod_module_eval(int argc, const VALUE *argv, VALUE mod)
1748 {
1749     return specific_eval(argc, argv, mod, mod);
1750 }
1751 
1752 /*
1753  *  call-seq:
1754  *     mod.module_exec(arg...) {|var...| block }       -> obj
1755  *     mod.class_exec(arg...) {|var...| block }        -> obj
1756  *
1757  *  Evaluates the given block in the context of the class/module.
1758  *  The method defined in the block will belong to the receiver.
1759  *  Any arguments passed to the method will be passed to the block.
1760  *  This can be used if the block needs to access instance variables.
1761  *
1762  *     class Thing
1763  *     end
1764  *     Thing.class_exec{
1765  *       def hello() "Hello there!" end
1766  *     }
1767  *     puts Thing.new.hello()
1768  *
1769  *  <em>produces:</em>
1770  *
1771  *     Hello there!
1772  */
1773 
1774 VALUE
rb_mod_module_exec(int argc,const VALUE * argv,VALUE mod)1775 rb_mod_module_exec(int argc, const VALUE *argv, VALUE mod)
1776 {
1777     return yield_under(mod, mod, argc, argv);
1778 }
1779 
1780 /*
1781  *  Document-class: UncaughtThrowError
1782  *
1783  *  Raised when +throw+ is called with a _tag_ which does not have
1784  *  corresponding +catch+ block.
1785  *
1786  *     throw "foo", "bar"
1787  *
1788  *  <em>raises the exception:</em>
1789  *
1790  *     UncaughtThrowError: uncaught throw "foo"
1791  */
1792 
1793 static VALUE
uncaught_throw_init(int argc,const VALUE * argv,VALUE exc)1794 uncaught_throw_init(int argc, const VALUE *argv, VALUE exc)
1795 {
1796     rb_check_arity(argc, 2, UNLIMITED_ARGUMENTS);
1797     rb_call_super(argc - 2, argv + 2);
1798     rb_ivar_set(exc, id_tag, argv[0]);
1799     rb_ivar_set(exc, id_value, argv[1]);
1800     return exc;
1801 }
1802 
1803 /*
1804  * call-seq:
1805  *   uncaught_throw.tag   -> obj
1806  *
1807  * Return the tag object which was called for.
1808  */
1809 
1810 static VALUE
uncaught_throw_tag(VALUE exc)1811 uncaught_throw_tag(VALUE exc)
1812 {
1813     return rb_ivar_get(exc, id_tag);
1814 }
1815 
1816 /*
1817  * call-seq:
1818  *   uncaught_throw.value   -> obj
1819  *
1820  * Return the return value which was called for.
1821  */
1822 
1823 static VALUE
uncaught_throw_value(VALUE exc)1824 uncaught_throw_value(VALUE exc)
1825 {
1826     return rb_ivar_get(exc, id_value);
1827 }
1828 
1829 /*
1830  * call-seq:
1831  *   uncaught_throw.to_s   ->  string
1832  *
1833  * Returns formatted message with the inspected tag.
1834  */
1835 
1836 static VALUE
uncaught_throw_to_s(VALUE exc)1837 uncaught_throw_to_s(VALUE exc)
1838 {
1839     VALUE mesg = rb_attr_get(exc, id_mesg);
1840     VALUE tag = uncaught_throw_tag(exc);
1841     return rb_str_format(1, &tag, mesg);
1842 }
1843 
1844 /*
1845  *  call-seq:
1846  *     throw(tag [, obj])
1847  *
1848  *  Transfers control to the end of the active +catch+ block
1849  *  waiting for _tag_. Raises +UncaughtThrowError+ if there
1850  *  is no +catch+ block for the _tag_. The optional second
1851  *  parameter supplies a return value for the +catch+ block,
1852  *  which otherwise defaults to +nil+. For examples, see
1853  *  <code>Kernel::catch</code>.
1854  */
1855 
1856 static VALUE
rb_f_throw(int argc,VALUE * argv)1857 rb_f_throw(int argc, VALUE *argv)
1858 {
1859     VALUE tag, value;
1860 
1861     rb_scan_args(argc, argv, "11", &tag, &value);
1862     rb_throw_obj(tag, value);
1863     UNREACHABLE_RETURN(Qnil);
1864 }
1865 
1866 void
rb_throw_obj(VALUE tag,VALUE value)1867 rb_throw_obj(VALUE tag, VALUE value)
1868 {
1869     rb_execution_context_t *ec = GET_EC();
1870     struct rb_vm_tag *tt = ec->tag;
1871 
1872     while (tt) {
1873 	if (tt->tag == tag) {
1874 	    tt->retval = value;
1875 	    break;
1876 	}
1877 	tt = tt->prev;
1878     }
1879     if (!tt) {
1880 	VALUE desc[3];
1881 	desc[0] = tag;
1882 	desc[1] = value;
1883 	desc[2] = rb_str_new_cstr("uncaught throw %p");
1884 	rb_exc_raise(rb_class_new_instance(numberof(desc), desc, rb_eUncaughtThrow));
1885     }
1886 
1887     ec->errinfo = (VALUE)THROW_DATA_NEW(tag, NULL, TAG_THROW);
1888     EC_JUMP_TAG(ec, TAG_THROW);
1889 }
1890 
1891 void
rb_throw(const char * tag,VALUE val)1892 rb_throw(const char *tag, VALUE val)
1893 {
1894     rb_throw_obj(rb_sym_intern_ascii_cstr(tag), val);
1895 }
1896 
1897 static VALUE
catch_i(VALUE tag,VALUE data)1898 catch_i(VALUE tag, VALUE data)
1899 {
1900     return rb_yield_0(1, &tag);
1901 }
1902 
1903 /*
1904  *  call-seq:
1905  *     catch([tag]) {|tag| block }  -> obj
1906  *
1907  *  +catch+ executes its block. If +throw+ is not called, the block executes
1908  *  normally, and +catch+ returns the value of the last expression evaluated.
1909  *
1910  *     catch(1) { 123 }            # => 123
1911  *
1912  *  If <code>throw(tag2, val)</code> is called, Ruby searches up its stack for
1913  *  a +catch+ block whose +tag+ has the same +object_id+ as _tag2_. When found,
1914  *  the block stops executing and returns _val_ (or +nil+ if no second argument
1915  *  was given to +throw+).
1916  *
1917  *     catch(1) { throw(1, 456) }  # => 456
1918  *     catch(1) { throw(1) }       # => nil
1919  *
1920  *  When +tag+ is passed as the first argument, +catch+ yields it as the
1921  *  parameter of the block.
1922  *
1923  *     catch(1) {|x| x + 2 }       # => 3
1924  *
1925  *  When no +tag+ is given, +catch+ yields a new unique object (as from
1926  *  +Object.new+) as the block parameter. This object can then be used as the
1927  *  argument to +throw+, and will match the correct +catch+ block.
1928  *
1929  *     catch do |obj_A|
1930  *       catch do |obj_B|
1931  *         throw(obj_B, 123)
1932  *         puts "This puts is not reached"
1933  *       end
1934  *
1935  *       puts "This puts is displayed"
1936  *       456
1937  *     end
1938  *
1939  *     # => 456
1940  *
1941  *     catch do |obj_A|
1942  *       catch do |obj_B|
1943  *         throw(obj_A, 123)
1944  *         puts "This puts is still not reached"
1945  *       end
1946  *
1947  *       puts "Now this puts is also not reached"
1948  *       456
1949  *     end
1950  *
1951  *     # => 123
1952  */
1953 
1954 static VALUE
rb_f_catch(int argc,VALUE * argv,VALUE self)1955 rb_f_catch(int argc, VALUE *argv, VALUE self)
1956 {
1957     VALUE tag = rb_check_arity(argc, 0, 1) ? argv[0] : rb_obj_alloc(rb_cObject);
1958     return rb_catch_obj(tag, catch_i, 0);
1959 }
1960 
1961 VALUE
rb_catch(const char * tag,VALUE (* func)(),VALUE data)1962 rb_catch(const char *tag, VALUE (*func)(), VALUE data)
1963 {
1964     VALUE vtag = tag ? rb_sym_intern_ascii_cstr(tag) : rb_obj_alloc(rb_cObject);
1965     return rb_catch_obj(vtag, func, data);
1966 }
1967 
1968 static VALUE
vm_catch_protect(VALUE tag,rb_block_call_func * func,VALUE data,enum ruby_tag_type * stateptr,rb_execution_context_t * volatile ec)1969 vm_catch_protect(VALUE tag, rb_block_call_func *func, VALUE data,
1970 		 enum ruby_tag_type *stateptr, rb_execution_context_t *volatile ec)
1971 {
1972     enum ruby_tag_type state;
1973     VALUE val = Qnil;		/* OK */
1974     rb_control_frame_t *volatile saved_cfp = ec->cfp;
1975 
1976     EC_PUSH_TAG(ec);
1977 
1978     _tag.tag = tag;
1979 
1980     if ((state = EC_EXEC_TAG()) == TAG_NONE) {
1981 	/* call with argc=1, argv = [tag], block = Qnil to insure compatibility */
1982 	val = (*func)(tag, data, 1, (const VALUE *)&tag, Qnil);
1983     }
1984     else if (state == TAG_THROW && THROW_DATA_VAL((struct vm_throw_data *)ec->errinfo) == tag) {
1985 	rb_vm_rewind_cfp(ec, saved_cfp);
1986 	val = ec->tag->retval;
1987 	ec->errinfo = Qnil;
1988 	state = 0;
1989     }
1990     EC_POP_TAG();
1991     if (stateptr)
1992 	*stateptr = state;
1993 
1994     return val;
1995 }
1996 
1997 VALUE
rb_catch_protect(VALUE t,rb_block_call_func * func,VALUE data,enum ruby_tag_type * stateptr)1998 rb_catch_protect(VALUE t, rb_block_call_func *func, VALUE data, enum ruby_tag_type *stateptr)
1999 {
2000     return vm_catch_protect(t, func, data, stateptr, GET_EC());
2001 }
2002 
2003 VALUE
rb_catch_obj(VALUE t,VALUE (* func)(),VALUE data)2004 rb_catch_obj(VALUE t, VALUE (*func)(), VALUE data)
2005 {
2006     enum ruby_tag_type state;
2007     rb_execution_context_t *ec = GET_EC();
2008     VALUE val = vm_catch_protect(t, (rb_block_call_func *)func, data, &state, ec);
2009     if (state) EC_JUMP_TAG(ec, state);
2010     return val;
2011 }
2012 
2013 static void
local_var_list_init(struct local_var_list * vars)2014 local_var_list_init(struct local_var_list *vars)
2015 {
2016     vars->tbl = rb_hash_new_compare_by_id();
2017     RBASIC_CLEAR_CLASS(vars->tbl);
2018 }
2019 
2020 static VALUE
local_var_list_finish(struct local_var_list * vars)2021 local_var_list_finish(struct local_var_list *vars)
2022 {
2023     /* TODO: not to depend on the order of st_table */
2024     VALUE ary = rb_hash_keys(vars->tbl);
2025     rb_hash_clear(vars->tbl);
2026     vars->tbl = 0;
2027     return ary;
2028 }
2029 
2030 static int
local_var_list_update(st_data_t * key,st_data_t * value,st_data_t arg,int existing)2031 local_var_list_update(st_data_t *key, st_data_t *value, st_data_t arg, int existing)
2032 {
2033     if (existing) return ST_STOP;
2034     *value = (st_data_t)Qtrue;	/* INT2FIX(arg) */
2035     return ST_CONTINUE;
2036 }
2037 
2038 static void
local_var_list_add(const struct local_var_list * vars,ID lid)2039 local_var_list_add(const struct local_var_list *vars, ID lid)
2040 {
2041     if (lid && rb_is_local_id(lid)) {
2042         /* should skip temporary variable */
2043         st_data_t idx = 0;	/* tbl->num_entries */
2044         rb_hash_stlike_update(vars->tbl, ID2SYM(lid), local_var_list_update, idx);
2045     }
2046 }
2047 
2048 /*
2049  *  call-seq:
2050  *     local_variables    -> array
2051  *
2052  *  Returns the names of the current local variables.
2053  *
2054  *     fred = 1
2055  *     for i in 1..10
2056  *        # ...
2057  *     end
2058  *     local_variables   #=> [:fred, :i]
2059  */
2060 
2061 static VALUE
rb_f_local_variables(void)2062 rb_f_local_variables(void)
2063 {
2064     struct local_var_list vars;
2065     rb_execution_context_t *ec = GET_EC();
2066     rb_control_frame_t *cfp = vm_get_ruby_level_caller_cfp(ec, RUBY_VM_PREVIOUS_CONTROL_FRAME(ec->cfp));
2067     unsigned int i;
2068 
2069     local_var_list_init(&vars);
2070     while (cfp) {
2071 	if (cfp->iseq) {
2072 	    for (i = 0; i < cfp->iseq->body->local_table_size; i++) {
2073 		local_var_list_add(&vars, cfp->iseq->body->local_table[i]);
2074 	    }
2075 	}
2076 	if (!VM_ENV_LOCAL_P(cfp->ep)) {
2077 	    /* block */
2078 	    const VALUE *ep = VM_CF_PREV_EP(cfp);
2079 
2080 	    if (vm_collect_local_variables_in_heap(ep, &vars)) {
2081 		break;
2082 	    }
2083 	    else {
2084 		while (cfp->ep != ep) {
2085 		    cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
2086 		}
2087 	    }
2088 	}
2089 	else {
2090 	    break;
2091 	}
2092     }
2093     return local_var_list_finish(&vars);
2094 }
2095 
2096 /*
2097  *  call-seq:
2098  *     block_given?   -> true or false
2099  *     iterator?      -> true or false
2100  *
2101  *  Returns <code>true</code> if <code>yield</code> would execute a
2102  *  block in the current context. The <code>iterator?</code> form
2103  *  is mildly deprecated.
2104  *
2105  *     def try
2106  *       if block_given?
2107  *         yield
2108  *       else
2109  *         "no block"
2110  *       end
2111  *     end
2112  *     try                  #=> "no block"
2113  *     try { "hello" }      #=> "hello"
2114  *     try do "hello" end   #=> "hello"
2115  */
2116 
2117 
2118 static VALUE
rb_f_block_given_p(void)2119 rb_f_block_given_p(void)
2120 {
2121     rb_execution_context_t *ec = GET_EC();
2122     rb_control_frame_t *cfp = ec->cfp;
2123     cfp = vm_get_ruby_level_caller_cfp(ec, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
2124 
2125     if (cfp != NULL && VM_CF_BLOCK_HANDLER(cfp) != VM_BLOCK_HANDLER_NONE) {
2126 	return Qtrue;
2127     }
2128     else {
2129 	return Qfalse;
2130     }
2131 }
2132 
2133 VALUE
rb_current_realfilepath(void)2134 rb_current_realfilepath(void)
2135 {
2136     const rb_execution_context_t *ec = GET_EC();
2137     rb_control_frame_t *cfp = ec->cfp;
2138     cfp = vm_get_ruby_level_caller_cfp(ec, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
2139     if (cfp != 0) return rb_iseq_realpath(cfp->iseq);
2140     return Qnil;
2141 }
2142 
2143 void
Init_vm_eval(void)2144 Init_vm_eval(void)
2145 {
2146     rb_define_global_function("eval", rb_f_eval, -1);
2147     rb_define_global_function("local_variables", rb_f_local_variables, 0);
2148     rb_define_global_function("iterator?", rb_f_block_given_p, 0);
2149     rb_define_global_function("block_given?", rb_f_block_given_p, 0);
2150 
2151     rb_define_global_function("catch", rb_f_catch, -1);
2152     rb_define_global_function("throw", rb_f_throw, -1);
2153 
2154     rb_define_global_function("loop", rb_f_loop, 0);
2155 
2156     rb_define_method(rb_cBasicObject, "instance_eval", rb_obj_instance_eval, -1);
2157     rb_define_method(rb_cBasicObject, "instance_exec", rb_obj_instance_exec, -1);
2158     rb_define_private_method(rb_cBasicObject, "method_missing", rb_method_missing, -1);
2159 
2160 #if 1
2161     rb_add_method(rb_cBasicObject, id__send__,
2162 		  VM_METHOD_TYPE_OPTIMIZED, (void *)OPTIMIZED_METHOD_TYPE_SEND, METHOD_VISI_PUBLIC);
2163     rb_add_method(rb_mKernel, idSend,
2164 		  VM_METHOD_TYPE_OPTIMIZED, (void *)OPTIMIZED_METHOD_TYPE_SEND, METHOD_VISI_PUBLIC);
2165 #else
2166     rb_define_method(rb_cBasicObject, "__send__", rb_f_send, -1);
2167     rb_define_method(rb_mKernel, "send", rb_f_send, -1);
2168 #endif
2169     rb_define_method(rb_mKernel, "public_send", rb_f_public_send, -1);
2170 
2171     rb_define_method(rb_cModule, "module_exec", rb_mod_module_exec, -1);
2172     rb_define_method(rb_cModule, "class_exec", rb_mod_module_exec, -1);
2173     rb_define_method(rb_cModule, "module_eval", rb_mod_module_eval, -1);
2174     rb_define_method(rb_cModule, "class_eval", rb_mod_module_eval, -1);
2175 
2176     rb_eUncaughtThrow = rb_define_class("UncaughtThrowError", rb_eArgError);
2177     rb_define_method(rb_eUncaughtThrow, "initialize", uncaught_throw_init, -1);
2178     rb_define_method(rb_eUncaughtThrow, "tag", uncaught_throw_tag, 0);
2179     rb_define_method(rb_eUncaughtThrow, "value", uncaught_throw_value, 0);
2180     rb_define_method(rb_eUncaughtThrow, "to_s", uncaught_throw_to_s, 0);
2181 
2182     id_result = rb_intern_const("result");
2183     id_tag = rb_intern_const("tag");
2184     id_value = rb_intern_const("value");
2185 }
2186 
2187 #endif /* #ifndef MJIT_HEADER */
2188