Ruby 2.1.5p273(2014-11-13revision48405)

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