Ejemplo n.º 1
0
  /* Run when an AccessVariable is executed. Uses the details in exec
   * to access instance variables of args.recv() */
  Object* AccessVariable::access_execute(STATE, CallFrame* call_frame, Executable* exec, Module* mod,
                                         Arguments& args) {
    AccessVariable* access = as<AccessVariable>(exec);
    Object* const self = args.recv();

    /* The writer case. */
    if(access->write()->true_p()) {
      if(CBOOL(self->frozen_p(state))) {
        Exception::frozen_error(state, call_frame);
        return 0;
      }

      if(args.total() != 1) {
        Exception::argument_error(state, 1, args.total());
        return NULL;
      }

      if(kind_of<Class>(mod) && self->reference_p()) {
        // Promote this to use a direct accessor
        if(TypeInfo* ti = state->memory()->find_type_info(self)) {
          TypeInfo::Slots::iterator it = ti->slots.find(access->name()->index());
          if(it != ti->slots.end()) {
            // Found one!
            access->set_executor(ti->slot_accessors[it->second]);
            ti->set_field(state, self, it->second, args.get_argument(0));
            return args.get_argument(0);
          }
        }

        /* Fall through, handle it as a normal ivar. */
        access->set_executor(access_write_regular_ivar);
      }

      self->set_ivar(state, access->name(), args.get_argument(0));
      return args.get_argument(0);
    }

    /* The read case. */
    if(args.total() != 0) {
      Exception::argument_error(state, 0, args.total());
      return NULL;
    }

    if(kind_of<Class>(mod) && self->reference_p()) {
      // Promote this to use a direct accessor
      if(TypeInfo* ti = state->memory()->find_type_info(self)) {
        TypeInfo::Slots::iterator it = ti->slots.find(access->name()->index());
        if(it != ti->slots.end()) {
          // Found one!
          access->set_executor(ti->slot_accessors[it->second]);
          return ti->get_field(state, self, it->second);
        }
      }
      // Ok, its a table ivar, setup fast access for next time.
      access->set_executor(access_read_regular_ivar);
    }

    return self->get_ivar(state, access->name());
  }
Ejemplo n.º 2
0
 AccessVariable* AccessVariable::allocate(STATE) {
   AccessVariable* av = state->new_object<AccessVariable>(G(access_variable));
   av->inliners_ = 0;
   av->prim_index_ = -1;
   av->set_executor(AccessVariable::access_execute);
   return av;
 }
Ejemplo n.º 3
0
 AccessVariable* AccessVariable::allocate(STATE) {
   AccessVariable* av = state->new_object<AccessVariable>(G(access_variable));
   av->set_executor(AccessVariable::access_execute);
   return av;
 }