示例#1
0
void HiRes5Engine::setupOpcodeTables() {
	AdlEngine_v4::setupOpcodeTables();

	_actOpcodes[0x0b] = opcode(&HiRes5Engine::o_checkItemTimeLimits);
	_actOpcodes[0x13] = opcode(&HiRes5Engine::o_startAnimation);
	_actOpcodes[0x1e] = opcode(&HiRes5Engine::o_winGame);
}
示例#2
0
void DexInstruction::verify_encoding() const {
  auto test = m_count ? new DexInstruction(opcode()) : new DexInstruction(opcode(), 0);
  if (dests_size()) {
    test->set_dest(dest());
  }
  for (unsigned i = 0; i < srcs_size(); i++) {
    test->set_src(i, src(i));
  }
  if (has_range_base()) test->set_range_base(range_base());
  if (has_range_size()) test->set_range_size(range_size());
  if (has_arg_word_count()) test->set_arg_word_count(arg_word_count());
  if (has_literal()) test->set_literal(literal());
  if (has_offset()) test->set_offset(offset());

  assert_log(m_opcode == test->m_opcode, "%x %x\n", m_opcode, test->m_opcode);
  for (unsigned i = 0; i < m_count; i++) {
    assert_log(m_arg[i] == test->m_arg[i],
               "(%x %x) (%x %x)",
               m_opcode,
               m_arg[i],
               test->m_opcode,
               test->m_arg[i]);
  }

  delete test;
}
示例#3
0
ValueKey Value::key() const
{
    switch (opcode()) {
    case FramePointer:
        return ValueKey(opcode(), type());
    case Identity:
    case Sqrt:
    case SExt8:
    case SExt16:
    case SExt32:
    case ZExt32:
    case Clz:
    case Trunc:
    case FRound:
    case IToD:
    case DToI32:
    case Check:
        return ValueKey(opcode(), type(), child(0));
    case Add:
    case Sub:
    case Mul:
    case ChillDiv:
    case Mod:
    case BitAnd:
    case BitOr:
    case BitXor:
    case Shl:
    case SShr:
    case ZShr:
    case Equal:
    case NotEqual:
    case LessThan:
    case GreaterThan:
    case Above:
    case Below:
    case AboveEqual:
    case BelowEqual:
    case Div:
    case CheckAdd:
    case CheckSub:
    case CheckMul:
        return ValueKey(opcode(), type(), child(0), child(1));
    case Select:
        return ValueKey(opcode(), type(), child(0), child(1), child(2));
    case Const32:
        return ValueKey(Const32, type(), static_cast<int64_t>(asInt32()));
    case Const64:
        return ValueKey(Const64, type(), asInt64());
    case ConstDouble:
        return ValueKey(ConstDouble, type(), asDouble());
    case ArgumentReg:
        return ValueKey(
            ArgumentReg, type(),
            static_cast<int64_t>(as<ArgumentRegValue>()->argumentReg().index()));
    default:
        return ValueKey();
    }
}
示例#4
0
Value* ValueKey::materialize(Procedure& proc, Origin origin) const
{
    switch (opcode()) {
    case FramePointer:
        return proc.add<Value>(opcode(), type(), origin);
    case Identity:
    case Sqrt:
    case SExt8:
    case SExt16:
    case SExt32:
    case ZExt32:
    case Clz:
    case Trunc:
    case IToD:
    case IToF:
    case FloatToDouble:
    case DoubleToFloat:
    case Check:
        return proc.add<Value>(opcode(), type(), origin, child(proc, 0));
    case Add:
    case Sub:
    case Mul:
    case ChillDiv:
    case Mod:
    case BitAnd:
    case BitOr:
    case BitXor:
    case Shl:
    case SShr:
    case ZShr:
    case Equal:
    case NotEqual:
    case LessThan:
    case GreaterThan:
    case Above:
    case Below:
    case AboveEqual:
    case BelowEqual:
    case Div:
        return proc.add<Value>(opcode(), type(), origin, child(proc, 0), child(proc, 1));
    case Select:
        return proc.add<Value>(opcode(), type(), origin, child(proc, 0), child(proc, 1), child(proc, 2));
    case Const32:
        return proc.add<Const32Value>(origin, static_cast<int32_t>(value()));
    case Const64:
        return proc.add<Const64Value>(origin, value());
    case ConstDouble:
        return proc.add<ConstDoubleValue>(origin, doubleValue());
    case ConstFloat:
        return proc.add<ConstFloatValue>(origin, floatValue());
    case ArgumentReg:
        return proc.add<ArgumentRegValue>(origin, Reg::fromIndex(static_cast<unsigned>(value())));
    case SlotBase:
        return proc.add<SlotBaseValue>(origin, proc.stackSlots()[value()]);
    default:
        return nullptr;
    }
}
示例#5
0
TEST(PropagationTest1, localDCE1) {
  g_redex = new RedexContext();

  const char* dexfile = std::getenv("dexfile");
  ASSERT_NE(nullptr, dexfile);

  std::vector<DexStore> stores;
  DexMetadata dm;
  dm.set_id("classes");
  DexStore root_store(dm);
  root_store.add_classes(load_classes_from_dex(dexfile));
  DexClasses& classes = root_store.get_dexen().back();
  stores.emplace_back(std::move(root_store));
  std::cout << "Loaded classes: " << classes.size() << std::endl ;

  TRACE(DCE, 2, "Code before:\n");
  for(const auto& cls : classes) {
    TRACE(DCE, 2, "Class %s\n", SHOW(cls));
    for (const auto& dm : cls->get_dmethods()) {
      TRACE(DCE, 2, "dmethod: %s\n",  dm->get_name()->c_str());
      if (strcmp(dm->get_name()->c_str(), "propagate") == 0) {
        TRACE(DCE, 2, "dmethod: %s\n",  SHOW(dm->get_code()));
      }
    }
  }

  std::vector<Pass*> passes = {
    new PeepholePass(),
    new LocalDcePass(),
  };

  PassManager manager(passes);
  manager.set_testing_mode();

  Json::Value conf_obj = Json::nullValue;
  ConfigFiles dummy_cfg(conf_obj);
  manager.run_passes(stores, dummy_cfg);

  TRACE(DCE, 2, "Code after:\n");
  for(const auto& cls : classes) {
    TRACE(DCE, 2, "Class %s\n", SHOW(cls));
    for (const auto& dm : cls->get_dmethods()) {
      TRACE(DCE, 2, "dmethod: %s\n",  dm->get_name()->c_str());
      if (strcmp(dm->get_name()->c_str(), "propagate") == 0) {
        TRACE(DCE, 2, "dmethod: %s\n",  SHOW(dm->get_code()));
        for (auto& mie : InstructionIterable(dm->get_code())) {
          auto instruction = mie.insn;
          // Make sure there is no invoke-virtual in the optimized method.
          ASSERT_NE(instruction->opcode(), OPCODE_INVOKE_VIRTUAL);
          // Make sure there is no const-class in the optimized method.
          ASSERT_NE(instruction->opcode(), OPCODE_CONST_CLASS);
        }
      }
    }
  }

}
示例#6
0
void compile() {
	while(word()) {				// For each word in input
		if (line > 2) skip();		// Skip to end of line if we are in a comment
		ident = string();		// Find string identity
		if (ident == 0) continue;	// If it is an empty string continue
		fprintf(stderr,"found string ["); dump(); fprintf(stderr,"]\n");
		opcode() ? byte(opcode()): 	// If opcode compile it otherwise
		method() ? function():		// Else see if it is a method, and compile a function call
		find() ? nop() : unknown();	// Otherwise see if it is an object, or unknown
		if (key == 0x60) line = 0;	// reset line on newline
	}
}
示例#7
0
DexOpcode* DexOpcode::set_arg_word_count(uint16_t count) {
  auto DEBUG_ONLY format = opcode_format(opcode());
  assert(format == FMT_f35c);
  assert((count & 0xf) == count);
  m_opcode = (m_opcode & 0x0fff) | (count << 12);
  return this;
}
示例#8
0
void  EiC_peephole(code_t *C, int *visit)
{
    int  i, n,j;
    n = nextinst(C);
    for(i = 0; i < n; ++i)
	if(isgoto(C,i)) {
	    j = i + ivalcode(C,i);
	    if(j >= n)
		continue;
	    if(opcode(C,j) == jmpu || opcode(C,i) == opcode(C,j)) {
		/*visit[i+ivalcode(C,i)]--;*/
		ivalcode(C,i) += ivalcode(C,j);

	    }
	}
}
示例#9
0
WT_Result WT_Text_Option_Scoring::serialize(WT_Object const &, WT_File & file) const
{
    if (file.heuristics().allow_binary_data())
    {
        // Binary output
        WD_CHECK (file.write_count(m_count + 1));
        for (int ii = 0; ii < m_count; ii++)
            WD_CHECK (file.write_count(m_positions[ii] + 1));
    }
    else
    {
        // ASCII output
        if (m_count)
        {
            WD_CHECK (file.write((WT_Byte) ' '));
            WD_CHECK (file.write(opcode()));
            WD_CHECK (file.write(" ("));
            WD_CHECK (file.write_ascii(m_count));
            WD_CHECK (file.write((WT_Byte) ' '));

            WD_CHECK (file.write_ascii(m_positions[0]));
            for (int ii = 1; ii < m_count; ii++)
            {
                WD_CHECK (file.write((WT_Byte) ','));
                WD_CHECK (file.write_ascii(m_positions[ii]));
            }

            WD_CHECK (file.write("))"));
        } // if (m_count)
    } // ascii

    return WT_Result::Success;
}
示例#10
0
uint16_t DexInstruction::range_size() const {
  auto format = opcode_format(opcode());
  assert(format == FMT_f3rc || format == FMT_f5rc);
  if (format == FMT_f5rc)
    return m_arg[0];
  return (m_opcode >> 8) & 0xff;
}
示例#11
0
uint16_t DexInstruction::range_base() const {
  auto format = opcode_format(opcode());
  assert(format == FMT_f3rc || format == FMT_f5rc);
  if (format == FMT_f5rc)
    return m_arg[1];
  return m_arg[0];
}
示例#12
0
DexInstruction* DexInstruction::set_offset(int32_t offset) {
  auto format = opcode_format(opcode());
  switch (format) {
  case FMT_f10t:
    always_assert_log((int32_t)(int8_t)(offset & 0xff) == offset,
                      "offset %d too large for %s",
                      offset,
                      SHOW(this));
    m_opcode = (m_opcode & 0xff) | ((offset & 0xff) << 8);
    return this;
  case FMT_f20t:
  case FMT_f21t:
  case FMT_f22t:
    always_assert_log((int32_t)(int16_t)(offset & 0xffff) == offset,
                      "offset %d too large for %s",
                      offset,
                      SHOW(this));
    m_arg[0] = offset;
    return this;
  case FMT_f30t:
  case FMT_f31t:
    m_arg[0] = offset;
    m_arg[1] = offset >> 16;
    return this;
  default:
    assert(false);
  }
  not_reached();
}
示例#13
0
DexInstruction* DexInstruction::set_literal(int64_t literal) {
  assert(has_literal());
  auto format = opcode_format(opcode());
  switch (format) {
  case FMT_f11n:
    m_opcode = (m_opcode & 0xfff) | ((literal & 0xf) << 12);
    return this;
  case FMT_f21s:
    m_arg[0] = literal;
    return this;
  case FMT_f21h:
    m_arg[0] = literal >> 16;
    return this;
  case FMT_f22b:
    m_arg[0] = literal >> 48;
    return this;
  case FMT_f22s:
    m_arg[0] = literal;
    return this;
  case FMT_f31i:
    m_arg[0] = literal & 0xffff;
    m_arg[1] = literal >> 16;
    return this;
  case FMT_f51l:
    m_arg[0] = literal;
    m_arg[1] = literal >> 16;
    m_arg[2] = literal >> 32;
    m_arg[3] = literal >> 48;
    return this;
  default:
    assert(false);
  }
  not_reached();
}
示例#14
0
int64_t DexInstruction::literal() const {
  assert(has_literal());
  auto format = opcode_format(opcode());
  switch (format) {
  case FMT_f11n:
    return signext<4>(m_opcode >> 12);
  case FMT_f21s:
    return signext<16>(m_arg[0]);
  case FMT_f21h:
    return signext<16>(m_arg[0]) << 16;
  case FMT_f22b:
    return signext<16>(m_arg[0]) << 48;
  case FMT_f22s:
    return signext<16>(m_arg[0]);
  case FMT_f31i: {
    auto literal = uint32_t(m_arg[0]) | (uint32_t(m_arg[1]) << 16);
    return signext<32>(literal);
  }
  case FMT_f51l: {
    auto literal = uint64_t(m_arg[0]) | (uint64_t(m_arg[1]) << 16) |
                   (uint64_t(m_arg[2]) << 32) | (uint64_t(m_arg[3]) << 48);
    return signext<64>(literal);
  }
  default:
    assert(false);
  }
  not_reached();
}
示例#15
0
uint16_t DexInstruction::dest() const {
  auto format = opcode_format(opcode());
  switch (format) {
  case FMT_f12x:
  case FMT_f12x_2:
  case FMT_f11n:
  case FMT_f22s:
  case FMT_f22c_d:
  case FMT_f22cs:
    return (m_opcode >> 8) & 0xf;
  case FMT_f11x_d:
  case FMT_f22x:
  case FMT_f21s:
  case FMT_f21h:
  case FMT_f21c_d:
  case FMT_f23x_d:
  case FMT_f22b:
  case FMT_f31i:
  case FMT_f31c:
  case FMT_f51l:
    return (m_opcode >> 8) & 0xff;
  case FMT_f32x:
    return m_arg[0];
  case FMT_f41c_d:
  case FMT_f52c_d:
    return m_arg[0];
  default:
    // All other formats do not define a destination register.
    always_assert_log(false, "Unhandled opcode: %s", SHOW(this));
  }
  not_reached();
}
示例#16
0
文件: asm.c 项目: drcz/drczlang
void assemble(SE *code,FILE *out,char first) {
  char *opsym;
  /* 1) machine code file should always start with number of used env-slots (symbols),
     2) machine code should at first add T atom to its environment, like this: (CONST t NAME t). */
  if(first==1) fprintf(out,"(%d %d t %d 0 ",symbols_p,O_CONST,O_NAME);
  else fprintf(out,"( ");
  while(code!=NULL) {
    opsym=symval(car(code));
    fprintf(out,"%d ",opcode(opsym));
    if(strcmp(opsym,"const")==0) {      
      write_se(car(cdr(code)),out); fprintf(out," ");
      code=cdr(cdr(code)); continue;

    } else if(strcmp(opsym,"lookup")==0 || strcmp(opsym,"name")==0 || strcmp(opsym,"forget")==0) {
      fprintf(out,"%d ",sym2num(symval(car(cdr(code)))));
      code=cdr(cdr(code)); continue;

    } else if(strcmp(opsym,"select")==0 || strcmp(opsym,"srelect")==0) {
      assemble(car(cdr(code)),out,0);
      assemble(car(cdr(cdr(code))),out,0);
      code=cdr(cdr(cdr(code)));
      continue;

    } else if(strcmp(opsym,"proc")==0) {
      assemble(car(cdr(code)),out,0);
      code=cdr(cdr(code));
      continue;

    } else {
      code=cdr(code);
    }
  } /* while... */
  fprintf(out,") ");
}
示例#17
0
// Format: <string_or_id>[<n><value_1>...<value_n>]<consistency>
// where:
// <string_or_id> is a [long string] for <string> and a [short bytes] for <id>
// <n> is a [short] (only for execute statements)
// <value> is a [bytes] (only for execute statements)
// <consistency> is a [short]
int32_t Statement::encode_v1(RequestCallback* callback, BufferVec* bufs) const {
  int32_t length = 0;
  const int version = 1;

  bufs->push_back(query_or_id_);
  length += query_or_id_.size();

  if (opcode() == CQL_OPCODE_EXECUTE) {
    { // <n> [short]
      Buffer buf(sizeof(uint16_t));
      buf.encode_uint16(0, elements().size());
      bufs->push_back(buf);
      length += sizeof(uint16_t);
    }
    // <value_1>...<value_n>
    int32_t result = encode_values(version, callback, bufs);
    if (result < 0) return result;
    length += result;
  }

  { // <consistency> [short]
    Buffer buf(sizeof(uint16_t));
    buf.encode_uint16(0, callback->consistency());
    bufs->push_back(buf);
    length += sizeof(uint16_t);
  }

  return length;
}
示例#18
0
std::string Statement::query() const {
  if (opcode() == CQL_OPCODE_QUERY) {
    return std::string(query_or_id_.data() + sizeof(int32_t),
                       query_or_id_.size() - sizeof(int32_t));
  }
  return std::string();
}
示例#19
0
DexOpcode* DexOpcode::set_dest(uint16_t vreg) {
  auto format = opcode_format(opcode());
  switch (format) {
  case FMT_f12x:
  case FMT_f12x_2:
  case FMT_f11n:
  case FMT_f22s:
  case FMT_f22c_d:
  case FMT_f22cs:
    assert((vreg & 0xf) == vreg);
    m_opcode = (m_opcode & 0xf0ff) | (vreg << 8);
    return this;
  case FMT_f11x_d:
  case FMT_f22x:
  case FMT_f21s:
  case FMT_f21h:
  case FMT_f21c_d:
  case FMT_f23x_d:
  case FMT_f22b:
  case FMT_f31i:
  case FMT_f31c:
  case FMT_f51l:
    assert((vreg & 0xff) == vreg);
    m_opcode = (m_opcode & 0x00ff) | (vreg << 8);
    return this;
  case FMT_f32x:
    m_arg[0] = vreg;
    return this;
  default:
    // All other formats do not define a destination register.
    always_assert_log(false, "Unhandled opcode: %s", SHOW(this));
  }
  not_reached();
}
示例#20
0
// Return the vector version of a scalar load node.
VectorLoadNode* VectorLoadNode::make(Compile* C, int opc, Node* ctl, Node* mem,
                                     Node* adr, const TypePtr* atyp, uint vlen) {
  int vopc = opcode(opc, vlen);

  switch(vopc) {
  case Op_Load16B: return new (C, 3) Load16BNode(ctl, mem, adr, atyp);
  case Op_Load8B:  return new (C, 3) Load8BNode(ctl, mem, adr, atyp);
  case Op_Load4B:  return new (C, 3) Load4BNode(ctl, mem, adr, atyp);

  case Op_Load8C:  return new (C, 3) Load8CNode(ctl, mem, adr, atyp);
  case Op_Load4C:  return new (C, 3) Load4CNode(ctl, mem, adr, atyp);
  case Op_Load2C:  return new (C, 3) Load2CNode(ctl, mem, adr, atyp);

  case Op_Load8S:  return new (C, 3) Load8SNode(ctl, mem, adr, atyp);
  case Op_Load4S:  return new (C, 3) Load4SNode(ctl, mem, adr, atyp);
  case Op_Load2S:  return new (C, 3) Load2SNode(ctl, mem, adr, atyp);

  case Op_Load4I:  return new (C, 3) Load4INode(ctl, mem, adr, atyp);
  case Op_Load2I:  return new (C, 3) Load2INode(ctl, mem, adr, atyp);

  case Op_Load2L:  return new (C, 3) Load2LNode(ctl, mem, adr, atyp);

  case Op_Load4F:  return new (C, 3) Load4FNode(ctl, mem, adr, atyp);
  case Op_Load2F:  return new (C, 3) Load2FNode(ctl, mem, adr, atyp);

  case Op_Load2D:  return new (C, 3) Load2DNode(ctl, mem, adr, atyp);
  }
  ShouldNotReachHere();
  return NULL;
}
示例#21
0
// Return the vector version of a scalar store node.
VectorStoreNode* VectorStoreNode::make(Compile* C, int opc, Node* ctl, Node* mem,
                                       Node* adr, const TypePtr* atyp, VectorNode* val,
                                       uint vlen) {
  int vopc = opcode(opc, vlen);

  switch(vopc) {
  case Op_Store16B: return new (C, 4) Store16BNode(ctl, mem, adr, atyp, val);
  case Op_Store8B: return new (C, 4) Store8BNode(ctl, mem, adr, atyp, val);
  case Op_Store4B: return new (C, 4) Store4BNode(ctl, mem, adr, atyp, val);

  case Op_Store8C: return new (C, 4) Store8CNode(ctl, mem, adr, atyp, val);
  case Op_Store4C: return new (C, 4) Store4CNode(ctl, mem, adr, atyp, val);
  case Op_Store2C: return new (C, 4) Store2CNode(ctl, mem, adr, atyp, val);

  case Op_Store4I: return new (C, 4) Store4INode(ctl, mem, adr, atyp, val);
  case Op_Store2I: return new (C, 4) Store2INode(ctl, mem, adr, atyp, val);

  case Op_Store2L: return new (C, 4) Store2LNode(ctl, mem, adr, atyp, val);

  case Op_Store4F: return new (C, 4) Store4FNode(ctl, mem, adr, atyp, val);
  case Op_Store2F: return new (C, 4) Store2FNode(ctl, mem, adr, atyp, val);

  case Op_Store2D: return new (C, 4) Store2DNode(ctl, mem, adr, atyp, val);
  }
  ShouldNotReachHere();
  return NULL;
}
示例#22
0
bool Value::returnsBool() const
{
    if (type() != Int32)
        return false;
    switch (opcode()) {
    case Const32:
        return asInt32() == 0 || asInt32() == 1;
    case BitAnd:
        return child(1)->isInt32(1);
    case Equal:
    case NotEqual:
    case LessThan:
    case GreaterThan:
    case LessEqual:
    case GreaterEqual:
    case Above:
    case Below:
    case AboveEqual:
    case BelowEqual:
        return true;
    case Phi:
        // FIXME: We should have a story here.
        // https://bugs.webkit.org/show_bug.cgi?id=150725
        return false;
    default:
        return false;
    }
}
bool CommonUniformElimPass::IsLoopHeader(ir::BasicBlock* block_ptr) {
  auto iItr = block_ptr->tail();
  if (iItr == block_ptr->begin())
    return false;
  --iItr;
  return iItr->opcode() == SpvOpLoopMerge;
}
bool CommonUniformElimPass::CommonUniformLoadElimBlock(ir::Function* func) {
  bool modified = false;
  for (auto& blk : *func) {
    uniform2load_id_.clear();
    for (auto ii = blk.begin(); ii != blk.end(); ++ii) {
      if (ii->opcode() != SpvOpLoad)
        continue;
      uint32_t varId;
      ir::Instruction* ptrInst = GetPtr(&*ii, &varId);
      if (ptrInst->opcode() != SpvOpVariable)
        continue;
      if (!IsUniformVar(varId))
        continue;
      if (!IsSamplerOrImageVar(varId))
        continue;
      if (HasUnsupportedDecorates(ii->result_id()))
        continue;
      uint32_t replId;
      const auto uItr = uniform2load_id_.find(varId);
      if (uItr != uniform2load_id_.end()) {
        replId = uItr->second;
      }
      else {
        uniform2load_id_[varId] = ii->result_id();
        continue;
      }
      ReplaceAndDeleteLoad(&*ii, replId, ptrInst);
      modified = true;
    }
  }
  return modified;
}
bool CommonUniformElimPass::UniformAccessChainConvert(ir::Function* func) {
  bool modified = false;
  for (auto bi = func->begin(); bi != func->end(); ++bi) {
    for (auto ii = bi->begin(); ii != bi->end(); ++ii) {
      if (ii->opcode() != SpvOpLoad)
        continue;
      uint32_t varId;
      ir::Instruction* ptrInst = GetPtr(&*ii, &varId);
      if (!IsNonPtrAccessChain(ptrInst->opcode()))
        continue;
      // Do not convert nested access chains
      if (ptrInst->GetSingleWordInOperand(kAccessChainPtrIdInIdx) != varId)
        continue;
      if (!IsUniformVar(varId))
        continue;
      if (!IsConstantIndexAccessChain(ptrInst))
        continue;
      if (HasUnsupportedDecorates(ii->result_id()))
        continue;
      if (HasUnsupportedDecorates(ptrInst->result_id()))
        continue;
      std::vector<std::unique_ptr<ir::Instruction>> newInsts;
      uint32_t replId;
      GenACLoadRepl(ptrInst, &newInsts, &replId);
      ReplaceAndDeleteLoad(&*ii, replId, ptrInst);
      ++ii;
      ii = ii.InsertBefore(&newInsts);
      ++ii;
      modified = true;
    }
  }
  return modified;
}
示例#26
0
void Pass::AddCalls(ir::Function* func,
    std::queue<uint32_t>* todo) {
  for (auto bi = func->begin(); bi != func->end(); ++bi)
    for (auto ii = bi->begin(); ii != bi->end(); ++ii)
      if (ii->opcode() == SpvOpFunctionCall)
        todo->push(ii->GetSingleWordInOperand(0));
}
示例#27
0
void patch_iget(DexMethod* meth,
                IRList::iterator it,
                DexType* original_field_type) {
  auto insn = it->insn;
  const auto op = insn->opcode();
  always_assert(is_iget(op));
  switch (op) {
  case OPCODE_IGET_OBJECT: {
    auto dest = std::next(it)->insn->dest();
    auto cast = ModelMethodMerger::make_check_cast(original_field_type, dest);
    meth->get_code()->insert_after(insn, cast);
    break;
  }
  case OPCODE_IGET_BYTE: {
    always_assert(original_field_type == get_byte_type());
    auto int_to_byte = new IRInstruction(OPCODE_INT_TO_BYTE);
    patch_iget_for_int_like_types(meth, it, int_to_byte);
    break;
  }
  case OPCODE_IGET_CHAR: {
    always_assert(original_field_type == get_char_type());
    auto int_to_char = new IRInstruction(OPCODE_INT_TO_CHAR);
    patch_iget_for_int_like_types(meth, it, int_to_char);
    break;
  }
  case OPCODE_IGET_SHORT: {
    always_assert(original_field_type == get_short_type());
    auto int_to_short = new IRInstruction(OPCODE_INT_TO_SHORT);
    patch_iget_for_int_like_types(meth, it, int_to_short);
    break;
  }
  default:
    break;
  }
};
示例#28
0
uint16_t DexInstruction::arg_word_count() const {
  auto format = opcode_format(opcode());
  assert(format == FMT_f35c || format == FMT_f57c);
  if (format == FMT_f57c) {
    return (m_arg[0]) & 0xf;
  }
  return (m_opcode >> 12) & 0xf;
}
示例#29
0
Value* Value::invertedCompare(Procedure& proc) const
{
    if (!numChildren())
        return nullptr;
    if (Optional<Opcode> invertedOpcode = B3::invertedCompare(opcode(), child(0)->type()))
        return proc.add<Value>(*invertedOpcode, type(), origin(), children());
    return nullptr;
}
示例#30
0
TEST_F(PostVerify, testArrayDataInCaller) {
  auto cls = find_class_named(
    classes, "Lcom/facebook/redexinline/InlineTest;");
  auto m = find_vmethod_named(*cls, "testArrayDataInCaller");
  ASSERT_EQ(nullptr, find_invoke(m, OPCODE_INVOKE_DIRECT, "callerWithIf"));
  auto last_insn = m->get_code()->get_instructions().back();
  ASSERT_EQ(last_insn->opcode(), FOPCODE_FILLED_ARRAY);
}