Esempio n. 1
0
  Object* CallSite::empty_cache(STATE, CallSite* call_site, CallFrame* call_frame,
                                   Arguments& args)
  {
    Object* const recv = args.recv();
    Class*  const recv_class  = recv->direct_class(state);

    LookupData lookup(call_frame->self(), recv->lookup_begin(state), G(sym_public));
    Dispatch dis(call_site->name());

    if(!dis.resolve(state, call_site->name(), lookup)) {
      if(!lookup_method_missing(state, call_frame, args,
          dis, call_frame->self(), recv->lookup_begin(state))) {
        return NULL;
      }
    }

    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);
    }
  }
Esempio n. 2
0
  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);
    }
  }
Esempio n. 3
0
  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);
    }
  }