Ruby 2.0.0p247(2013-06-27revision41674)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

vm_eval.c
Go to the documentation of this file.
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 static inline VALUE method_missing(VALUE obj, ID id, int argc, const VALUE *argv, int call_status);
15 static inline VALUE vm_yield_with_cref(rb_thread_t *th, int argc, const VALUE *argv, const NODE *cref);
16 static inline VALUE vm_yield(rb_thread_t *th, int argc, const VALUE *argv);
17 static NODE *vm_cref_push(rb_thread_t *th, VALUE klass, int noex, rb_block_t *blockptr);
18 static VALUE vm_exec(rb_thread_t *th);
19 static void vm_set_eval_stack(rb_thread_t * th, VALUE iseqval, const NODE *cref, rb_block_t *base_block);
20 static int vm_collect_local_variables_in_heap(rb_thread_t *th, VALUE *dfp, VALUE ary);
21
22 /* vm_backtrace.c */
23 VALUE vm_backtrace_str_ary(rb_thread_t *th, int lev, int n);
24
25 typedef enum call_type {
26 CALL_PUBLIC,
27 CALL_FCALL,
28 CALL_VCALL,
29 CALL_TYPE_MAX
30 } call_type;
31
32 static VALUE send_internal(int argc, const VALUE *argv, VALUE recv, call_type scope);
33
34 static VALUE vm_call0_body(rb_thread_t* th, rb_call_info_t *ci, const VALUE *argv);
35
36 static VALUE
37 vm_call0(rb_thread_t* th, VALUE recv, VALUE id, int argc, const VALUE *argv,
38 const rb_method_entry_t *me, VALUE defined_class)
39 {
40 rb_call_info_t ci_entry, *ci = &ci_entry;
41
42 ci->flag = 0;
43 ci->mid = id;
44 ci->recv = recv;
45 ci->defined_class = defined_class;
46 ci->argc = argc;
47 ci->me = me;
48
49 return vm_call0_body(th, ci, argv);
50 }
51
52 #if OPT_CALL_CFUNC_WITHOUT_FRAME
53 static VALUE
54 vm_call0_cfunc(rb_thread_t* th, rb_call_info_t *ci, const VALUE *argv)
55 {
56 VALUE val;
57
58 RUBY_DTRACE_CMETHOD_ENTRY_HOOK(th, ci->defined_class, ci->mid);
59 EXEC_EVENT_HOOK(th, RUBY_EVENT_C_CALL, ci->recv, ci->mid, ci->defined_class, Qnil);
60 {
61 rb_control_frame_t *reg_cfp = th->cfp;
62 const rb_method_entry_t *me = ci->me;
63 const rb_method_cfunc_t *cfunc = &me->def->body.cfunc;
64 int len = cfunc->argc;
65
66 if (len >= 0) rb_check_arity(ci->argc, len, len);
67
68 th->passed_ci = ci;
69 ci->aux.inc_sp = 0;
70 VM_PROFILE_UP(2);
71 val = (*cfunc->invoker)(cfunc->func, ci, argv);
72
73 if (reg_cfp == th->cfp) {
74 if (UNLIKELY(th->passed_ci != ci)) {
75 rb_bug("vm_call0_cfunc: passed_ci error (ci: %p, passed_ci: %p)", ci, th->passed_ci);
76 }
77 th->passed_ci = 0;
78 }
79 else {
80 if (reg_cfp != th->cfp + 1) {
81 rb_bug("vm_call0_cfunc: cfp consistency error");
82 }
83 VM_PROFILE_UP(3);
84 vm_pop_frame(th);
85 }
86 }
87 EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, ci->recv, ci->mid, ci->defined_class, val);
88 RUBY_DTRACE_CMETHOD_RETURN_HOOK(th, ci->defined_class, ci->mid);
89
90 return val;
91 }
92 #else
93 static VALUE
94 vm_call0_cfunc_with_frame(rb_thread_t* th, rb_call_info_t *ci, const VALUE *argv)
95 {
96 VALUE val;
97 const rb_method_entry_t *me = ci->me;
98 const rb_method_cfunc_t *cfunc = &me->def->body.cfunc;
99 int len = cfunc->argc;
100 VALUE recv = ci->recv;
101 VALUE defined_class = ci->defined_class;
102 int argc = ci->argc;
103 ID mid = ci->mid;
104 rb_block_t *blockptr = ci->blockptr;
105
106 RUBY_DTRACE_CMETHOD_ENTRY_HOOK(th, defined_class, mid);
107 EXEC_EVENT_HOOK(th, RUBY_EVENT_C_CALL, recv, mid, defined_class, Qnil);
108 {
109 rb_control_frame_t *reg_cfp = th->cfp;
110
111 vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC, recv, defined_class,
112 VM_ENVVAL_BLOCK_PTR(blockptr), 0, reg_cfp->sp, 1, me);
113
114 if (len >= 0) rb_check_arity(argc, len, len);
115
116 VM_PROFILE_UP(2);
117 val = (*cfunc->invoker)(cfunc->func, recv, argc, argv);
118
119 if (UNLIKELY(reg_cfp != th->cfp + 1)) {
120 rb_bug("vm_call0_cfunc_with_frame: cfp consistency error");
121 }
122 VM_PROFILE_UP(3);
123 vm_pop_frame(th);
124 }
125 EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, recv, mid, defined_class, val);
126 RUBY_DTRACE_CMETHOD_RETURN_HOOK(th, defined_class, mid);
127
128 return val;
129 }
130
131 static VALUE
132 vm_call0_cfunc(rb_thread_t* th, rb_call_info_t *ci, const VALUE *argv)
133 {
134 return vm_call0_cfunc_with_frame(th, ci, argv);
135 }
136 #endif
137
138 /* `ci' should point temporal value (on stack value) */
139 static VALUE
140 vm_call0_body(rb_thread_t* th, rb_call_info_t *ci, const VALUE *argv)
141 {
142 VALUE ret;
143
144 if (!ci->me->def) return Qnil;
145
146 if (th->passed_block) {
147 ci->blockptr = (rb_block_t *)th->passed_block;
148 th->passed_block = 0;
149 }
150 else {
151 ci->blockptr = 0;
152 }
153
154 again:
155 switch (ci->me->def->type) {
156 case VM_METHOD_TYPE_ISEQ:
157 {
158 rb_control_frame_t *reg_cfp = th->cfp;
159 int i;
160
161 CHECK_VM_STACK_OVERFLOW(reg_cfp, ci->argc + 1);
162
163 *reg_cfp->sp++ = ci->recv;
164 for (i = 0; i < ci->argc; i++) {
165 *reg_cfp->sp++ = argv[i];
166 }
167
168 vm_call_iseq_setup(th, reg_cfp, ci);
169 th->cfp->flag |= VM_FRAME_FLAG_FINISH;
170 return vm_exec(th); /* CHECK_INTS in this function */
171 }
172 case VM_METHOD_TYPE_NOTIMPLEMENTED:
173 case VM_METHOD_TYPE_CFUNC:
174 ret = vm_call0_cfunc(th, ci, argv);
175 goto success;
176 case VM_METHOD_TYPE_ATTRSET:
177 rb_check_arity(ci->argc, 1, 1);
178 ret = rb_ivar_set(ci->recv, ci->me->def->body.attr.id, argv[0]);
179 goto success;
180 case VM_METHOD_TYPE_IVAR:
181 rb_check_arity(ci->argc, 0, 0);
182 ret = rb_attr_get(ci->recv, ci->me->def->body.attr.id);
183 goto success;
184 case VM_METHOD_TYPE_BMETHOD:
185 ret = vm_call_bmethod_body(th, ci, argv);
186 goto success;
187 case VM_METHOD_TYPE_ZSUPER:
188 case VM_METHOD_TYPE_REFINED:
189 {
190 if (ci->me->def->type == VM_METHOD_TYPE_REFINED &&
191 ci->me->def->body.orig_me) {
192 ci->me = ci->me->def->body.orig_me;
193 goto again;
194 }
195
196 ci->defined_class = RCLASS_SUPER(ci->defined_class);
197
198 if (!ci->defined_class || !(ci->me = rb_method_entry(ci->defined_class, ci->mid, &ci->defined_class))) {
199 ret = method_missing(ci->recv, ci->mid, ci->argc, argv, NOEX_SUPER);
200 goto success;
201 }
202 RUBY_VM_CHECK_INTS(th);
203 if (!ci->me->def) return Qnil;
204 goto again;
205 }
206 case VM_METHOD_TYPE_MISSING:
207 {
208 VALUE new_args = rb_ary_new4(ci->argc, argv);
209
210 RB_GC_GUARD(new_args);
211 rb_ary_unshift(new_args, ID2SYM(ci->mid));
212 th->passed_block = ci->blockptr;
213 return rb_funcall2(ci->recv, idMethodMissing, ci->argc+1, RARRAY_PTR(new_args));
214 }
215 case VM_METHOD_TYPE_OPTIMIZED:
216 switch (ci->me->def->body.optimize_type) {
217 case OPTIMIZED_METHOD_TYPE_SEND:
218 ret = send_internal(ci->argc, argv, ci->recv, CALL_FCALL);
219 goto success;
220 case OPTIMIZED_METHOD_TYPE_CALL:
221 {
222 rb_proc_t *proc;
223 GetProcPtr(ci->recv, proc);
224 ret = rb_vm_invoke_proc(th, proc, ci->argc, argv, ci->blockptr);
225 goto success;
226 }
227 default:
228 rb_bug("vm_call0: unsupported optimized method type (%d)", ci->me->def->body.optimize_type);
229 }
230 break;
231 case VM_METHOD_TYPE_UNDEF:
232 break;
233 }
234 rb_bug("vm_call0: unsupported method type (%d)", ci->me->def->type);
235 return Qundef;
236
237 success:
238 RUBY_VM_CHECK_INTS(th);
239 return ret;
240 }
241
242 VALUE
243 rb_vm_call(rb_thread_t *th, VALUE recv, VALUE id, int argc, const VALUE *argv,
244 const rb_method_entry_t *me, VALUE defined_class)
245 {
246 return vm_call0(th, recv, id, argc, argv, me, defined_class);
247 }
248
249 static inline VALUE
250 vm_call_super(rb_thread_t *th, int argc, const VALUE *argv)
251 {
252 VALUE recv = th->cfp->self;
253 VALUE klass;
254 ID id;
255 rb_method_entry_t *me;
256 rb_control_frame_t *cfp = th->cfp;
257
258 if (cfp->iseq || NIL_P(cfp->klass)) {
259 rb_bug("vm_call_super: should not be reached");
260 }
261
262 klass = RCLASS_SUPER(cfp->klass);
263 id = cfp->me->def->original_id;
264 me = rb_method_entry(klass, id, &klass);
265 if (!me) {
266 return method_missing(recv, id, argc, argv, NOEX_SUPER);
267 }
268
269 return vm_call0(th, recv, id, argc, argv, me, klass);
270 }
271
272 VALUE
273 rb_call_super(int argc, const VALUE *argv)
274 {
275 PASS_PASSED_BLOCK();
276 return vm_call_super(GET_THREAD(), argc, argv);
277 }
278
279 static inline void
280 stack_check(void)
281 {
282 rb_thread_t *th = GET_THREAD();
283
284 if (!rb_thread_raised_p(th, RAISED_STACKOVERFLOW) && ruby_stack_check()) {
285 rb_thread_raised_set(th, RAISED_STACKOVERFLOW);
286 rb_exc_raise(sysstack_error);
287 }
288 }
289
290 static inline rb_method_entry_t *
291 rb_search_method_entry(VALUE recv, ID mid, VALUE *defined_class_ptr);
292 static inline int rb_method_call_status(rb_thread_t *th, const rb_method_entry_t *me, call_type scope, VALUE self);
293 #define NOEX_OK NOEX_NOSUPER
294
310 static inline VALUE
311 rb_call0(VALUE recv, ID mid, int argc, const VALUE *argv,
312 call_type scope, VALUE self)
313 {
314 VALUE defined_class;
315 rb_method_entry_t *me =
316 rb_search_method_entry(recv, mid, &defined_class);
317 rb_thread_t *th = GET_THREAD();
318 int call_status = rb_method_call_status(th, me, scope, self);
319
320 if (call_status != NOEX_OK) {
321 return method_missing(recv, mid, argc, argv, call_status);
322 }
323 stack_check();
324 return vm_call0(th, recv, mid, argc, argv, me, defined_class);
325 }
326
327 struct rescue_funcall_args {
328 VALUE recv;
329 VALUE sym;
330 int argc;
331 VALUE *argv;
332 };
333
334 static VALUE
335 check_funcall_exec(struct rescue_funcall_args *args)
336 {
337 VALUE new_args = rb_ary_new4(args->argc, args->argv);
338
339 RB_GC_GUARD(new_args);
340 rb_ary_unshift(new_args, args->sym);
341 return rb_funcall2(args->recv, idMethodMissing,
342 args->argc+1, RARRAY_PTR(new_args));
343 }
344
345 static VALUE
346 check_funcall_failed(struct rescue_funcall_args *args, VALUE e)
347 {
348 if (rb_respond_to(args->recv, SYM2ID(args->sym))) {
349 rb_exc_raise(e);
350 }
351 return Qundef;
352 }
353
354 static int
355 check_funcall_respond_to(rb_thread_t *th, VALUE klass, VALUE recv, ID mid)
356 {
357 VALUE defined_class;
358 const rb_method_entry_t *me = rb_method_entry(klass, idRespond_to, &defined_class);
359
360 if (me && !(me->flag & NOEX_BASIC)) {
361 const rb_block_t *passed_block = th->passed_block;
362 VALUE args[2], result;
363 int arity = rb_method_entry_arity(me);
364
365 if (arity > 2)
366 rb_raise(rb_eArgError, "respond_to? must accept 1 or 2 arguments (requires %d)", arity);
367
368 if (arity < 1) arity = 2;
369
370 args[0] = ID2SYM(mid);
371 args[1] = Qtrue;
372 result = vm_call0(th, recv, idRespond_to, arity, args, me, defined_class);
373 th->passed_block = passed_block;
374 if (!RTEST(result)) {
375 return FALSE;
376 }
377 }
378 return TRUE;
379 }
380
381 static int
382 check_funcall_callable(rb_thread_t *th, const rb_method_entry_t *me)
383 {
384 return rb_method_call_status(th, me, CALL_FCALL, th->cfp->self) == NOEX_OK;
385 }
386
387 static VALUE
388 check_funcall_missing(rb_thread_t *th, VALUE klass, VALUE recv, ID mid, int argc, VALUE *argv)
389 {
390 if (rb_method_basic_definition_p(klass, idMethodMissing)) {
391 return Qundef;
392 }
393 else {
394 struct rescue_funcall_args args;
395
396 th->method_missing_reason = 0;
397 args.recv = recv;
398 args.sym = ID2SYM(mid);
399 args.argc = argc;
400 args.argv = argv;
401 return rb_rescue2(check_funcall_exec, (VALUE)&args,
402 check_funcall_failed, (VALUE)&args,
403 rb_eNoMethodError, (VALUE)0);
404 }
405 }
406
407 VALUE
408 rb_check_funcall(VALUE recv, ID mid, int argc, VALUE *argv)
409 {
410 VALUE klass = CLASS_OF(recv);
411 const rb_method_entry_t *me;
412 rb_thread_t *th = GET_THREAD();
413 VALUE defined_class;
414
415 if (!check_funcall_respond_to(th, klass, recv, mid))
416 return Qundef;
417
418 me = rb_search_method_entry(recv, mid, &defined_class);
419 if (check_funcall_callable(th, me) != NOEX_OK) {
420 return check_funcall_missing(th, klass, recv, mid, argc, argv);
421 }
422 stack_check();
423 return vm_call0(th, recv, mid, argc, argv, me, defined_class);
424 }
425
426 VALUE
427 rb_check_funcall_with_hook(VALUE recv, ID mid, int argc, VALUE *argv,
428 rb_check_funcall_hook *hook, VALUE arg)
429 {
430 VALUE klass = CLASS_OF(recv);
431 const rb_method_entry_t *me;
432 rb_thread_t *th = GET_THREAD();
433 VALUE defined_class;
434
435 if (!check_funcall_respond_to(th, klass, recv, mid))
436 return Qundef;
437
438 me = rb_search_method_entry(recv, mid, &defined_class);
439 if (check_funcall_callable(th, me) != NOEX_OK) {
440 (*hook)(FALSE, recv, mid, argc, argv, arg);
441 return check_funcall_missing(th, klass, recv, mid, argc, argv);
442 }
443 stack_check();
444 (*hook)(TRUE, recv, mid, argc, argv, arg);
445 return vm_call0(th, recv, mid, argc, argv, me, defined_class);
446 }
447
448 static const char *
449 rb_type_str(enum ruby_value_type type)
450 {
451 #define type_case(t) case t: return #t;
452 switch (type) {
453 type_case(T_NONE)
454 type_case(T_OBJECT)
455 type_case(T_CLASS)
456 type_case(T_MODULE)
457 type_case(T_FLOAT)
458 type_case(T_STRING)
459 type_case(T_REGEXP)
460 type_case(T_ARRAY)
461 type_case(T_HASH)
462 type_case(T_STRUCT)
463 type_case(T_BIGNUM)
464 type_case(T_FILE)
465 type_case(T_DATA)
466 type_case(T_MATCH)
467 type_case(T_COMPLEX)
468 type_case(T_RATIONAL)
469 type_case(T_NIL)
470 type_case(T_TRUE)
471 type_case(T_FALSE)
472 type_case(T_SYMBOL)
473 type_case(T_FIXNUM)
474 type_case(T_UNDEF)
475 type_case(T_NODE)
476 type_case(T_ICLASS)
477 type_case(T_ZOMBIE)
478 default: return NULL;
479 }
480 #undef type_case
481 }
482
483 static inline rb_method_entry_t *
484 rb_search_method_entry(VALUE recv, ID mid, VALUE *defined_class_ptr)
485 {
486 VALUE klass = CLASS_OF(recv);
487
488 if (!klass) {
489 VALUE flags, klass;
490 if (IMMEDIATE_P(recv)) {
491 rb_raise(rb_eNotImpError,
492 "method `%s' called on unexpected immediate object (%p)",
493 rb_id2name(mid), (void *)recv);
494 }
495 flags = RBASIC(recv)->flags;
496 klass = RBASIC(recv)->klass;
497 if (flags == 0) {
498 rb_raise(rb_eNotImpError,
499 "method `%s' called on terminated object"
500 " (%p flags=0x%"PRIxVALUE" klass=0x%"PRIxVALUE")",
501 rb_id2name(mid), (void *)recv, flags, klass);
502 }
503 else {
504 int type = BUILTIN_TYPE(recv);
505 const char *typestr = rb_type_str(type);
506 if (typestr && T_OBJECT <= type && type < T_NIL)
507 rb_raise(rb_eNotImpError,
508 "method `%s' called on hidden %s object"
509 " (%p flags=0x%"PRIxVALUE" klass=0x%"PRIxVALUE")",
510 rb_id2name(mid), typestr, (void *)recv, flags, klass);
511 if (typestr)
512 rb_raise(rb_eNotImpError,
513 "method `%s' called on unexpected %s object"
514 " (%p flags=0x%"PRIxVALUE" klass=0x%"PRIxVALUE")",
515 rb_id2name(mid), typestr, (void *)recv, flags, klass);
516 else
517 rb_raise(rb_eNotImpError,
518 "method `%s' called on broken T_???" "(0x%02x) object"
519 " (%p flags=0x%"PRIxVALUE" klass=0x%"PRIxVALUE")",
520 rb_id2name(mid), type, (void *)recv, flags, klass);
521 }
522 }
523 return rb_method_entry(klass, mid, defined_class_ptr);
524 }
525
526 static inline int
527 rb_method_call_status(rb_thread_t *th, const rb_method_entry_t *me, call_type scope, VALUE self)
528 {
529 VALUE klass;
530 ID oid;
531 int noex;
532
533 if (UNDEFINED_METHOD_ENTRY_P(me)) {
534 return scope == CALL_VCALL ? NOEX_VCALL : 0;
535 }
536 klass = me->klass;
537 oid = me->def->original_id;
538 noex = me->flag;
539
540 if (oid != idMethodMissing) {
541 /* receiver specified form for private method */
542 if (UNLIKELY(noex)) {
543 if (((noex & NOEX_MASK) & NOEX_PRIVATE) && scope == CALL_PUBLIC) {
544 return NOEX_PRIVATE;
545 }
546
547 /* self must be kind of a specified form for protected method */
548 if (((noex & NOEX_MASK) & NOEX_PROTECTED) && scope == CALL_PUBLIC) {
549 VALUE defined_class = klass;
550
551 if (RB_TYPE_P(defined_class, T_ICLASS)) {
552 defined_class = RBASIC(defined_class)->klass;
553 }
554
555 if (self == Qundef || !rb_obj_is_kind_of(self, defined_class)) {
556 return NOEX_PROTECTED;
557 }
558 }
559
560 if (NOEX_SAFE(noex) > th->safe_level) {
561 rb_raise(rb_eSecurityError, "calling insecure method: %s",
562 rb_id2name(me->called_id));
563 }
564 }
565 }
566 return NOEX_OK;
567 }
568
569
581 static inline VALUE
582 rb_call(VALUE recv, ID mid, int argc, const VALUE *argv, call_type scope)
583 {
584 rb_thread_t *th = GET_THREAD();
585 return rb_call0(recv, mid, argc, argv, scope, th->cfp->self);
586 }
587
588 NORETURN(static void raise_method_missing(rb_thread_t *th, int argc, const VALUE *argv,
589 VALUE obj, int call_status));
590
591 /*
592 * call-seq:
593 * obj.method_missing(symbol [, *args] ) -> result
594 *
595 * Invoked by Ruby when <i>obj</i> is sent a message it cannot handle.
596 * <i>symbol</i> is the symbol for the method called, and <i>args</i>
597 * are any arguments that were passed to it. By default, the interpreter
598 * raises an error when this method is called. However, it is possible
599 * to override the method to provide more dynamic behavior.
600 * If it is decided that a particular method should not be handled, then
601 * <i>super</i> should be called, so that ancestors can pick up the
602 * missing method.
603 * The example below creates
604 * a class <code>Roman</code>, which responds to methods with names
605 * consisting of roman numerals, returning the corresponding integer
606 * values.
607 *
608 * class Roman
609 * def roman_to_int(str)
610 * # ...
611 * end
612 * def method_missing(methId)
613 * str = methId.id2name
614 * roman_to_int(str)
615 * end
616 * end
617 *
618 * r = Roman.new
619 * r.iv #=> 4
620 * r.xxiii #=> 23
621 * r.mm #=> 2000
622 */
623
624 static VALUE
625 rb_method_missing(int argc, const VALUE *argv, VALUE obj)
626 {
627 rb_thread_t *th = GET_THREAD();
628 raise_method_missing(th, argc, argv, obj, th->method_missing_reason);
629 UNREACHABLE;
630 }
631
632 #define NOEX_MISSING 0x80
633
634 static VALUE
635 make_no_method_exception(VALUE exc, const char *format, VALUE obj, int argc, const VALUE *argv)
636 {
637 int n = 0;
638 VALUE mesg;
639 VALUE args[3];
640
641 if (!format) {
642 format = "undefined method `%s' for %s";
643 }
644 mesg = rb_const_get(exc, rb_intern("message"));
645 if (rb_method_basic_definition_p(CLASS_OF(mesg), '!')) {
646 args[n++] = rb_name_err_mesg_new(mesg, rb_str_new2(format), obj, argv[0]);
647 }
648 else {
649 args[n++] = rb_funcall(mesg, '!', 3, rb_str_new2(format), obj, argv[0]);
650 }
651 args[n++] = argv[0];
652 if (exc == rb_eNoMethodError) {
653 args[n++] = rb_ary_new4(argc - 1, argv + 1);
654 }
655 return rb_class_new_instance(n, args, exc);
656 }
657
658 static void
659 raise_method_missing(rb_thread_t *th, int argc, const VALUE *argv, VALUE obj,
660 int last_call_status)
661 {
662 VALUE exc = rb_eNoMethodError;
663 const char *format = 0;
664
665 if (argc == 0 || !SYMBOL_P(argv[0])) {
666 rb_raise(rb_eArgError, "no id given");
667 }
668
669 stack_check();
670
671 if (last_call_status & NOEX_PRIVATE) {
672 format = "private method `%s' called for %s";
673 }
674 else if (last_call_status & NOEX_PROTECTED) {
675 format = "protected method `%s' called for %s";
676 }
677 else if (last_call_status & NOEX_VCALL) {
678 format = "undefined local variable or method `%s' for %s";
679 exc = rb_eNameError;
680 }
681 else if (last_call_status & NOEX_SUPER) {
682 format = "super: no superclass method `%s' for %s";
683 }
684
685 {
686 exc = make_no_method_exception(exc, format, obj, argc, argv);
687 if (!(last_call_status & NOEX_MISSING)) {
688 th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp);
689 }
690 rb_exc_raise(exc);
691 }
692 }
693
694 static inline VALUE
695 method_missing(VALUE obj, ID id, int argc, const VALUE *argv, int call_status)
696 {
697 VALUE *nargv, result, argv_ary = 0;
698 rb_thread_t *th = GET_THREAD();
699 const rb_block_t *blockptr = th->passed_block;
700
701 th->method_missing_reason = call_status;
702 th->passed_block = 0;
703
704 if (id == idMethodMissing) {
705 raise_method_missing(th, argc, argv, obj, call_status | NOEX_MISSING);
706 }
707
708 if (argc < 0x100) {
709 nargv = ALLOCA_N(VALUE, argc + 1);
710 }
711 else {
712 argv_ary = rb_ary_tmp_new(argc + 1);
713 nargv = RARRAY_PTR(argv_ary);
714 }
715 nargv[0] = ID2SYM(id);
716 MEMCPY(nargv + 1, argv, VALUE, argc);
717 if (argv_ary) rb_ary_set_len(argv_ary, argc + 1);
718
719 if (rb_method_basic_definition_p(CLASS_OF(obj) , idMethodMissing)) {
720 raise_method_missing(th, argc+1, nargv, obj, call_status | NOEX_MISSING);
721 }
722 th->passed_block = blockptr;
723 result = rb_funcall2(obj, idMethodMissing, argc + 1, nargv);
724 if (argv_ary) rb_ary_clear(argv_ary);
725 return result;
726 }
727
728 void
729 rb_raise_method_missing(rb_thread_t *th, int argc, VALUE *argv,
730 VALUE obj, int call_status)
731 {
732 th->passed_block = 0;
733 raise_method_missing(th, argc, argv, obj, call_status | NOEX_MISSING);
734 }
735
744 VALUE
745 rb_apply(VALUE recv, ID mid, VALUE args)
746 {
747 int argc;
748 VALUE *argv, ret;
749
750 argc = RARRAY_LENINT(args);
751 if (argc >= 0x100) {
752 args = rb_ary_subseq(args, 0, argc);
753 RBASIC(args)->klass = 0;
754 OBJ_FREEZE(args);
755 ret = rb_call(recv, mid, argc, RARRAY_PTR(args), CALL_FCALL);
756 RB_GC_GUARD(args);
757 return ret;
758 }
759 argv = ALLOCA_N(VALUE, argc);
760 MEMCPY(argv, RARRAY_PTR(args), VALUE, argc);
761 return rb_call(recv, mid, argc, argv, CALL_FCALL);
762 }
763
773 VALUE
774 rb_funcall(VALUE recv, ID mid, int n, ...)
775 {
776 VALUE *argv;
777 va_list ar;
778
779 if (n > 0) {
780 long i;
781
782 va_init_list(ar, n);
783
784 argv = ALLOCA_N(VALUE, n);
785
786 for (i = 0; i < n; i++) {
787 argv[i] = va_arg(ar, VALUE);
788 }
789 va_end(ar);
790 }
791 else {
792 argv = 0;
793 }
794 return rb_call(recv, mid, n, argv, CALL_FCALL);
795 }
796
804 VALUE
805 rb_funcall2(VALUE recv, ID mid, int argc, const VALUE *argv)
806 {
807 return rb_call(recv, mid, argc, argv, CALL_FCALL);
808 }
809
819 VALUE
820 rb_funcall3(VALUE recv, ID mid, int argc, const VALUE *argv)
821 {
822 return rb_call(recv, mid, argc, argv, CALL_PUBLIC);
823 }
824
825 VALUE
826 rb_funcall_passing_block(VALUE recv, ID mid, int argc, const VALUE *argv)
827 {
828 PASS_PASSED_BLOCK_TH(GET_THREAD());
829
830 return rb_call(recv, mid, argc, argv, CALL_PUBLIC);
831 }
832
833 VALUE
834 rb_funcall_with_block(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE pass_procval)
835 {
836 if (!NIL_P(pass_procval)) {
837 rb_thread_t *th = GET_THREAD();
838 rb_block_t *block = 0;
839
840 rb_proc_t *pass_proc;
841 GetProcPtr(pass_procval, pass_proc);
842 block = &pass_proc->block;
843
844 th->passed_block = block;
845 }
846
847 return rb_call(recv, mid, argc, argv, CALL_PUBLIC);
848 }
849
850 static VALUE
851 send_internal(int argc, const VALUE *argv, VALUE recv, call_type scope)
852 {
853 ID id;
854 VALUE vid;
855 VALUE self;
856 rb_thread_t *th = GET_THREAD();
857
858 if (scope == CALL_PUBLIC) {
859 self = Qundef;
860 }
861 else {
862 self = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp)->self;
863 }
864
865 if (argc == 0) {
866 rb_raise(rb_eArgError, "no method name given");
867 }
868
869 vid = *argv++; argc--;
870
871 id = rb_check_id(&vid);
872 if (!id) {
873 if (rb_method_basic_definition_p(CLASS_OF(recv), idMethodMissing)) {
874 VALUE exc = make_no_method_exception(rb_eNoMethodError, NULL,
875 recv, ++argc, --argv);
876 rb_exc_raise(exc);
877 }
878 id = rb_to_id(vid);
879 }
880 PASS_PASSED_BLOCK_TH(th);
881 return rb_call0(recv, id, argc, argv, scope, self);
882 }
883
884 /*
885 * call-seq:
886 * foo.send(symbol [, args...]) -> obj
887 * foo.__send__(symbol [, args...]) -> obj
888 *
889 * Invokes the method identified by _symbol_, passing it any
890 * arguments specified. You can use <code>__send__</code> if the name
891 * +send+ clashes with an existing method in _obj_.
892 *
893 * class Klass
894 * def hello(*args)
895 * "Hello " + args.join(' ')
896 * end
897 * end
898 * k = Klass.new
899 * k.send :hello, "gentle", "readers" #=> "Hello gentle readers"
900 */
901
902 VALUE
903 rb_f_send(int argc, VALUE *argv, VALUE recv)
904 {
905 return send_internal(argc, argv, recv, CALL_FCALL);
906 }
907
908 /*
909 * call-seq:
910 * obj.public_send(symbol [, args...]) -> obj
911 *
912 * Invokes the method identified by _symbol_, passing it any
913 * arguments specified. Unlike send, public_send calls public
914 * methods only.
915 *
916 * 1.public_send(:puts, "hello") # causes NoMethodError
917 */
918
919 VALUE
920 rb_f_public_send(int argc, VALUE *argv, VALUE recv)
921 {
922 return send_internal(argc, argv, recv, CALL_PUBLIC);
923 }
924
925 /* yield */
926
927 static inline VALUE
928 rb_yield_0(int argc, const VALUE * argv)
929 {
930 return vm_yield(GET_THREAD(), argc, argv);
931 }
932
933 VALUE
934 rb_yield(VALUE val)
935 {
936 if (val == Qundef) {
937 return rb_yield_0(0, 0);
938 }
939 else {
940 return rb_yield_0(1, &val);
941 }
942 }
943
944 VALUE
945 rb_yield_values(int n, ...)
946 {
947 if (n == 0) {
948 return rb_yield_0(0, 0);
949 }
950 else {
951 int i;
952 VALUE *argv;
953 va_list args;
954 argv = ALLOCA_N(VALUE, n);
955
956 va_init_list(args, n);
957 for (i=0; i<n; i++) {
958 argv[i] = va_arg(args, VALUE);
959 }
960 va_end(args);
961
962 return rb_yield_0(n, argv);
963 }
964 }
965
966 VALUE
967 rb_yield_values2(int argc, const VALUE *argv)
968 {
969 return rb_yield_0(argc, argv);
970 }
971
972 VALUE
973 rb_yield_splat(VALUE values)
974 {
975 VALUE tmp = rb_check_array_type(values);
976 volatile VALUE v;
977 if (NIL_P(tmp)) {
978 rb_raise(rb_eArgError, "not an array");
979 }
980 v = rb_yield_0(RARRAY_LENINT(tmp), RARRAY_PTR(tmp));
981 return v;
982 }
983
984 static VALUE
985 loop_i(void)
986 {
987 for (;;) {
988 rb_yield_0(0, 0);
989 }
990 return Qnil;
991 }
992
993 static VALUE
994 rb_f_loop_size(VALUE self, VALUE args)
995 {
996 return DBL2NUM(INFINITY);
997 }
998
999 /*
1000 * call-seq:
1001 * loop { block }
1002 * loop -> an_enumerator
1003 *
1004 * Repeatedly executes the block.
1005 *
1006 * If no block is given, an enumerator is returned instead.
1007 *
1008 * loop do
1009 * print "Input: "
1010 * line = gets
1011 * break if !line or line =~ /^qQ/
1012 * # ...
1013 * end
1014 *
1015 * StopIteration raised in the block breaks the loop.
1016 */
1017
1018 static VALUE
1019 rb_f_loop(VALUE self)
1020 {
1021 RETURN_SIZED_ENUMERATOR(self, 0, 0, rb_f_loop_size);
1022 rb_rescue2(loop_i, (VALUE)0, 0, 0, rb_eStopIteration, (VALUE)0);
1023 return Qnil; /* dummy */
1024 }
1025
1026 #if VMDEBUG
1027 static const char *
1028 vm_frametype_name(const rb_control_frame_t *cfp);
1029 #endif
1030
1031 VALUE
1032 rb_iterate(VALUE (* it_proc) (VALUE), VALUE data1,
1033 VALUE (* bl_proc) (ANYARGS), VALUE data2)
1034 {
1035 int state;
1036 volatile VALUE retval = Qnil;
1037 NODE *node = NEW_IFUNC(bl_proc, data2);
1038 rb_thread_t *th = GET_THREAD();
1039 rb_control_frame_t *volatile cfp = th->cfp;
1040
1041 node->nd_aid = rb_frame_this_func();
1042 TH_PUSH_TAG(th);
1043 state = TH_EXEC_TAG();
1044 if (state == 0) {
1045 iter_retry:
1046 {
1047 rb_block_t *blockptr;
1048 if (bl_proc) {
1049 blockptr = RUBY_VM_GET_BLOCK_PTR_IN_CFP(th->cfp);
1050 blockptr->iseq = (void *)node;
1051 blockptr->proc = 0;
1052 }
1053 else {
1054 blockptr = VM_CF_BLOCK_PTR(th->cfp);
1055 }
1056 th->passed_block = blockptr;
1057 }
1058 retval = (*it_proc) (data1);
1059 }
1060 else {
1061 VALUE err = th->errinfo;
1062 if (state == TAG_BREAK) {
1063 VALUE *escape_ep = GET_THROWOBJ_CATCH_POINT(err);
1064 VALUE *cep = cfp->ep;
1065
1066 if (cep == escape_ep) {
1067 state = 0;
1068 th->state = 0;
1069 th->errinfo = Qnil;
1070 retval = GET_THROWOBJ_VAL(err);
1071
1072 /* check skipped frame */
1073 while (th->cfp != cfp) {
1074 #if VMDEBUG
1075 printf("skipped frame: %s\n", vm_frametype_name(th->cfp));
1076 #endif
1077 if (UNLIKELY(VM_FRAME_TYPE(th->cfp) == VM_FRAME_MAGIC_CFUNC)) {
1078 const rb_method_entry_t *me = th->cfp->me;
1079 EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, th->cfp->self, me->called_id, me->klass, Qnil);
1080 RUBY_DTRACE_CMETHOD_RETURN_HOOK(th, me->klass, me->called_id);
1081 }
1082
1083 th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp);
1084 }
1085 }
1086 else{
1087 /* SDR(); printf("%p, %p\n", cdfp, escape_dfp); */
1088 }
1089 }
1090 else if (state == TAG_RETRY) {
1091 VALUE *escape_ep = GET_THROWOBJ_CATCH_POINT(err);
1092 VALUE *cep = cfp->ep;
1093
1094 if (cep == escape_ep) {
1095 state = 0;
1096 th->state = 0;
1097 th->errinfo = Qnil;
1098 th->cfp = cfp;
1099 goto iter_retry;
1100 }
1101 }
1102 }
1103 TH_POP_TAG();
1104
1105 switch (state) {
1106 case 0:
1107 break;
1108 default:
1109 TH_JUMP_TAG(th, state);
1110 }
1111 return retval;
1112 }
1113
1114 struct iter_method_arg {
1115 VALUE obj;
1116 ID mid;
1117 int argc;
1118 VALUE *argv;
1119 };
1120
1121 static VALUE
1122 iterate_method(VALUE obj)
1123 {
1124 const struct iter_method_arg * arg =
1125 (struct iter_method_arg *) obj;
1126
1127 return rb_call(arg->obj, arg->mid, arg->argc, arg->argv, CALL_FCALL);
1128 }
1129
1130 VALUE
1131 rb_block_call(VALUE obj, ID mid, int argc, VALUE * argv,
1132 VALUE (*bl_proc) (ANYARGS), VALUE data2)
1133 {
1134 struct iter_method_arg arg;
1135
1136 arg.obj = obj;
1137 arg.mid = mid;
1138 arg.argc = argc;
1139 arg.argv = argv;
1140 return rb_iterate(iterate_method, (VALUE)&arg, bl_proc, data2);
1141 }
1142
1143 static VALUE
1144 iterate_check_method(VALUE obj)
1145 {
1146 const struct iter_method_arg * arg =
1147 (struct iter_method_arg *) obj;
1148
1149 return rb_check_funcall(arg->obj, arg->mid, arg->argc, arg->argv);
1150 }
1151
1152 VALUE
1153 rb_check_block_call(VALUE obj, ID mid, int argc, VALUE * argv,
1154 VALUE (*bl_proc) (ANYARGS), VALUE data2)
1155 {
1156 struct iter_method_arg arg;
1157
1158 arg.obj = obj;
1159 arg.mid = mid;
1160 arg.argc = argc;
1161 arg.argv = argv;
1162 return rb_iterate(iterate_check_method, (VALUE)&arg, bl_proc, data2);
1163 }
1164
1165 VALUE
1166 rb_each(VALUE obj)
1167 {
1168 return rb_call(obj, idEach, 0, 0, CALL_FCALL);
1169 }
1170
1171 static VALUE
1172 eval_string_with_cref(VALUE self, VALUE src, VALUE scope, NODE *cref, const char *volatile file, volatile int line)
1173 {
1174 int state;
1175 VALUE result = Qundef;
1176 VALUE envval;
1177 rb_thread_t *th = GET_THREAD();
1178 rb_env_t *env = NULL;
1179 rb_block_t block, *base_block;
1180 volatile int parse_in_eval;
1181 volatile int mild_compile_error;
1182
1183 if (file == 0) {
1184 file = rb_sourcefile();
1185 line = rb_sourceline();
1186 }
1187
1188 parse_in_eval = th->parse_in_eval;
1189 mild_compile_error = th->mild_compile_error;
1190 TH_PUSH_TAG(th);
1191 if ((state = TH_EXEC_TAG()) == 0) {
1192 rb_binding_t *bind = 0;
1193 rb_iseq_t *iseq;
1194 volatile VALUE iseqval;
1195 VALUE absolute_path = Qnil;
1196
1197 if (scope != Qnil) {
1198 if (rb_obj_is_kind_of(scope, rb_cBinding)) {
1199 GetBindingPtr(scope, bind);
1200 envval = bind->env;
1201 if (strcmp(file, "(eval)") == 0 && bind->path != Qnil) {
1202 file = RSTRING_PTR(bind->path);
1203 line = bind->first_lineno;
1204 absolute_path = rb_current_realfilepath();
1205 }
1206 }
1207 else {
1208 rb_raise(rb_eTypeError,
1209 "wrong argument type %s (expected Binding)",
1210 rb_obj_classname(scope));
1211 }
1212 GetEnvPtr(envval, env);
1213 base_block = &env->block;
1214 }
1215 else {
1216 rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);
1217
1218 if (cfp != 0) {
1219 block = *RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp);
1220 base_block = &block;
1221 base_block->self = self;
1222 base_block->iseq = cfp->iseq; /* TODO */
1223 }
1224 else {
1225 rb_raise(rb_eRuntimeError, "Can't eval on top of Fiber or Thread");
1226 }
1227 }
1228
1229 /* make eval iseq */
1230 th->parse_in_eval++;
1231 th->mild_compile_error++;
1232 iseqval = rb_iseq_compile_with_option(src, rb_str_new2(file), absolute_path, INT2FIX(line), base_block, Qnil);
1233 th->mild_compile_error--;
1234 th->parse_in_eval--;
1235
1236 vm_set_eval_stack(th, iseqval, cref, base_block);
1237
1238 if (0) { /* for debug */
1239 VALUE disasm = rb_iseq_disasm(iseqval);
1240 printf("%s\n", StringValuePtr(disasm));
1241 }
1242
1243 /* save new env */
1244 GetISeqPtr(iseqval, iseq);
1245 if (bind && iseq->local_table_size > 0) {
1246 bind->env = rb_vm_make_env_object(th, th->cfp);
1247 }
1248
1249 /* kick */
1250 CHECK_VM_STACK_OVERFLOW(th->cfp, iseq->stack_max);
1251 result = vm_exec(th);
1252 }
1253 TH_POP_TAG();
1254 th->mild_compile_error = mild_compile_error;
1255 th->parse_in_eval = parse_in_eval;
1256
1257 if (state) {
1258 if (state == TAG_RAISE) {
1259 VALUE errinfo = th->errinfo;
1260 if (strcmp(file, "(eval)") == 0) {
1261 VALUE mesg, errat, bt2;
1262 ID id_mesg;
1263
1264 CONST_ID(id_mesg, "mesg");
1265 errat = rb_get_backtrace(errinfo);
1266 mesg = rb_attr_get(errinfo, id_mesg);
1267 if (!NIL_P(errat) && RB_TYPE_P(errat, T_ARRAY) &&
1268 (bt2 = vm_backtrace_str_ary(th, 0, 0), RARRAY_LEN(bt2) > 0)) {
1269 if (!NIL_P(mesg) && RB_TYPE_P(mesg, T_STRING) && !RSTRING_LEN(mesg)) {
1270 if (OBJ_FROZEN(mesg)) {
1271 VALUE m = rb_str_cat(rb_str_dup(RARRAY_PTR(errat)[0]), ": ", 2);
1272 rb_ivar_set(errinfo, id_mesg, rb_str_append(m, mesg));
1273 }
1274 else {
1275 rb_str_update(mesg, 0, 0, rb_str_new2(": "));
1276 rb_str_update(mesg, 0, 0, RARRAY_PTR(errat)[0]);
1277 }
1278 }
1279 RARRAY_PTR(errat)[0] = RARRAY_PTR(bt2)[0];
1280 }
1281 }
1282 rb_exc_raise(errinfo);
1283 }
1284 JUMP_TAG(state);
1285 }
1286 return result;
1287 }
1288
1289 static VALUE
1290 eval_string(VALUE self, VALUE src, VALUE scope, const char *file, int line)
1291 {
1292 return eval_string_with_cref(self, src, scope, 0, file, line);
1293 }
1294
1295 /*
1296 * call-seq:
1297 * eval(string [, binding [, filename [,lineno]]]) -> obj
1298 *
1299 * Evaluates the Ruby expression(s) in <em>string</em>. If
1300 * <em>binding</em> is given, which must be a <code>Binding</code>
1301 * object, the evaluation is performed in its context. If the
1302 * optional <em>filename</em> and <em>lineno</em> parameters are
1303 * present, they will be used when reporting syntax errors.
1304 *
1305 * def get_binding(str)
1306 * return binding
1307 * end
1308 * str = "hello"
1309 * eval "str + ' Fred'" #=> "hello Fred"
1310 * eval "str + ' Fred'", get_binding("bye") #=> "bye Fred"
1311 */
1312
1313 VALUE
1314 rb_f_eval(int argc, VALUE *argv, VALUE self)
1315 {
1316 VALUE src, scope, vfile, vline;
1317 const char *file = "(eval)";
1318 int line = 1;
1319
1320 rb_scan_args(argc, argv, "13", &src, &scope, &vfile, &vline);
1321 if (rb_safe_level() >= 4) {
1322 StringValue(src);
1323 if (!NIL_P(scope) && !OBJ_TAINTED(scope)) {
1324 rb_raise(rb_eSecurityError,
1325 "Insecure: can't modify trusted binding");
1326 }
1327 }
1328 else {
1329 SafeStringValue(src);
1330 }
1331 if (argc >= 3) {
1332 StringValue(vfile);
1333 }
1334 if (argc >= 4) {
1335 line = NUM2INT(vline);
1336 }
1337
1338 if (!NIL_P(vfile))
1339 file = RSTRING_PTR(vfile);
1340 return eval_string(self, src, scope, file, line);
1341 }
1342
1344 VALUE
1345 ruby_eval_string_from_file(const char *str, const char *filename)
1346 {
1347 return eval_string(rb_vm_top_self(), rb_str_new2(str), Qnil, filename, 1);
1348 }
1349
1350 struct eval_string_from_file_arg {
1351 const char *str;
1352 const char *filename;
1353 };
1354
1355 static VALUE
1356 eval_string_from_file_helper(void *data)
1357 {
1358 const struct eval_string_from_file_arg *const arg = (struct eval_string_from_file_arg*)data;
1359 return eval_string(rb_vm_top_self(), rb_str_new2(arg->str), Qnil, arg->filename, 1);
1360 }
1361
1362 VALUE
1363 ruby_eval_string_from_file_protect(const char *str, const char *filename, int *state)
1364 {
1365 struct eval_string_from_file_arg arg;
1366 arg.str = str;
1367 arg.filename = filename;
1368 return rb_protect((VALUE (*)(VALUE))eval_string_from_file_helper, (VALUE)&arg, state);
1369 }
1370
1383 VALUE
1384 rb_eval_string(const char *str)
1385 {
1386 return ruby_eval_string_from_file(str, "eval");
1387 }
1388
1399 VALUE
1400 rb_eval_string_protect(const char *str, int *state)
1401 {
1402 return rb_protect((VALUE (*)(VALUE))rb_eval_string, (VALUE)str, state);
1403 }
1404
1416 VALUE
1417 rb_eval_string_wrap(const char *str, int *state)
1418 {
1419 int status;
1420 rb_thread_t *th = GET_THREAD();
1421 VALUE self = th->top_self;
1422 VALUE wrapper = th->top_wrapper;
1423 VALUE val;
1424
1425 th->top_wrapper = rb_module_new();
1426 th->top_self = rb_obj_clone(rb_vm_top_self());
1427 rb_extend_object(th->top_self, th->top_wrapper);
1428
1429 val = rb_eval_string_protect(str, &status);
1430
1431 th->top_self = self;
1432 th->top_wrapper = wrapper;
1433
1434 if (state) {
1435 *state = status;
1436 }
1437 else if (status) {
1438 JUMP_TAG(status);
1439 }
1440 return val;
1441 }
1442
1443 VALUE
1444 rb_eval_cmd(VALUE cmd, VALUE arg, int level)
1445 {
1446 int state;
1447 VALUE val = Qnil; /* OK */
1448 volatile int safe = rb_safe_level();
1449
1450 if (OBJ_TAINTED(cmd)) {
1451 level = 4;
1452 }
1453
1454 if (!RB_TYPE_P(cmd, T_STRING)) {
1455 PUSH_TAG();
1456 rb_set_safe_level_force(level);
1457 if ((state = EXEC_TAG()) == 0) {
1458 val = rb_funcall2(cmd, rb_intern("call"), RARRAY_LENINT(arg),
1459 RARRAY_PTR(arg));
1460 }
1461 POP_TAG();
1462
1463 rb_set_safe_level_force(safe);
1464
1465 if (state)
1466 JUMP_TAG(state);
1467 return val;
1468 }
1469
1470 PUSH_TAG();
1471 if ((state = EXEC_TAG()) == 0) {
1472 val = eval_string(rb_vm_top_self(), cmd, Qnil, 0, 0);
1473 }
1474 POP_TAG();
1475
1476 rb_set_safe_level_force(safe);
1477 if (state) JUMP_TAG(state);
1478 return val;
1479 }
1480
1481 /* block eval under the class/module context */
1482
1483 static VALUE
1484 yield_under(VALUE under, VALUE self, VALUE values)
1485 {
1486 rb_thread_t *th = GET_THREAD();
1487 rb_block_t block, *blockptr;
1488 NODE *cref;
1489
1490 if ((blockptr = VM_CF_BLOCK_PTR(th->cfp)) != 0) {
1491 block = *blockptr;
1492 block.self = self;
1493 VM_CF_LEP(th->cfp)[0] = VM_ENVVAL_BLOCK_PTR(&block);
1494 }
1495 cref = vm_cref_push(th, under, NOEX_PUBLIC, blockptr);
1496 cref->flags |= NODE_FL_CREF_PUSHED_BY_EVAL;
1497
1498 if (values == Qundef) {
1499 return vm_yield_with_cref(th, 1, &self, cref);
1500 }
1501 else {
1502 return vm_yield_with_cref(th, RARRAY_LENINT(values), RARRAY_PTR(values), cref);
1503 }
1504 }
1505
1506 VALUE
1507 rb_yield_refine_block(VALUE refinement, VALUE refinements)
1508 {
1509 rb_thread_t *th = GET_THREAD();
1510 rb_block_t block, *blockptr;
1511 NODE *cref;
1512
1513 if ((blockptr = VM_CF_BLOCK_PTR(th->cfp)) != 0) {
1514 block = *blockptr;
1515 block.self = refinement;
1516 VM_CF_LEP(th->cfp)[0] = VM_ENVVAL_BLOCK_PTR(&block);
1517 }
1518 cref = vm_cref_push(th, refinement, NOEX_PUBLIC, blockptr);
1519 cref->flags |= NODE_FL_CREF_PUSHED_BY_EVAL;
1520 cref->nd_refinements = refinements;
1521
1522 return vm_yield_with_cref(th, 0, NULL, cref);
1523 }
1524
1525 /* string eval under the class/module context */
1526 static VALUE
1527 eval_under(VALUE under, VALUE self, VALUE src, const char *file, int line)
1528 {
1529 NODE *cref = vm_cref_push(GET_THREAD(), under, NOEX_PUBLIC, NULL);
1530
1531 if (SPECIAL_CONST_P(self) && !NIL_P(under)) {
1532 cref->flags |= NODE_FL_CREF_PUSHED_BY_EVAL;
1533 }
1534 if (rb_safe_level() >= 4) {
1535 StringValue(src);
1536 }
1537 else {
1538 SafeStringValue(src);
1539 }
1540
1541 return eval_string_with_cref(self, src, Qnil, cref, file, line);
1542 }
1543
1544 static VALUE
1545 specific_eval(int argc, VALUE *argv, VALUE klass, VALUE self)
1546 {
1547 if (rb_block_given_p()) {
1548 rb_check_arity(argc, 0, 0);
1549 return yield_under(klass, self, Qundef);
1550 }
1551 else {
1552 const char *file = "(eval)";
1553 int line = 1;
1554
1555 rb_check_arity(argc, 1, 3);
1556 if (rb_safe_level() >= 4) {
1557 StringValue(argv[0]);
1558 }
1559 else {
1560 SafeStringValue(argv[0]);
1561 }
1562 if (argc > 2)
1563 line = NUM2INT(argv[2]);
1564 if (argc > 1) {
1565 file = StringValuePtr(argv[1]);
1566 }
1567 return eval_under(klass, self, argv[0], file, line);
1568 }
1569 }
1570
1571 /*
1572 * call-seq:
1573 * obj.instance_eval(string [, filename [, lineno]] ) -> obj
1574 * obj.instance_eval {| | block } -> obj
1575 *
1576 * Evaluates a string containing Ruby source code, or the given block,
1577 * within the context of the receiver (_obj_). In order to set the
1578 * context, the variable +self+ is set to _obj_ while
1579 * the code is executing, giving the code access to _obj_'s
1580 * instance variables. In the version of <code>instance_eval</code>
1581 * that takes a +String+, the optional second and third
1582 * parameters supply a filename and starting line number that are used
1583 * when reporting compilation errors.
1584 *
1585 * class KlassWithSecret
1586 * def initialize
1587 * @secret = 99
1588 * end
1589 * end
1590 * k = KlassWithSecret.new
1591 * k.instance_eval { @secret } #=> 99
1592 */
1593
1594 VALUE
1595 rb_obj_instance_eval(int argc, VALUE *argv, VALUE self)
1596 {
1597 VALUE klass;
1598
1599 if (SPECIAL_CONST_P(self)) {
1600 klass = rb_special_singleton_class(self);
1601 }
1602 else {
1603 klass = rb_singleton_class(self);
1604 }
1605 return specific_eval(argc, argv, klass, self);
1606 }
1607
1608 /*
1609 * call-seq:
1610 * obj.instance_exec(arg...) {|var...| block } -> obj
1611 *
1612 * Executes the given block within the context of the receiver
1613 * (_obj_). In order to set the context, the variable +self+ is set
1614 * to _obj_ while the code is executing, giving the code access to
1615 * _obj_'s instance variables. Arguments are passed as block parameters.
1616 *
1617 * class KlassWithSecret
1618 * def initialize
1619 * @secret = 99
1620 * end
1621 * end
1622 * k = KlassWithSecret.new
1623 * k.instance_exec(5) {|x| @secret+x } #=> 104
1624 */
1625
1626 VALUE
1627 rb_obj_instance_exec(int argc, VALUE *argv, VALUE self)
1628 {
1629 VALUE klass;
1630
1631 if (SPECIAL_CONST_P(self)) {
1632 klass = rb_special_singleton_class(self);
1633 }
1634 else {
1635 klass = rb_singleton_class(self);
1636 }
1637 return yield_under(klass, self, rb_ary_new4(argc, argv));
1638 }
1639
1640 /*
1641 * call-seq:
1642 * mod.class_eval(string [, filename [, lineno]]) -> obj
1643 * mod.module_eval {|| block } -> obj
1644 *
1645 * Evaluates the string or block in the context of _mod_, except that when
1646 * a block is given, constant/class variable lookup is not affected. This
1647 * can be used to add methods to a class. <code>module_eval</code> returns
1648 * the result of evaluating its argument. The optional _filename_ and
1649 * _lineno_ parameters set the text for error messages.
1650 *
1651 * class Thing
1652 * end
1653 * a = %q{def hello() "Hello there!" end}
1654 * Thing.module_eval(a)
1655 * puts Thing.new.hello()
1656 * Thing.module_eval("invalid code", "dummy", 123)
1657 *
1658 * <em>produces:</em>
1659 *
1660 * Hello there!
1661 * dummy:123:in `module_eval': undefined local variable
1662 * or method `code' for Thing:Class
1663 */
1664
1665 VALUE
1666 rb_mod_module_eval(int argc, VALUE *argv, VALUE mod)
1667 {
1668 return specific_eval(argc, argv, mod, mod);
1669 }
1670
1671 /*
1672 * call-seq:
1673 * mod.module_exec(arg...) {|var...| block } -> obj
1674 * mod.class_exec(arg...) {|var...| block } -> obj
1675 *
1676 * Evaluates the given block in the context of the class/module.
1677 * The method defined in the block will belong to the receiver.
1678 *
1679 * class Thing
1680 * end
1681 * Thing.class_exec{
1682 * def hello() "Hello there!" end
1683 * }
1684 * puts Thing.new.hello()
1685 *
1686 * <em>produces:</em>
1687 *
1688 * Hello there!
1689 */
1690
1691 VALUE
1692 rb_mod_module_exec(int argc, VALUE *argv, VALUE mod)
1693 {
1694 return yield_under(mod, mod, rb_ary_new4(argc, argv));
1695 }
1696
1697 /*
1698 * call-seq:
1699 * throw(tag [, obj])
1700 *
1701 * Transfers control to the end of the active +catch+ block
1702 * waiting for _tag_. Raises +ArgumentError+ if there
1703 * is no +catch+ block for the _tag_. The optional second
1704 * parameter supplies a return value for the +catch+ block,
1705 * which otherwise defaults to +nil+. For examples, see
1706 * <code>Kernel::catch</code>.
1707 */
1708
1709 static VALUE
1710 rb_f_throw(int argc, VALUE *argv)
1711 {
1712 VALUE tag, value;
1713
1714 rb_scan_args(argc, argv, "11", &tag, &value);
1715 rb_throw_obj(tag, value);
1716 UNREACHABLE;
1717 }
1718
1719 void
1720 rb_throw_obj(VALUE tag, VALUE value)
1721 {
1722 rb_thread_t *th = GET_THREAD();
1723 struct rb_vm_tag *tt = th->tag;
1724
1725 while (tt) {
1726 if (tt->tag == tag) {
1727 tt->retval = value;
1728 break;
1729 }
1730 tt = tt->prev;
1731 }
1732 if (!tt) {
1733 VALUE desc = rb_inspect(tag);
1734 RB_GC_GUARD(desc);
1735 rb_raise(rb_eArgError, "uncaught throw %s", RSTRING_PTR(desc));
1736 }
1737 th->errinfo = NEW_THROW_OBJECT(tag, 0, TAG_THROW);
1738
1739 JUMP_TAG(TAG_THROW);
1740 }
1741
1742 void
1743 rb_throw(const char *tag, VALUE val)
1744 {
1745 rb_throw_obj(ID2SYM(rb_intern(tag)), val);
1746 }
1747
1748 static VALUE
1749 catch_i(VALUE tag, VALUE data)
1750 {
1751 return rb_yield_0(1, &tag);
1752 }
1753
1754 /*
1755 * call-seq:
1756 * catch([arg]) {|tag| block } -> obj
1757 *
1758 * +catch+ executes its block. If a +throw+ is
1759 * executed, Ruby searches up its stack for a +catch+ block
1760 * with a tag corresponding to the +throw+'s
1761 * _tag_. If found, that block is terminated, and
1762 * +catch+ returns the value given to +throw+. If
1763 * +throw+ is not called, the block terminates normally, and
1764 * the value of +catch+ is the value of the last expression
1765 * evaluated. +catch+ expressions may be nested, and the
1766 * +throw+ call need not be in lexical scope.
1767 *
1768 * def routine(n)
1769 * puts n
1770 * throw :done if n <= 0
1771 * routine(n-1)
1772 * end
1773 *
1774 *
1775 * catch(:done) { routine(3) }
1776 *
1777 * <em>produces:</em>
1778 *
1779 * 3
1780 * 2
1781 * 1
1782 * 0
1783 *
1784 * when _arg_ is given, +catch+ yields it as is, or when no
1785 * _arg_ is given, +catch+ assigns a new unique object to
1786 * +throw+. this is useful for nested +catch+. _arg_ can
1787 * be an arbitrary object, not only Symbol.
1788 *
1789 */
1790
1791 static VALUE
1792 rb_f_catch(int argc, VALUE *argv)
1793 {
1794 VALUE tag;
1795
1796 if (argc == 0) {
1797 tag = rb_obj_alloc(rb_cObject);
1798 }
1799 else {
1800 rb_scan_args(argc, argv, "01", &tag);
1801 }
1802 return rb_catch_obj(tag, catch_i, 0);
1803 }
1804
1805 VALUE
1806 rb_catch(const char *tag, VALUE (*func)(), VALUE data)
1807 {
1808 VALUE vtag = tag ? ID2SYM(rb_intern(tag)) : rb_obj_alloc(rb_cObject);
1809 return rb_catch_obj(vtag, func, data);
1810 }
1811
1812 VALUE
1813 rb_catch_obj(VALUE tag, VALUE (*func)(), VALUE data)
1814 {
1815 int state;
1816 volatile VALUE val = Qnil; /* OK */
1817 rb_thread_t *th = GET_THREAD();
1818 rb_control_frame_t *saved_cfp = th->cfp;
1819
1820 TH_PUSH_TAG(th);
1821
1822 th->tag->tag = tag;
1823
1824 if ((state = TH_EXEC_TAG()) == 0) {
1825 /* call with argc=1, argv = [tag], block = Qnil to insure compatibility */
1826 val = (*func)(tag, data, 1, &tag, Qnil);
1827 }
1828 else if (state == TAG_THROW && RNODE(th->errinfo)->u1.value == tag) {
1829 th->cfp = saved_cfp;
1830 val = th->tag->retval;
1831 th->errinfo = Qnil;
1832 state = 0;
1833 }
1834 TH_POP_TAG();
1835 if (state)
1836 JUMP_TAG(state);
1837
1838 return val;
1839 }
1840
1841 /*
1842 * call-seq:
1843 * local_variables -> array
1844 *
1845 * Returns the names of the current local variables.
1846 *
1847 * fred = 1
1848 * for i in 1..10
1849 * # ...
1850 * end
1851 * local_variables #=> [:fred, :i]
1852 */
1853
1854 static VALUE
1855 rb_f_local_variables(void)
1856 {
1857 VALUE ary = rb_ary_new();
1858 rb_thread_t *th = GET_THREAD();
1859 rb_control_frame_t *cfp =
1860 vm_get_ruby_level_caller_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp));
1861 int i;
1862
1863 while (cfp) {
1864 if (cfp->iseq) {
1865 for (i = 0; i < cfp->iseq->local_table_size; i++) {
1866 ID lid = cfp->iseq->local_table[i];
1867 if (lid) {
1868 const char *vname = rb_id2name(lid);
1869 /* should skip temporary variable */
1870 if (vname) {
1871 rb_ary_push(ary, ID2SYM(lid));
1872 }
1873 }
1874 }
1875 }
1876 if (!VM_EP_LEP_P(cfp->ep)) {
1877 /* block */
1878 VALUE *ep = VM_CF_PREV_EP(cfp);
1879
1880 if (vm_collect_local_variables_in_heap(th, ep, ary)) {
1881 break;
1882 }
1883 else {
1884 while (cfp->ep != ep) {
1885 cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
1886 }
1887 }
1888 }
1889 else {
1890 break;
1891 }
1892 }
1893 return ary;
1894 }
1895
1896 /*
1897 * call-seq:
1898 * block_given? -> true or false
1899 * iterator? -> true or false
1900 *
1901 * Returns <code>true</code> if <code>yield</code> would execute a
1902 * block in the current context. The <code>iterator?</code> form
1903 * is mildly deprecated.
1904 *
1905 * def try
1906 * if block_given?
1907 * yield
1908 * else
1909 * "no block"
1910 * end
1911 * end
1912 * try #=> "no block"
1913 * try { "hello" } #=> "hello"
1914 * try do "hello" end #=> "hello"
1915 */
1916
1917
1918 VALUE
1919 rb_f_block_given_p(void)
1920 {
1921 rb_thread_t *th = GET_THREAD();
1922 rb_control_frame_t *cfp = th->cfp;
1923 cfp = vm_get_ruby_level_caller_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
1924
1925 if (cfp != 0 && VM_CF_BLOCK_PTR(cfp)) {
1926 return Qtrue;
1927 }
1928 else {
1929 return Qfalse;
1930 }
1931 }
1932
1933 VALUE
1934 rb_current_realfilepath(void)
1935 {
1936 rb_thread_t *th = GET_THREAD();
1937 rb_control_frame_t *cfp = th->cfp;
1938 cfp = vm_get_ruby_level_caller_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
1939 if (cfp != 0) return cfp->iseq->location.absolute_path;
1940 return Qnil;
1941 }
1942
1943 void
1944 Init_vm_eval(void)
1945 {
1946 rb_define_global_function("eval", rb_f_eval, -1);
1947 rb_define_global_function("local_variables", rb_f_local_variables, 0);
1948 rb_define_global_function("iterator?", rb_f_block_given_p, 0);
1949 rb_define_global_function("block_given?", rb_f_block_given_p, 0);
1950
1951 rb_define_global_function("catch", rb_f_catch, -1);
1952 rb_define_global_function("throw", rb_f_throw, -1);
1953
1954 rb_define_global_function("loop", rb_f_loop, 0);
1955
1956 rb_define_method(rb_cBasicObject, "instance_eval", rb_obj_instance_eval, -1);
1957 rb_define_method(rb_cBasicObject, "instance_exec", rb_obj_instance_exec, -1);
1958 rb_define_private_method(rb_cBasicObject, "method_missing", rb_method_missing, -1);
1959
1960 #if 1
1961 rb_add_method(rb_cBasicObject, rb_intern("__send__"),
1962 VM_METHOD_TYPE_OPTIMIZED, (void *)OPTIMIZED_METHOD_TYPE_SEND, 0);
1963 rb_add_method(rb_mKernel, rb_intern("send"),
1964 VM_METHOD_TYPE_OPTIMIZED, (void *)OPTIMIZED_METHOD_TYPE_SEND, 0);
1965 #else
1966 rb_define_method(rb_cBasicObject, "__send__", rb_f_send, -1);
1967 rb_define_method(rb_mKernel, "send", rb_f_send, -1);
1968 #endif
1969 rb_define_method(rb_mKernel, "public_send", rb_f_public_send, -1);
1970
1971 rb_define_method(rb_cModule, "module_exec", rb_mod_module_exec, -1);
1972 rb_define_method(rb_cModule, "class_exec", rb_mod_module_exec, -1);
1973 rb_define_method(rb_cModule, "module_eval", rb_mod_module_eval, -1);
1974 rb_define_method(rb_cModule, "class_eval", rb_mod_module_eval, -1);
1975 }
1976