예제 #1
0
파일: hhbc.cpp 프로젝트: swtaarrs/hhvm
IterTable iterTableFromStream(PC& pc) {
  IterTable ret;
  auto const length = decode_iva(pc);
  for (int32_t i = 0; i < length; ++i) {
    auto const kind = static_cast<IterKind>(decode_iva(pc));
    auto const id = decode_iva(pc);
    auto const local = (kind == KindOfLIter)
      ? static_cast<int32_t>(decode_iva(pc))
      : kInvalidId;
    ret.push_back(IterTableEnt{kind, static_cast<int32_t>(id), local});
  }
  return ret;
}
예제 #2
0
파일: hhbc.cpp 프로젝트: BruceZu/hhvm
ArgUnion getImm(PC const origPC, int idx, const Unit* unit) {
  auto pc = origPC;
  auto const UNUSED op = decode_op(pc);
  assert(idx >= 0 && idx < numImmediates(op));
  ArgUnion retval;
  retval.u_NA = 0;
  int cursor = 0;
  for (cursor = 0; cursor < idx; cursor++) {
    // Advance over this immediate.
    pc += immSize(origPC, cursor);
  }
  always_assert(cursor == idx);
  auto const type = immType(op, idx);
  if (type == IVA || type == LA || type == IA) {
    retval.u_IVA = decode_iva(pc);
  } else if (type == KA) {
    assert(unit != nullptr);
    retval.u_KA = decode_member_key(pc, unit);
  } else if (!immIsVector(op, cursor)) {
    always_assert(type != RATA);  // Decode RATAs with a different function.
    memcpy(&retval.bytes, pc, immSize(origPC, idx));
  }
  always_assert(numImmediates(op) > idx);
  return retval;
}
예제 #3
0
파일: hhbc.cpp 프로젝트: swtaarrs/hhvm
ArgUnion getImm(const PC origPC, int idx, const Unit* unit) {
  auto pc = origPC;
  auto const op = decode_op(pc);
  assertx(idx >= 0 && idx < numImmediates(op));
  ArgUnion retval;
  retval.u_NA = 0;
  int cursor = 0;
  for (cursor = 0; cursor < idx; cursor++) {
    // Advance over this immediate.
    pc += immSize(immType(op, cursor), pc);
  }
  always_assert(cursor == idx);
  auto const type = immType(op, idx);
  if (type == IVA || type == LA || type == IA ||
      type == CAR || type == CAW) {
    retval.u_IVA = decode_iva(pc);
  } else if (type == KA) {
    assertx(unit != nullptr);
    retval.u_KA = decode_member_key(pc, unit);
  } else if (type == LAR) {
    retval.u_LAR = decodeLocalRange(pc);
  } else if (type == FCA) {
    retval.u_FCA = decodeFCallArgs(pc);
  } else if (type == RATA) {
    assertx(unit != nullptr);
    retval.u_RATA = decodeRAT(unit, pc);
  } else if (!argTypeIsVector(type)) {
    memcpy(&retval.bytes, pc, immSize(type, pc));
  }
  always_assert(numImmediates(op) > idx);
  return retval;
}
예제 #4
0
파일: cmd_next.cpp 프로젝트: facebook/hhvm
// Await / Yield opcodes mark a suspend points of async functions and
// generators. Execution will resume at this function later after the
// opcode.
void CmdNext::setupStepSuspend(ActRec* fp, PC pc) {
  // Yield is followed by the label where execution will continue.
  auto const op = decode_op(pc);
  assertx(op == OpAwait || op == OpYield || op == OpYieldK);
  if (op == OpAwait) {
    decode_iva(pc);
  }
  Offset nextInst = fp->func()->unit()->offsetOf(pc);
  assertx(nextInst != InvalidAbsoluteOffset);
  m_stepResumableId = fp;
  TRACE(2, "CmdNext: patch for resumable step at '%s' offset %d\n",
        fp->m_func->fullName()->data(), nextInst);
  m_stepResumable = StepDestination(fp->m_func->unit(), nextInst);
}
예제 #5
0
파일: hhbc.cpp 프로젝트: swtaarrs/hhvm
ImmVector getImmVector(PC opcode) {
  auto const op = peek_op(opcode);
  int numImm = numImmediates(op);
  for (int k = 0; k < numImm; ++k) {
    ArgType t = immType(op, k);
    if (t == BLA || t == SLA || t == I32LA || t == BLLA || t == VSA) {
      PC vp = getImmPtr(opcode, k)->bytes;
      auto const size = decode_iva(vp);
      return ImmVector(vp, size, t == VSA ? size : 0);
    }
  }

  not_reached();
}
예제 #6
0
파일: hhbc.cpp 프로젝트: swtaarrs/hhvm
/**
 * Return the number of successor-edges including fall-through paths but not
 * implicit exception paths.
 */
int numSuccs(const PC origPC) {
  auto pc = origPC;
  auto const op = decode_op(pc);
  if ((instrFlags(op) & TF) != 0) {
    if (isSwitch(op)) {
      if (op == Op::Switch) {
        decode_raw<SwitchKind>(pc); // skip bounded flag
        decode_raw<int64_t>(pc); // skip base
      }
      return decode_iva(pc); // vector length
    }
    if (isUnconditionalJmp(op) || op == OpIterBreak) return 1;
    return 0;
  }
  if (!instrIsControlFlow(op)) return 1;
  if (instrJumpOffset(origPC)) return 2;
  return 1;
}
예제 #7
0
MemberKey decode_member_key(PC& pc, Either<const Unit*, const UnitEmitter*> u) {
  auto const mcode = static_cast<MemberCode>(decode_byte(pc));

  switch (mcode) {
    case MEC: case MEL: case MPC: case MPL:
      return MemberKey{mcode, decode_iva(pc)};

    case MEI:
      return MemberKey{mcode, decode_raw<int64_t>(pc)};

    case MET: case MPT: case MQT: {
      auto const id = decode_raw<Id>(pc);
      auto const str = u.match(
        [id](const Unit* u) { return u->lookupLitstrId(id); },
        [id](const UnitEmitter* ue) { return ue->lookupLitstr(id); }
      );
      return MemberKey{mcode, str};
    }

    case MW:
      return MemberKey{};
  }
  not_reached();
}
예제 #8
0
파일: hhbc.cpp 프로젝트: fredemmott/hhvm
int immSize(PC origPC, int idx) {
  auto pc = origPC;
  auto const op = decode_op(pc);
  assertx(idx >= 0 && idx < numImmediates(op));
  always_assert(idx < 4); // No origPCs have more than four immediates
  static const int8_t argTypeToSizes[] = {
#define ARGTYPE(nm, type) sizeof(type),
#define ARGTYPEVEC(nm, type) 0,
    ARGTYPES
#undef ARGTYPE
#undef ARGTYPEVEC
  };

  if (immType(op, idx) == IVA ||
      immType(op, idx) == LA ||
      immType(op, idx) == IA ||
      immType(op, idx) == CAR ||
      immType(op, idx) == CAW) {
    if (idx >= 1) pc += immSize(origPC, 0);
    if (idx >= 2) pc += immSize(origPC, 1);
    if (idx >= 3) pc += immSize(origPC, 2);
    return encoded_iva_size(decode_raw<uint8_t>(pc));
  }

  if (immType(op, idx) == KA) {
    if (idx >= 1) pc += immSize(origPC, 0);
    if (idx >= 2) pc += immSize(origPC, 1);
    if (idx >= 3) pc += immSize(origPC, 2);

    switch (decode_raw<MemberCode>(pc)) {
      case MW:
        return 1;
      case MEL: case MPL: case MEC: case MPC:
        return 1 + encoded_iva_size(decode_raw<uint8_t>(pc));
      case MEI:
        return 1 + sizeof(int64_t);
      case MET: case MPT: case MQT:
        return 1 + sizeof(Id);
    }
    not_reached();
  }

  if (immType(op, idx) == RATA) {
    if (idx >= 1) pc += immSize(origPC, 0);
    if (idx >= 2) pc += immSize(origPC, 1);
    if (idx >= 3) pc += immSize(origPC, 2);
    return encodedRATSize(pc);
  }

  if (immType(op, idx) == LAR) {
    if (idx >= 1) pc += immSize(origPC, 0);
    if (idx >= 2) pc += immSize(origPC, 1);
    if (idx >= 3) pc += immSize(origPC, 2);
    auto start = pc;
    decode_iva(pc); // first
    decode_iva(pc); // restCount
    return pc - start;
  }

  if (immIsVector(op, idx)) {
    if (idx >= 1) pc += immSize(origPC, 0);
    if (idx >= 2) pc += immSize(origPC, 1);
    if (idx >= 3) pc += immSize(origPC, 2);
    int vecElemSz;
    auto itype = immType(op, idx);
    if (itype == BLA) {
      vecElemSz = sizeof(Offset);
    } else if (itype == ILA) {
      vecElemSz = 2 * sizeof(uint32_t);
    } else if (itype == VSA) {
      vecElemSz = sizeof(Id);
    } else if (itype == I32LA) {
      vecElemSz = sizeof(uint32_t);
    } else {
      assertx(itype == SLA);
      vecElemSz = sizeof(StrVecItem);
    }
    return sizeof(int32_t) + vecElemSz * decode_raw<int32_t>(pc);
  }

  ArgType type = immType(op, idx);
  return (type >= 0) ? argTypeToSizes[type] : 0;
}