Пример #1
0
/*
 * find all the leaders (instruction) in the InstrList given,
 * leaders returned as an ArrayList(set) of Instruction*
 */
ArrayList *findLeaders(InstrList *iList){
	Instruction *temp_ins;
	ArrayList *leaders = al_newGeneric(AL_LIST_SET, addressCompare, refPrint, NULL);
	int i=0;

	//add first instr into leader list
	Instruction *instr = getInstruction(iList, i);
	al_add(leaders, (void *)(instr->addr));

	for(i=0;i<iList->numInstrs;i++){
		Instruction *instr = getInstruction(iList, i);

		//ignore non-jump instructions and native invocations
		if(!isBranch(iList, instr) &&
				!isRetInstruction(iList, instr) &&
				!(isInvokeInstruction(iList, instr) && INSTR_HAS_FLAG(instr, INSTR_IS_SCRIPT_INVOKE))
		)
			continue;

		/* add:
		 * 		instr as target of jump
		 * 		instr immediately after jump
		 */
		if(isBranch(iList, instr)){
			if(!instr->jmpOffset){
				printInstruction(instr);
			}
			assert(instr->jmpOffset);
			al_add(leaders, (void *)(instr->addr + instr->jmpOffset));
			assert(instr->length>0);
			al_add(leaders, (void *)(instr->addr + instr->length));
		}
		else if(isRetInstruction(iList, instr)){
			if(i < iList->numInstrs-1){
				temp_ins = getInstruction(iList, i+1);
				al_add(leaders, (void *)(temp_ins->addr));
			}
		}
		else{	//non-native invoke and document.write() which generate code

			if(i < iList->numInstrs-1){
				assert(isInvokeInstruction(iList, instr) && INSTR_HAS_FLAG(instr, INSTR_IS_SCRIPT_INVOKE));
				temp_ins = getInstruction(iList, i+1);
				al_add(leaders, (void *)(temp_ins->addr));
			}
		}
	}
	return leaders;
}
Пример #2
0
void ForestCell::_updateBounds()
{   
   mIsDirty = false;
   mBounds = Box3F::Invalid;
   mLargestItem = ForestItem::Invalid;

   F32 radius;

   if ( isBranch() )
   {
      for ( U32 i=0; i < 4; i++ )
      {
         mBounds.intersect( mSubCells[i]->getBounds() );

         radius = mSubCells[i]->mLargestItem.getRadius();
         if ( radius > mLargestItem.getRadius() )
            mLargestItem = mSubCells[i]->mLargestItem;
      }

      return;
   }

   // Loop thru all the items in this cell.
   Vector<ForestItem>::const_iterator item = mItems.begin();
   for ( ; item != mItems.end(); item++ )
   {
      mBounds.intersect( (*item).getWorldBox() );

      radius = (*item).getRadius();
      if ( radius > mLargestItem.getRadius() )
         mLargestItem = (*item);
   }
}
Пример #3
0
list listWritedReg(instruction ins, int dico_entry) {
    list L=NULL;
    if(ins.value==-1) {
        return L;   //Si l'instruction est invalide
    }
    switch(dico_data[dico_entry].type) {
    case 0: //R type
        if(ins.r.rd!=0) {
            L=insert(ins.r.rd,L);
        }
        break;

    case 1: //I type (il faut separer les branchs, qui n'ont pas le meme comportement)
        if(isBranch(dico_entry)!=0) { //Si ce n'est pas une branch, on write rt
            if(ins.i.rt!=0) {
                L=insert(ins.i.rt,L);
            }
        }
        break;

    default: //J type no register
        break;
    }
    //printList(L);
    return L;
}
static PTXInstruction* getBranch(block_iterator block)
{
	if(block->instructions.empty()) return nullptr;	
	
	auto ptxBranch = static_cast<ir::PTXInstruction*>(
		block->instructions.back());
	
	if(!ptxBranch->isBranch()) return nullptr;
	
	return ptxBranch;
}
Пример #5
0
int NCodeHook<ArchT>::getMinOffset(const unsigned char* codePtr, unsigned int jumpPatchSize) {
	_DecodeResult result;
	_DecodedInst instructions[MaxInstructions];
	unsigned int instructionCount = 0;

	result = distorm_decode(0, codePtr, 20, ArchT::DisasmType, instructions, MaxInstructions, &instructionCount);
	if (result != DECRES_SUCCESS) return -1;

	unsigned int offset = 0;
	for (unsigned int i = 0; offset < jumpPatchSize && i < instructionCount; ++i) {
		if (isBranch((const char*)instructions[i].mnemonic.p)) return -1;
		offset += instructions[i].size;
	}
	// If we were unable to disassemble enough instructions we fail.
	if (offset < jumpPatchSize) return -1;

	return offset;
}
Пример #6
0
 // Can this statement forego codegen?
 bool isTrivial() const {return !isBranch() && !isEffect();}
Пример #7
0
const ForestItem& ForestCell::insertItem( ForestItemKey key,
                                          ForestItemData *data,
                                          const MatrixF &xfm,
                                          F32 scale )
{
   AssertFatal( key != 0, "ForestCell::insertItem() - Got null key!" );
   AssertFatal( data != NULL, "ForestCell::insertItem() - Got null datablock!" );

   // Make sure we update the bounds later.
   mIsDirty = true;

   // PhysicsBody is now invalid and must be rebuilt later.
   SAFE_DELETE( mPhysicsRep[0] );
   SAFE_DELETE( mPhysicsRep[1] );

   // Destroy batches so we recreate it on
   // the next next render.
   freeBatches();

   // Ok... do we need to split this cell?
   if ( isLeaf() && mItems.size() > MaxItems )
   {
      // Add the children.
      for ( U32 i=0; i < 4; i++ )
         mSubCells[i] = new ForestCell( _makeChildRect( i ) );

      // Now push all our current children down.
      Vector<ForestItem>::iterator item = mItems.begin();
      for ( ; item != mItems.end(); item++ )
      {
         U32 index = _getSubCell( item->getPosition().x, item->getPosition().y );

         mSubCells[index]->insertItem( item->getKey(), 
                                       item->getData(), 
                                       item->getTransform(), 
                                       item->getScale() );
      }

      // Clean up.
      mItems.clear();
      mItems.compact();
   }

   // Do we have children?
   if ( isBranch() )
   {
      // Ok... kick this item down then.
      U32 index = _getSubCell( xfm.getPosition().x, xfm.getPosition().y );
      const ForestItem &result = mSubCells[index]->insertItem( key, data, xfm, scale );

      AssertFatal( index == _getSubCell( result.getPosition().x, result.getPosition().y ), "ForestCell::insertItem() - binning is hosed." );

      return result;
   }

   // Do the datablock preload here to insure it happens
   // before an item is used in the scene.
   data->preload();

   // First see if we can find it.  This is nifty so
   // I'll explain it a bit more.
   // 
   // The find function does a binary search thru the
   // sorted item list.
   //
   // If found the index is the position of the item.
   // 
   // If not found the index is the correct insertion 
   // position for adding the new item.
   //
   // So not only do we have a fast find which is worst
   // case O(log n)... but we also have the proper insert
   // position to maintain a sorted item list.
   //
   U32 index;
   bool found = findIndexByKey( key, &index );
   
   // If we didn't find one then insert it.
   if ( !found )
      mItems.insert( index );

   // Update the item settings.
   ForestItem &item = mItems[ index ];   
   item.setData( data );
   item.setTransform( xfm, scale );

   if ( !found )
      item.setKey( key );

   return item;
}
Пример #8
0
void computeBytecodeBasicBlocks(CodeBlock* codeBlock, Vector<RefPtr<BytecodeBasicBlock> >& basicBlocks)
{
    Vector<unsigned, 32> jumpTargets;
    computePreciseJumpTargets(codeBlock, jumpTargets);

    // Create the entry and exit basic blocks.
    BytecodeBasicBlock* entry = new BytecodeBasicBlock(BytecodeBasicBlock::EntryBlock);
    basicBlocks.append(adoptRef(entry));
    BytecodeBasicBlock* exit = new BytecodeBasicBlock(BytecodeBasicBlock::ExitBlock);

    // Find basic block boundaries.
    BytecodeBasicBlock* current = new BytecodeBasicBlock(0, 0);
    linkBlocks(entry, current);
    basicBlocks.append(adoptRef(current));

    bool nextInstructionIsLeader = false;

    Interpreter* interpreter = codeBlock->vm()->interpreter;
    Instruction* instructionsBegin = codeBlock->instructions().begin();
    unsigned instructionCount = codeBlock->instructions().size();
    for (unsigned bytecodeOffset = 0; bytecodeOffset < instructionCount;) {
        OpcodeID opcodeID = interpreter->getOpcodeID(instructionsBegin[bytecodeOffset].u.opcode);
        unsigned opcodeLength = opcodeLengths[opcodeID];

        bool createdBlock = false;
        // If the current bytecode is a jump target, then it's the leader of its own basic block.
        if (isJumpTarget(opcodeID, jumpTargets, bytecodeOffset) || nextInstructionIsLeader) {
            BytecodeBasicBlock* block = new BytecodeBasicBlock(bytecodeOffset, opcodeLength);
            basicBlocks.append(adoptRef(block));
            current = block;
            createdBlock = true;
            nextInstructionIsLeader = false;
            bytecodeOffset += opcodeLength;
        }

        // If the current bytecode is a branch or a return, then the next instruction is the leader of its own basic block.
        if (isBranch(opcodeID) || isTerminal(opcodeID) || isThrow(opcodeID))
            nextInstructionIsLeader = true;

        if (createdBlock)
            continue;

        // Otherwise, just add to the length of the current block.
        current->addBytecodeLength(opcodeLength);
        bytecodeOffset += opcodeLength;
    }

    // Link basic blocks together.
    for (unsigned i = 0; i < basicBlocks.size(); i++) {
        BytecodeBasicBlock* block = basicBlocks[i].get();

        if (block->isEntryBlock() || block->isExitBlock())
            continue;

        bool fallsThrough = true; 
        for (unsigned bytecodeOffset = block->leaderBytecodeOffset(); bytecodeOffset < block->leaderBytecodeOffset() + block->totalBytecodeLength();) {
            const Instruction& currentInstruction = instructionsBegin[bytecodeOffset];
            OpcodeID opcodeID = interpreter->getOpcodeID(currentInstruction.u.opcode);
            unsigned opcodeLength = opcodeLengths[opcodeID];
            // If we found a terminal bytecode, link to the exit block.
            if (isTerminal(opcodeID)) {
                ASSERT(bytecodeOffset + opcodeLength == block->leaderBytecodeOffset() + block->totalBytecodeLength());
                linkBlocks(block, exit);
                fallsThrough = false;
                break;
            }

            // If we found a throw, get the HandlerInfo for this instruction to see where we will jump. 
            // If there isn't one, treat this throw as a terminal. This is true even if we have a finally
            // block because the finally block will create its own catch, which will generate a HandlerInfo.
            if (isThrow(opcodeID)) {
                ASSERT(bytecodeOffset + opcodeLength == block->leaderBytecodeOffset() + block->totalBytecodeLength());
                HandlerInfo* handler = codeBlock->handlerForBytecodeOffset(bytecodeOffset);
                fallsThrough = false;
                if (!handler) {
                    linkBlocks(block, exit);
                    break;
                }
                for (unsigned i = 0; i < basicBlocks.size(); i++) {
                    BytecodeBasicBlock* otherBlock = basicBlocks[i].get();
                    if (handler->target == otherBlock->leaderBytecodeOffset()) {
                        linkBlocks(block, otherBlock);
                        break;
                    }
                }
                break;
            }

            // If we found a branch, link to the block(s) that we jump to.
            if (isBranch(opcodeID)) {
                ASSERT(bytecodeOffset + opcodeLength == block->leaderBytecodeOffset() + block->totalBytecodeLength());
                Vector<unsigned, 1> bytecodeOffsetsJumpedTo;
                findJumpTargetsForBytecodeOffset(codeBlock, bytecodeOffset, bytecodeOffsetsJumpedTo);

                for (unsigned i = 0; i < basicBlocks.size(); i++) {
                    BytecodeBasicBlock* otherBlock = basicBlocks[i].get();
                    if (bytecodeOffsetsJumpedTo.contains(otherBlock->leaderBytecodeOffset()))
                        linkBlocks(block, otherBlock);
                }

                if (isUnconditionalBranch(opcodeID))
                    fallsThrough = false;

                break;
            }
            bytecodeOffset += opcodeLength;
        }

        // If we fall through then link to the next block in program order.
        if (fallsThrough) {
            ASSERT(i + 1 < basicBlocks.size());
            BytecodeBasicBlock* nextBlock = basicBlocks[i + 1].get();
            linkBlocks(block, nextBlock);
        }
    }

    basicBlocks.append(adoptRef(exit));
}
Пример #9
0
bool DecodedInstruction::isJmp() const {
  // if it's conditional branch, it's not a jmp
  return isBranch(false);
}
Пример #10
0
void BytecodeBasicBlock::computeImpl(Block* codeBlock, Instruction* instructionsBegin, unsigned instructionCount, Vector<std::unique_ptr<BytecodeBasicBlock>>& basicBlocks)
{
    Vector<unsigned, 32> jumpTargets;
    computePreciseJumpTargets(codeBlock, instructionsBegin, instructionCount, jumpTargets);

    auto appendBlock = [&] (std::unique_ptr<BytecodeBasicBlock>&& block) {
        block->m_index = basicBlocks.size();
        basicBlocks.append(WTFMove(block));
    };

    auto linkBlocks = [&] (BytecodeBasicBlock* from, BytecodeBasicBlock* to) {
        from->addSuccessor(to);
    };

    // Create the entry and exit basic blocks.
    basicBlocks.reserveCapacity(jumpTargets.size() + 2);

    auto entry = std::make_unique<BytecodeBasicBlock>(BytecodeBasicBlock::EntryBlock);
    auto firstBlock = std::make_unique<BytecodeBasicBlock>(0, 0);
    linkBlocks(entry.get(), firstBlock.get());

    appendBlock(WTFMove(entry));
    BytecodeBasicBlock* current = firstBlock.get();
    appendBlock(WTFMove(firstBlock));

    auto exit = std::make_unique<BytecodeBasicBlock>(BytecodeBasicBlock::ExitBlock);

    bool nextInstructionIsLeader = false;

    Interpreter* interpreter = codeBlock->vm()->interpreter;
    for (unsigned bytecodeOffset = 0; bytecodeOffset < instructionCount;) {
        OpcodeID opcodeID = interpreter->getOpcodeID(instructionsBegin[bytecodeOffset]);
        unsigned opcodeLength = opcodeLengths[opcodeID];

        bool createdBlock = false;
        // If the current bytecode is a jump target, then it's the leader of its own basic block.
        if (isJumpTarget(opcodeID, jumpTargets, bytecodeOffset) || nextInstructionIsLeader) {
            auto newBlock = std::make_unique<BytecodeBasicBlock>(bytecodeOffset, opcodeLength);
            current = newBlock.get();
            appendBlock(WTFMove(newBlock));
            createdBlock = true;
            nextInstructionIsLeader = false;
            bytecodeOffset += opcodeLength;
        }

        // If the current bytecode is a branch or a return, then the next instruction is the leader of its own basic block.
        if (isBranch(opcodeID) || isTerminal(opcodeID) || isThrow(opcodeID))
            nextInstructionIsLeader = true;

        if (createdBlock)
            continue;

        // Otherwise, just add to the length of the current block.
        current->addLength(opcodeLength);
        bytecodeOffset += opcodeLength;
    }

    // Link basic blocks together.
    for (unsigned i = 0; i < basicBlocks.size(); i++) {
        BytecodeBasicBlock* block = basicBlocks[i].get();

        if (block->isEntryBlock() || block->isExitBlock())
            continue;

        bool fallsThrough = true; 
        for (unsigned bytecodeOffset = block->leaderOffset(); bytecodeOffset < block->leaderOffset() + block->totalLength();) {
            OpcodeID opcodeID = interpreter->getOpcodeID(instructionsBegin[bytecodeOffset]);
            unsigned opcodeLength = opcodeLengths[opcodeID];
            // If we found a terminal bytecode, link to the exit block.
            if (isTerminal(opcodeID)) {
                ASSERT(bytecodeOffset + opcodeLength == block->leaderOffset() + block->totalLength());
                linkBlocks(block, exit.get());
                fallsThrough = false;
                break;
            }

            // If we found a throw, get the HandlerInfo for this instruction to see where we will jump. 
            // If there isn't one, treat this throw as a terminal. This is true even if we have a finally
            // block because the finally block will create its own catch, which will generate a HandlerInfo.
            if (isThrow(opcodeID)) {
                ASSERT(bytecodeOffset + opcodeLength == block->leaderOffset() + block->totalLength());
                auto* handler = codeBlock->handlerForBytecodeOffset(bytecodeOffset);
                fallsThrough = false;
                if (!handler) {
                    linkBlocks(block, exit.get());
                    break;
                }
                for (unsigned i = 0; i < basicBlocks.size(); i++) {
                    BytecodeBasicBlock* otherBlock = basicBlocks[i].get();
                    if (handler->target == otherBlock->leaderOffset()) {
                        linkBlocks(block, otherBlock);
                        break;
                    }
                }
                break;
            }

            // If we found a branch, link to the block(s) that we jump to.
            if (isBranch(opcodeID)) {
                ASSERT(bytecodeOffset + opcodeLength == block->leaderOffset() + block->totalLength());
                Vector<unsigned, 1> bytecodeOffsetsJumpedTo;
                findJumpTargetsForBytecodeOffset(codeBlock, instructionsBegin, bytecodeOffset, bytecodeOffsetsJumpedTo);

                for (unsigned i = 0; i < basicBlocks.size(); i++) {
                    BytecodeBasicBlock* otherBlock = basicBlocks[i].get();
                    if (bytecodeOffsetsJumpedTo.contains(otherBlock->leaderOffset()))
                        linkBlocks(block, otherBlock);
                }

                if (isUnconditionalBranch(opcodeID))
                    fallsThrough = false;

                break;
            }
            bytecodeOffset += opcodeLength;
        }

        // If we fall through then link to the next block in program order.
        if (fallsThrough) {
            ASSERT(i + 1 < basicBlocks.size());
            BytecodeBasicBlock* nextBlock = basicBlocks[i + 1].get();
            linkBlocks(block, nextBlock);
        }
    }

    appendBlock(WTFMove(exit));
    
    for (auto& basicBlock : basicBlocks)
        basicBlock->shrinkToFit();
}
void BytecodeBasicBlock::computeImpl(Block* codeBlock, const InstructionStream& instructions, Vector<std::unique_ptr<BytecodeBasicBlock>>& basicBlocks)
{
    Vector<InstructionStream::Offset, 32> jumpTargets;
    computePreciseJumpTargets(codeBlock, instructions, jumpTargets);

    auto appendBlock = [&] (std::unique_ptr<BytecodeBasicBlock>&& block) {
        block->m_index = basicBlocks.size();
        basicBlocks.append(WTFMove(block));
    };

    auto linkBlocks = [&] (BytecodeBasicBlock* from, BytecodeBasicBlock* to) {
        from->addSuccessor(to);
    };

    // Create the entry and exit basic blocks.
    basicBlocks.reserveCapacity(jumpTargets.size() + 2);

    auto entry = std::make_unique<BytecodeBasicBlock>(BytecodeBasicBlock::EntryBlock);
    auto firstBlock = std::make_unique<BytecodeBasicBlock>(BytecodeBasicBlock::EntryBlock);
    linkBlocks(entry.get(), firstBlock.get());

    appendBlock(WTFMove(entry));
    BytecodeBasicBlock* current = firstBlock.get();
    appendBlock(WTFMove(firstBlock));

    auto exit = std::make_unique<BytecodeBasicBlock>(BytecodeBasicBlock::ExitBlock);

    bool nextInstructionIsLeader = false;

    for (const auto& instruction : instructions) {
        auto bytecodeOffset = instruction.offset();
        OpcodeID opcodeID = instruction->opcodeID();

        bool createdBlock = false;
        // If the current bytecode is a jump target, then it's the leader of its own basic block.
        if (isJumpTarget(opcodeID, jumpTargets, bytecodeOffset) || nextInstructionIsLeader) {
            auto newBlock = std::make_unique<BytecodeBasicBlock>(instruction);
            current = newBlock.get();
            appendBlock(WTFMove(newBlock));
            createdBlock = true;
            nextInstructionIsLeader = false;
        }

        // If the current bytecode is a branch or a return, then the next instruction is the leader of its own basic block.
        if (isBranch(opcodeID) || isTerminal(opcodeID) || isThrow(opcodeID))
            nextInstructionIsLeader = true;

        if (createdBlock)
            continue;

        // Otherwise, just add to the length of the current block.
        current->addLength(instruction->size());
    }

    // Link basic blocks together.
    for (unsigned i = 0; i < basicBlocks.size(); i++) {
        BytecodeBasicBlock* block = basicBlocks[i].get();

        if (block->isEntryBlock() || block->isExitBlock())
            continue;

        bool fallsThrough = true;
        for (auto bytecodeOffset : block->offsets()) {
            auto instruction = instructions.at(bytecodeOffset);
            OpcodeID opcodeID = instruction->opcodeID();

            // If we found a terminal bytecode, link to the exit block.
            if (isTerminal(opcodeID)) {
                ASSERT(bytecodeOffset + instruction->size() == block->leaderOffset() + block->totalLength());
                linkBlocks(block, exit.get());
                fallsThrough = false;
                break;
            }

            // If we found a throw, get the HandlerInfo for this instruction to see where we will jump.
            // If there isn't one, treat this throw as a terminal. This is true even if we have a finally
            // block because the finally block will create its own catch, which will generate a HandlerInfo.
            if (isThrow(opcodeID)) {
                ASSERT(bytecodeOffset + instruction->size() == block->leaderOffset() + block->totalLength());
                auto* handler = codeBlock->handlerForBytecodeOffset(instruction.offset());
                fallsThrough = false;
                if (!handler) {
                    linkBlocks(block, exit.get());
                    break;
                }
                for (unsigned i = 0; i < basicBlocks.size(); i++) {
                    BytecodeBasicBlock* otherBlock = basicBlocks[i].get();
                    if (handler->target == otherBlock->leaderOffset()) {
                        linkBlocks(block, otherBlock);
                        break;
                    }
                }
                break;
            }

            // If we found a branch, link to the block(s) that we jump to.
            if (isBranch(opcodeID)) {
                ASSERT(bytecodeOffset + instruction->size() == block->leaderOffset() + block->totalLength());
                Vector<InstructionStream::Offset, 1> bytecodeOffsetsJumpedTo;
                findJumpTargetsForInstruction(codeBlock, instruction, bytecodeOffsetsJumpedTo);

                size_t numberOfJumpTargets = bytecodeOffsetsJumpedTo.size();
                ASSERT(numberOfJumpTargets);
                for (unsigned i = 0; i < basicBlocks.size(); i++) {
                    BytecodeBasicBlock* otherBlock = basicBlocks[i].get();
                    if (bytecodeOffsetsJumpedTo.contains(otherBlock->leaderOffset())) {
                        linkBlocks(block, otherBlock);
                        --numberOfJumpTargets;
                        if (!numberOfJumpTargets)
                            break;
                    }
                }
                // numberOfJumpTargets may not be 0 here if there are multiple jumps targeting the same
                // basic blocks (e.g. in a switch type opcode). Since we only decrement numberOfJumpTargets
                // once per basic block, the duplicates are not accounted for. For our purpose here,
                // that doesn't matter because we only need to link to the target block once regardless
                // of how many ways this block can jump there.

                if (isUnconditionalBranch(opcodeID))
                    fallsThrough = false;

                break;
            }
        }

        // If we fall through then link to the next block in program order.
        if (fallsThrough) {
            ASSERT(i + 1 < basicBlocks.size());
            BytecodeBasicBlock* nextBlock = basicBlocks[i + 1].get();
            linkBlocks(block, nextBlock);
        }
    }

    appendBlock(WTFMove(exit));

    for (auto& basicBlock : basicBlocks)
        basicBlock->shrinkToFit();
}
Пример #12
0
bool XmlNode::isLeaf() { return !isBranch(); }
Пример #13
0
void x86RevDis::RevDisasm(uint32 uStartAddr, uint32 uCurAddr)
{
	CPU_ADDR	curAddr;
	curAddr.addr32.offset = uCurAddr;

	for (unsigned i=uCurAddr-uStartAddr;i<m_uSize;)
	{
		x86dis_insn* insn = (x86dis_insn*)m_decoder.decode(m_pCode+i,m_uSize-i,curAddr);

		m_mapResult.insert(std::map<uint32,x86dis_insn>::value_type(curAddr.addr32.offset,*insn));

		const char* pcsIns = m_decoder.str(insn,DIS_STYLE_HEX_ASMSTYLE | DIS_STYLE_HEX_UPPERCASE | DIS_STYLE_HEX_NOZEROPAD);
		//printf("%08X\t%s\n",curAddr.addr32.offset, pcsIns);
		i += insn->size;
		curAddr.addr32.offset += insn->size;

		switch (isBranch(insn))
		{
		case br_return:
			return;
		case br_jump:
			{
				CPU_ADDR branch = branchAddr(insn);
				if (branch.addr32.offset<uStartAddr
					|| branch.addr32.offset>uStartAddr+m_uSize)
				{
					//跳转到的地址不在本段代码内
					break;
				}

				std::map<uint32,x86dis_insn>::iterator it = m_mapResult.find(branch.addr32.offset);
				if (it!=m_mapResult.end())
				{
					//已经反过了
					break;
				}
				return RevDisasm(uStartAddr,branch.addr32.offset);
			}
		case br_jXX:
		case br_call:
			{
				CPU_ADDR branch = branchAddr(insn);
				if (branch.addr32.offset<uStartAddr
					|| branch.addr32.offset>uStartAddr+m_uSize)
				{
					//跳转到的地址不在本段代码内
					break;
				}

				std::map<uint32,x86dis_insn>::iterator it = m_mapResult.find(branch.addr32.offset);
				if (it!=m_mapResult.end())
				{
					//已经反过了
					break;
				}
				RevDisasm(uStartAddr,branch.addr32.offset);
			}
			break;
		}
	}

}