Object* CallSite::empty_cache_super(STATE, CallSite* call_site, CallFrame* call_frame, Arguments& args) { Symbol* original_name = call_frame->original_name(); if(call_site->name_ != original_name) { call_site->name_ = original_name; args.set_name(call_site->name_); } Object* const recv = args.recv(); Class* const recv_class = recv->direct_class(state); Module* const start = call_frame->module()->superclass(); LookupData lookup(call_frame->self(), start, G(sym_private)); Dispatch dis(call_site->name()); if(start->nil_p() || !dis.resolve(state, call_site->name(), lookup)) { LookupData missing_lookup(call_frame->self(), recv->lookup_begin(state), G(sym_private)); Dispatch missing_dis(G(sym_method_missing)); if(!missing_dis.resolve(state, G(sym_method_missing), missing_lookup)) { std::ostringstream msg; msg << "no method_missing for "; msg << recv_class->to_string(state); msg << "#" << call_site->name()->to_string(state); Exception::internal_error(state, call_frame, msg.str().c_str()); return 0; } args.unshift(state, call_site->name()); dis.method = missing_dis.method; dis.module = missing_dis.module; dis.method_missing = eSuper; state->vm()->set_method_missing_reason(dis.method_missing); state->vm()->global_cache()->add_seen(state, call_site->name()); } state->vm()->metrics().machine.methods_invoked++; call_site->update(state, recv_class, dis); Executable* meth = dis.method; Module* mod = dis.module; if(meth->custom_call_site_p()) { CallSiteInformation info(call_site->executable(), call_site->ip()); state->set_call_site_information(&info); Object* res = meth->execute(state, call_frame, meth, mod, args); state->set_call_site_information(NULL); return res; } else { return meth->execute(state, call_frame, meth, mod, args); } }
Object* CallSite::empty_cache_super(STATE, CallSite* call_site, CallFrame* call_frame, Arguments& args) { Symbol* original_name = call_frame->original_name(); if(call_site->name_ != original_name) { call_site->name_ = original_name; args.set_name(call_site->name_); } Object* const recv = args.recv(); Class* const recv_class = recv->lookup_begin(state); Module* const start = call_frame->module()->superclass(); LookupData lookup(call_frame->self(), start, G(sym_private)); Dispatch dis(call_site->name()); if(start->nil_p() || !dis.resolve(state, call_site->name(), lookup)) { LookupData missing_lookup(call_frame->self(), recv_class, G(sym_private)); Dispatch missing_dis(G(sym_method_missing)); missing_dis.resolve(state, G(sym_method_missing), missing_lookup); if(missing_dis.method_missing != eNone) { Exception::internal_error(state, call_frame, "no method_missing"); return 0; } args.unshift(state, call_site->name()); dis.method = missing_dis.method; dis.module = missing_dis.module; dis.method_missing = eSuper; state->vm()->set_method_missing_reason(dis.method_missing); } call_site->update(state, recv_class, dis); Executable* meth = dis.method; Module* mod = dis.module; if(meth->custom_call_site_p()) { CallSiteInformation info(call_site->executable(), call_site->ip()); state->set_call_site_information(&info); Object* res = meth->execute(state, call_frame, meth, mod, args); state->set_call_site_information(NULL); return res; } else { return meth->execute(state, call_frame, meth, mod, args); } }
void CallSite::lookup_method_missing(STATE, CallFrame* call_frame, Arguments& args, Dispatch& dis, Object* self, Module* begin) { LookupData missing_lookup(self, begin, G(sym_private)); Dispatch missing_dis(G(sym_method_missing)); missing_dis.resolve(state, G(sym_method_missing), missing_lookup); if(missing_dis.method_missing != eNone) { std::ostringstream msg; msg << "no method_missing for "; msg << begin->to_string(state); msg << "#" << dis.name->to_string(state); Exception::internal_error(state, call_frame, msg.str().c_str()); } args.unshift(state, dis.name); dis.method = missing_dis.method; dis.module = missing_dis.module; state->vm()->set_method_missing_reason(dis.method_missing); state->vm()->global_cache()->add_seen(state, dis.name); }