Пример #1
0
bool Executor::ExecInsn(Method *method, MethodFrame *frame, Insn *insn) {
  bool need_suspend = false;
  switch (insn->op_) {
  case OP_NUM:
    {
      int dst = insn->dst_regs_[0]->id_;
      const numeric::Width *width =
	method->method_regs_[dst]->type_.width_;
      frame->reg_values_[dst].num_ = insn->src_regs_[0]->initial_num_;
      frame->reg_values_[dst].num_.type = width;
    }
    break;
  case OP_STR:
    ExecStr(frame, insn);
    break;
  case OP_ADD:
  case OP_SUB:
  case OP_MUL:
  case OP_ASSIGN:
  case OP_GT:
  case OP_LT:
  case OP_GTE:
  case OP_LTE:
  case OP_EQ:
  case OP_NE:
  case OP_LAND:
  case OP_LOR:
  case OP_AND:
  case OP_OR:
  case OP_XOR:
  case OP_CONCAT:
  case OP_LSHIFT:
  case OP_RSHIFT:
    ExecBinop(method, frame, insn);
    break;
  case OP_CHANNEL_READ:
    need_suspend = ExecChannelRead(frame, insn);
    if (need_suspend) {
      return true;
    }
    break;
  case OP_MEMORY_READ:
    ExecMemoryRead(frame, insn);
    break;
  case OP_FUNCALL:
    need_suspend = ExecFuncall(frame, insn);
    break;
  case OP_FUNCALL_DONE:
    ExecFuncallDone(method, frame, insn);
    break;
  case OP_LOAD_OBJ:
    ExecLoadObj(frame, insn);
    break;
  case OP_IF:
    ExecIf(frame, insn);
    // do not increment pc.
    return false;
  case OP_GOTO:
    ExecGoto(frame, insn);
    // do not increment pc.
    return false;
  case OP_NOP:
    break;
  case OP_CHANNEL_WRITE:
    ExecChannelWrite(method, frame, insn);
    break;
  case OP_MEMORY_WRITE:
    ExecMemoryWrite(method, frame, insn);
    break;
  case OP_PRE_INC:
  case OP_PRE_DEC:
    ExecIncDec(frame, insn);
    break;
  case OP_ARRAY_READ:
    ExecArrayRead(frame, insn);
    break;
  case OP_ARRAY_WRITE:
    ExecArrayWrite(frame, insn);
    break;
  case OP_LOGIC_INV:
    ExecLogicInv(frame, insn);
    break;
  case OP_BIT_INV:
  case OP_PLUS:
  case OP_MINUS:
    ExecNumUniop(frame, insn);
    break;
  case OP_MEMBER_READ:
  case OP_MEMBER_WRITE:
    ExecMemberAccess(frame, insn);
    break;
  case OP_BIT_RANGE:
    ExecBitRange(frame, insn);
    break;
  default:
    CHECK(false) << "unknown insn:" << vm::OpCodeName(insn->op_);
  }
  ++frame->pc_;
  return need_suspend;
}
Пример #2
0
static int
chat_UpdateSet(struct fdescriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n)
{
  struct chat *c = descriptor2chat(d);
  int special, gotabort, gottimeout, needcr;
  int TimedOut = c->TimedOut;
  static char arg_term;		/* An empty string */

  if (c->pause.state == TIMER_RUNNING)
    return 0;

  if (TimedOut) {
    log_Printf(LogCHAT, "Expect timeout\n");
    if (c->nargptr == NULL)
      c->state = CHAT_FAILED;
    else {
      /* c->state = CHAT_EXPECT; */
      c->argptr = &arg_term;
    }
    c->TimedOut = 0;
  }

  if (c->state != CHAT_EXPECT && c->state != CHAT_SEND)
    return 0;

  gottimeout = gotabort = 0;

  if (c->arg < c->argc && (c->arg < 0 || *c->argptr == '\0')) {
    /* Go get the next string */
    if (c->arg < 0 || c->state == CHAT_SEND)
      c->state = CHAT_EXPECT;
    else
      c->state = CHAT_SEND;

    special = 1;
    while (special && (c->nargptr || c->arg < c->argc - 1)) {
      if (c->arg < 0 || (!TimedOut && c->state == CHAT_SEND))
        c->nargptr = NULL;

      if (c->nargptr != NULL) {
        /* We're doing expect-send-expect.... */
        c->argptr = c->nargptr;
        /* Put the '-' back in case we ever want to rerun our script */
        c->nargptr[-1] = '-';
        c->nargptr = chat_NextChar(c->nargptr, '-');
        if (c->nargptr != NULL)
          *c->nargptr++ = '\0';
      } else {
        int minus;

        if ((c->argptr = c->argv[++c->arg]) == NULL) {
          /* End of script - all ok */
          c->state = CHAT_DONE;
          return 0;
        }

        if (c->state == CHAT_EXPECT) {
          /* Look for expect-send-expect sequence */
          c->nargptr = c->argptr;
          minus = 0;
          while ((c->nargptr = chat_NextChar(c->nargptr, '-'))) {
            c->nargptr++;
            minus++;
          }

          if (minus % 2)
            log_Printf(LogWARN, "chat_UpdateSet: \"%s\": Uneven number of"
                      " '-' chars, all ignored\n", c->argptr);
          else if (minus) {
            c->nargptr = chat_NextChar(c->argptr, '-');
            *c->nargptr++ = '\0';
          }
        }
      }

      /*
       * c->argptr now temporarily points into c->script (via c->argv)
       * If it's an expect-send-expect sequence, we've just got the correct
       * portion of that sequence.
       */

      needcr = c->state == CHAT_SEND &&
               (*c->argptr != '!' || c->argptr[1] == '!');

      /* We leave room for a potential HDLC header in the target string */
      ExpandString(c, c->argptr, c->exp + 2, sizeof c->exp - 2, needcr);

      /*
       * Now read our string.  If it's not a special string, we unset
       * ``special'' to break out of the loop.
       */
      if (gotabort) {
        if (c->abort.num < MAXABORTS) {
          int len, i;

          len = strlen(c->exp+2);
          for (i = 0; i < c->abort.num; i++)
            if (len > c->abort.string[i].len) {
              int last;

              for (last = c->abort.num; last > i; last--) {
                c->abort.string[last].data = c->abort.string[last-1].data;
                c->abort.string[last].len = c->abort.string[last-1].len;
              }
              break;
            }
          c->abort.string[i].len = len;
          if ((c->abort.string[i].data = (char *)malloc(len+1)) != NULL) {
            memcpy(c->abort.string[i].data, c->exp+2, len+1);
            c->abort.num++;
	  }
        } else
          log_Printf(LogERROR, "chat_UpdateSet: too many abort strings\n");
        gotabort = 0;
      } else if (gottimeout) {
        c->TimeoutSec = atoi(c->exp + 2);
        if (c->TimeoutSec <= 0)
          c->TimeoutSec = 30;
        gottimeout = 0;
      } else if (c->nargptr == NULL && !strcmp(c->exp+2, "ABORT"))
        gotabort = 1;
      else if (c->nargptr == NULL && !strcmp(c->exp+2, "TIMEOUT"))
        gottimeout = 1;
      else {
        if (c->exp[2] == '!' && c->exp[3] != '!')
          ExecStr(c->physical, c->exp + 3, c->exp + 3, sizeof c->exp - 3);

        if (c->exp[2] == '\0') {
          /* Empty string, reparse (this may be better as a `goto start') */
          c->argptr = &arg_term;
          return chat_UpdateSet(d, r, w, e, n);
        }

        special = 0;
      }
    }

    if (special) {
      if (gottimeout)
        log_Printf(LogWARN, "chat_UpdateSet: TIMEOUT: Argument expected\n");
      else if (gotabort)
        log_Printf(LogWARN, "chat_UpdateSet: ABORT: Argument expected\n");

      /* End of script - all ok */
      c->state = CHAT_DONE;
      return 0;
    }

    /* set c->argptr to point in the right place */
    c->argptr = c->exp + (c->exp[2] == '!' ? 3 : 2);
    c->arglen = strlen(c->argptr);

    if (c->state == CHAT_EXPECT) {
      /* We must check to see if the string's already been found ! */
      char *begin, *end;

      end = c->bufend - c->arglen + 1;
      if (end < c->bufstart)
        end = c->bufstart;
      for (begin = c->bufstart; begin < end; begin++)
        if (!strncmp(begin, c->argptr, c->arglen)) {
          c->bufstart = begin + c->arglen;
          c->argptr += c->arglen;
          c->arglen = 0;
          /* Continue - we've already read our expect string */
          return chat_UpdateSet(d, r, w, e, n);
        }

      log_Printf(LogCHAT, "Expect(%d): %s\n", c->TimeoutSec, c->argptr);
      chat_SetTimeout(c);
    }
  }

  /*
   * We now have c->argptr pointing at what we want to expect/send and
   * c->state saying what we want to do... we now know what to put in
   * the fd_set :-)
   */

  if (c->state == CHAT_EXPECT)
    return physical_doUpdateSet(&c->physical->desc, r, NULL, e, n, 1);
  else
    return physical_doUpdateSet(&c->physical->desc, NULL, w, e, n, 1);
}