/* -*- c -*- */ /* do not use C++ style comment */ /* */ MACRO macro_eval_invoke_method(recv, klass, id, num, mn, blockptr) { /* method missing */ if (mn == 0) { /* temporarily */ if (id == idMethodMissing) { rb_bug("method missing"); } else { int stat = 0; if (flag & VM_CALL_VCALL_BIT) { stat |= NOEX_VCALL; } if (flag & VM_CALL_SUPER_BIT) { stat |= NOEX_SUPER; } val = eval_method_missing(th, id, recv, num, blockptr, stat); } } else if (!(flag & VM_CALL_FCALL_BIT) && (mn->nd_noex & NOEX_MASK) & NOEX_PRIVATE) { int stat = NOEX_PRIVATE; if (flag & VM_CALL_VCALL_BIT) { stat |= NOEX_VCALL; } val = eval_method_missing(th, id, recv, num, blockptr, stat); } else if ((mn->nd_noex & NOEX_MASK) & NOEX_PROTECTED) { VALUE defined_class = mn->nd_clss; if (TYPE(defined_class) == T_ICLASS) { defined_class = RBASIC(defined_class)->klass; } if (!rb_obj_is_kind_of(GET_SELF(), rb_class_real(defined_class))) { val = eval_method_missing(th, id, recv, num, blockptr, NOEX_PROTECTED); } else { goto INSN_LABEL(normal_method_dispatch); } } else { NODE *node; INSN_LABEL(normal_method_dispatch): node = mn->nd_body; switch (nd_type(node)) { case RUBY_VM_METHOD_NODE:{ vm_setup_method(th, GET_CFP(), num, blockptr, flag, (VALUE)node->nd_body, recv, klass); RESTORE_REGS(); NEXT_INSN(); } case NODE_CFUNC:{ val = vm_call_cfunc(th, GET_CFP(), num, id, recv, klass, node, blockptr); break; } case NODE_ATTRSET:{ val = rb_ivar_set(recv, node->nd_vid, TOPN(0)); POPN(2); break; } case NODE_IVAR:{ val = rb_ivar_get(recv, node->nd_vid); POP(); break; } case NODE_BMETHOD:{ VALUE *argv = GET_SP() - num; val = th_invoke_bmethod(th, id, node->nd_cval, recv, klass, num, argv); INC_SP(-num-1); break; } case NODE_ZSUPER:{ klass = RCLASS(mn->nd_clss)->super; mn = rb_method_node(klass, id); if (mn != 0) { goto INSN_LABEL(normal_method_dispatch); } else { goto LABEL_IS_SC(start_method_dispatch); } } default:{ printf("node: %s\n", ruby_node_name(nd_type(node))); rb_bug("eval_invoke_method: unreachable"); /* unreachable */ break; } } } }