本文整理汇总了C++中Interpreter::getOpcodeID方法的典型用法代码示例。如果您正苦于以下问题:C++ Interpreter::getOpcodeID方法的具体用法?C++ Interpreter::getOpcodeID怎么用?C++ Interpreter::getOpcodeID使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Interpreter
的用法示例。
在下文中一共展示了Interpreter::getOpcodeID方法的10个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: canHandleOpcodes
bool canHandleOpcodes(CodeBlock* codeBlock)
{
Interpreter* interpreter = codeBlock->globalData()->interpreter;
Instruction* instructionsBegin = codeBlock->instructions().begin();
unsigned instructionCount = codeBlock->instructions().size();
for (unsigned bytecodeOffset = 0; bytecodeOffset < instructionCount; ) {
switch (interpreter->getOpcodeID(instructionsBegin[bytecodeOffset].u.opcode)) {
#define DEFINE_OP(opcode, length) \
case opcode: \
if (!canHandleOpcode(opcode)) { \
debugFail(codeBlock, opcode); \
return false; \
} \
bytecodeOffset += length; \
break;
FOR_EACH_OPCODE_ID(DEFINE_OP)
#undef DEFINE_OP
default:
ASSERT_NOT_REACHED();
break;
}
}
return true;
}
示例2: canHandleOpcodes
ReturnType canHandleOpcodes(CodeBlock* codeBlock, ReturnType initialValue)
{
Interpreter* interpreter = codeBlock->vm()->interpreter;
Instruction* instructionsBegin = codeBlock->instructions().begin();
unsigned instructionCount = codeBlock->instructions().size();
ReturnType result = initialValue;
for (unsigned bytecodeOffset = 0; bytecodeOffset < instructionCount; ) {
switch (interpreter->getOpcodeID(instructionsBegin[bytecodeOffset].u.opcode)) {
#define DEFINE_OP(opcode, length) \
case opcode: { \
ReturnType current = canHandleOpcode( \
opcode, codeBlock, instructionsBegin + bytecodeOffset); \
if (current < result) { \
result = current; \
debugFail(codeBlock, opcode, current); \
} \
bytecodeOffset += length; \
break; \
}
FOR_EACH_OPCODE_ID(DEFINE_OP)
#undef DEFINE_OP
default:
RELEASE_ASSERT_NOT_REACHED();
break;
}
}
return result;
}
示例3: dumpResults
void BytecodeLivenessAnalysis::dumpResults()
{
Interpreter* interpreter = m_codeBlock->vm()->interpreter;
Instruction* instructionsBegin = m_codeBlock->instructions().begin();
for (unsigned i = 0; i < m_basicBlocks.size(); i++) {
BytecodeBasicBlock* block = m_basicBlocks[i].get();
dataLogF("\nBytecode basic block %u: %p (offset: %u, length: %u)\n", i, block, block->leaderBytecodeOffset(), block->totalBytecodeLength());
dataLogF("Predecessors: ");
for (unsigned j = 0; j < block->predecessors().size(); j++) {
BytecodeBasicBlock* predecessor = block->predecessors()[j];
dataLogF("%p ", predecessor);
}
dataLogF("\n");
dataLogF("Successors: ");
for (unsigned j = 0; j < block->successors().size(); j++) {
BytecodeBasicBlock* successor = block->successors()[j];
dataLogF("%p ", successor);
}
dataLogF("\n");
if (block->isEntryBlock()) {
dataLogF("Entry block %p\n", block);
continue;
}
if (block->isExitBlock()) {
dataLogF("Exit block: %p\n", block);
continue;
}
for (unsigned bytecodeOffset = block->leaderBytecodeOffset(); bytecodeOffset < block->leaderBytecodeOffset() + block->totalBytecodeLength();) {
const Instruction* currentInstruction = &instructionsBegin[bytecodeOffset];
dataLogF("Live variables: ");
FastBitVector liveBefore = getLivenessInfoAtBytecodeOffset(bytecodeOffset);
for (unsigned j = 0; j < liveBefore.numBits(); j++) {
if (liveBefore.get(j))
dataLogF("%u ", j);
}
dataLogF("\n");
m_codeBlock->dumpBytecode(WTF::dataFile(), m_codeBlock->globalObject()->globalExec(), instructionsBegin, currentInstruction);
OpcodeID opcodeID = interpreter->getOpcodeID(instructionsBegin[bytecodeOffset].u.opcode);
unsigned opcodeLength = opcodeLengths[opcodeID];
bytecodeOffset += opcodeLength;
}
dataLogF("Live variables: ");
FastBitVector liveAfter = block->out();
for (unsigned j = 0; j < liveAfter.numBits(); j++) {
if (liveAfter.get(j))
dataLogF("%u ", j);
}
dataLogF("\n");
}
}
示例4: stepOverInstruction
static void stepOverInstruction(CodeBlock* codeBlock, BytecodeBasicBlock* block, Vector<std::unique_ptr<BytecodeBasicBlock>>& basicBlocks, unsigned bytecodeOffset, const UseFunctor& use, const DefFunctor& def)
{
// This abstractly execute the instruction in reverse. Instructions logically first use operands and
// then define operands. This logical ordering is necessary for operations that use and def the same
// operand, like:
//
// op_add loc1, loc1, loc2
//
// The use of loc1 happens before the def of loc1. That's a semantic requirement since the add
// operation cannot travel forward in time to read the value that it will produce after reading that
// value. Since we are executing in reverse, this means that we must do defs before uses (reverse of
// uses before defs).
//
// Since this is a liveness analysis, this ordering ends up being particularly important: if we did
// uses before defs, then the add operation above would appear to not have loc1 live, since we'd
// first add it to the out set (the use), and then we'd remove it (the def).
computeDefsForBytecodeOffset(
codeBlock, block, bytecodeOffset,
[&] (CodeBlock* codeBlock, Instruction*, OpcodeID, int operand) {
if (isValidRegisterForLiveness(codeBlock, operand))
def(VirtualRegister(operand).toLocal());
});
computeUsesForBytecodeOffset(
codeBlock, block, bytecodeOffset,
[&] (CodeBlock* codeBlock, Instruction*, OpcodeID, int operand) {
if (isValidRegisterForLiveness(codeBlock, operand))
use(VirtualRegister(operand).toLocal());
});
// If we have an exception handler, we want the live-in variables of the
// exception handler block to be included in the live-in of this particular bytecode.
if (HandlerInfo* handler = codeBlock->handlerForBytecodeOffset(bytecodeOffset)) {
// FIXME: This resume check should not be needed.
// https://bugs.webkit.org/show_bug.cgi?id=159281
Interpreter* interpreter = codeBlock->vm()->interpreter;
Instruction* instructionsBegin = codeBlock->instructions().begin();
Instruction* instruction = &instructionsBegin[bytecodeOffset];
OpcodeID opcodeID = interpreter->getOpcodeID(instruction->u.opcode);
if (opcodeID != op_resume) {
BytecodeBasicBlock* handlerBlock = findBasicBlockWithLeaderOffset(basicBlocks, handler->target);
ASSERT(handlerBlock);
handlerBlock->in().forEachSetBit(use);
}
}
}
示例5: computePreciseJumpTargetsInternal
void computePreciseJumpTargetsInternal(Block* codeBlock, Instruction* instructionsBegin, unsigned instructionCount, Vector<unsigned, vectorSize>& out)
{
ASSERT(out.isEmpty());
// We will derive a superset of the jump targets that the code block thinks it has.
// So, if the code block claims there are none, then we are done.
if (Mode == ComputePreciseJumpTargetsMode::FollowCodeBlockClaim && !codeBlock->numberOfJumpTargets())
return;
for (unsigned i = codeBlock->numberOfExceptionHandlers(); i--;) {
out.append(codeBlock->exceptionHandler(i).target);
out.append(codeBlock->exceptionHandler(i).start);
out.append(codeBlock->exceptionHandler(i).end);
}
Interpreter* interpreter = codeBlock->vm()->interpreter;
for (unsigned bytecodeOffset = 0; bytecodeOffset < instructionCount;) {
OpcodeID opcodeID = interpreter->getOpcodeID(instructionsBegin[bytecodeOffset]);
getJumpTargetsForBytecodeOffset(codeBlock, interpreter, instructionsBegin, bytecodeOffset, out);
bytecodeOffset += opcodeLengths[opcodeID];
}
std::sort(out.begin(), out.end());
// We will have duplicates, and we must remove them.
unsigned toIndex = 0;
unsigned fromIndex = 0;
unsigned lastValue = UINT_MAX;
while (fromIndex < out.size()) {
unsigned value = out[fromIndex++];
if (value == lastValue)
continue;
out[toIndex++] = value;
lastValue = value;
}
out.resize(toIndex);
out.shrinkToFit();
}
示例6: computeBytecodeBasicBlocks
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);
}
//.........这里部分代码省略.........
示例7: computePreciseJumpTargets
void computePreciseJumpTargets(CodeBlock* codeBlock, Vector<unsigned, 32>& out)
{
ASSERT(out.isEmpty());
// We will derive a superset of the jump targets that the code block thinks it has.
// So, if the code block claims there are none, then we are done.
if (!codeBlock->numberOfJumpTargets())
return;
for (unsigned i = codeBlock->numberOfExceptionHandlers(); i--;)
out.append(codeBlock->exceptionHandler(i).target);
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);
Instruction* current = instructionsBegin + bytecodeOffset;
switch (opcodeID) {
case op_jmp:
out.append(bytecodeOffset + current[1].u.operand);
break;
case op_jtrue:
case op_jfalse:
case op_jeq_null:
case op_jneq_null:
out.append(bytecodeOffset + current[2].u.operand);
break;
case op_jneq_ptr:
case op_jless:
case op_jlesseq:
case op_jgreater:
case op_jgreatereq:
case op_jnless:
case op_jnlesseq:
case op_jngreater:
case op_jngreatereq:
out.append(bytecodeOffset + current[3].u.operand);
break;
case op_switch_imm:
addSimpleSwitchTargets(codeBlock->immediateSwitchJumpTable(current[1].u.operand), bytecodeOffset, out);
out.append(bytecodeOffset + current[2].u.operand);
break;
case op_switch_char:
addSimpleSwitchTargets(codeBlock->characterSwitchJumpTable(current[1].u.operand), bytecodeOffset, out);
out.append(bytecodeOffset + current[2].u.operand);
break;
case op_switch_string: {
StringJumpTable& table = codeBlock->stringSwitchJumpTable(current[1].u.operand);
StringJumpTable::StringOffsetTable::iterator iter = table.offsetTable.begin();
StringJumpTable::StringOffsetTable::iterator end = table.offsetTable.end();
for (; iter != end; ++iter)
out.append(bytecodeOffset + iter->value.branchOffset);
out.append(bytecodeOffset + current[2].u.operand);
break;
}
case op_get_pnames:
out.append(bytecodeOffset + current[5].u.operand);
break;
case op_next_pname:
out.append(bytecodeOffset + current[6].u.operand);
break;
case op_check_has_instance:
out.append(bytecodeOffset + current[4].u.operand);
break;
case op_loop_hint:
out.append(bytecodeOffset);
break;
default:
break;
}
bytecodeOffset += opcodeLengths[opcodeID];
}
std::sort(out.begin(), out.end());
// We will have duplicates, and we must remove them.
unsigned toIndex = 0;
unsigned fromIndex = 0;
unsigned lastValue = UINT_MAX;
while (fromIndex < out.size()) {
unsigned value = out[fromIndex++];
if (value == lastValue)
continue;
out[toIndex++] = value;
lastValue = value;
}
out.resize(toIndex);
}
示例8: computeImpl
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());
//.........这里部分代码省略.........
示例9: computeUsesForBytecodeOffset
static void computeUsesForBytecodeOffset(CodeBlock* codeBlock, unsigned bytecodeOffset, FastBitVector& uses)
{
Interpreter* interpreter = codeBlock->vm()->interpreter;
Instruction* instructionsBegin = codeBlock->instructions().begin();
Instruction* instruction = &instructionsBegin[bytecodeOffset];
OpcodeID opcodeID = interpreter->getOpcodeID(instruction->u.opcode);
switch (opcodeID) {
// No uses.
case op_new_regexp:
case op_new_array_buffer:
case op_throw_static_error:
case op_debug:
case op_resolve_scope:
case op_pop_scope:
case op_jneq_ptr:
case op_new_func_exp:
case op_loop_hint:
case op_jmp:
case op_new_object:
case op_init_lazy_reg:
case op_get_callee:
case op_enter:
case op_catch:
return;
// First argument.
case op_new_func:
case op_create_activation:
case op_create_arguments:
case op_to_this:
case op_tear_off_activation:
case op_profile_will_call:
case op_profile_did_call:
case op_throw:
case op_push_with_scope:
case op_end:
case op_ret:
case op_jtrue:
case op_jfalse:
case op_jeq_null:
case op_jneq_null:
case op_dec:
case op_inc: {
if (isValidRegisterForLiveness(codeBlock, instruction[1].u.operand))
setForOperand(codeBlock, uses, instruction[1].u.operand);
return;
}
// First and second arguments.
case op_del_by_id:
case op_ret_object_or_this:
case op_jlesseq:
case op_jgreater:
case op_jgreatereq:
case op_jnless:
case op_jnlesseq:
case op_jngreater:
case op_jngreatereq:
case op_jless: {
if (isValidRegisterForLiveness(codeBlock, instruction[1].u.operand))
setForOperand(codeBlock, uses, instruction[1].u.operand);
if (isValidRegisterForLiveness(codeBlock, instruction[2].u.operand))
setForOperand(codeBlock, uses, instruction[2].u.operand);
return;
}
// First, second, and third arguments.
case op_del_by_val:
case op_put_by_val_direct:
case op_put_by_val: {
if (isValidRegisterForLiveness(codeBlock, instruction[1].u.operand))
setForOperand(codeBlock, uses, instruction[1].u.operand);
if (isValidRegisterForLiveness(codeBlock, instruction[2].u.operand))
setForOperand(codeBlock, uses, instruction[2].u.operand);
if (isValidRegisterForLiveness(codeBlock, instruction[3].u.operand))
setForOperand(codeBlock, uses, instruction[3].u.operand);
return;
}
// First and third arguments.
case op_put_by_index:
case op_put_by_id_replace:
case op_put_by_id_transition:
case op_put_by_id_transition_direct:
case op_put_by_id_transition_direct_out_of_line:
case op_put_by_id_transition_normal:
case op_put_by_id_transition_normal_out_of_line:
case op_put_by_id_generic:
case op_put_by_id_out_of_line:
case op_put_by_id:
case op_put_to_scope: {
if (isValidRegisterForLiveness(codeBlock, instruction[1].u.operand))
setForOperand(codeBlock, uses, instruction[1].u.operand);
if (isValidRegisterForLiveness(codeBlock, instruction[3].u.operand))
setForOperand(codeBlock, uses, instruction[3].u.operand);
return;
}
// First, third, and fourth arguments.
case op_put_getter_setter: {
if (isValidRegisterForLiveness(codeBlock, instruction[1].u.operand))
setForOperand(codeBlock, uses, instruction[1].u.operand);
if (isValidRegisterForLiveness(codeBlock, instruction[3].u.operand))
setForOperand(codeBlock, uses, instruction[3].u.operand);
if (isValidRegisterForLiveness(codeBlock, instruction[4].u.operand))
//.........这里部分代码省略.........
示例10: computeDefsForBytecodeOffset
static void computeDefsForBytecodeOffset(CodeBlock* codeBlock, unsigned bytecodeOffset, FastBitVector& defs)
{
Interpreter* interpreter = codeBlock->vm()->interpreter;
Instruction* instructionsBegin = codeBlock->instructions().begin();
Instruction* instruction = &instructionsBegin[bytecodeOffset];
OpcodeID opcodeID = interpreter->getOpcodeID(instruction->u.opcode);
switch (opcodeID) {
// These don't define anything.
case op_init_global_const:
case op_init_global_const_nop:
case op_push_name_scope:
case op_push_with_scope:
case op_put_to_scope:
case op_pop_scope:
case op_end:
case op_profile_will_call:
case op_profile_did_call:
case op_throw:
case op_throw_static_error:
case op_debug:
case op_ret:
case op_ret_object_or_this:
case op_jmp:
case op_jtrue:
case op_jfalse:
case op_jeq_null:
case op_jneq_null:
case op_jneq_ptr:
case op_jless:
case op_jlesseq:
case op_jgreater:
case op_jgreatereq:
case op_jnless:
case op_jnlesseq:
case op_jngreater:
case op_jngreatereq:
case op_loop_hint:
case op_switch_imm:
case op_switch_char:
case op_switch_string:
case op_put_by_id:
case op_put_by_id_out_of_line:
case op_put_by_id_replace:
case op_put_by_id_transition:
case op_put_by_id_transition_direct:
case op_put_by_id_transition_direct_out_of_line:
case op_put_by_id_transition_normal:
case op_put_by_id_transition_normal_out_of_line:
case op_put_by_id_generic:
case op_put_getter_setter:
case op_put_by_val:
case op_put_by_val_direct:
case op_put_by_index:
case op_del_by_id:
case op_del_by_val:
#define LLINT_HELPER_OPCODES(opcode, length) case opcode:
FOR_EACH_LLINT_OPCODE_EXTENSION(LLINT_HELPER_OPCODES);
#undef LLINT_HELPER_OPCODES
return;
// These all have a single destination for the first argument.
case op_next_pname:
case op_get_pnames:
case op_resolve_scope:
case op_strcat:
case op_tear_off_activation:
case op_to_primitive:
case op_catch:
case op_create_this:
case op_new_array:
case op_new_array_buffer:
case op_new_array_with_size:
case op_new_regexp:
case op_new_func:
case op_new_func_exp:
case op_call_varargs:
case op_get_from_scope:
case op_call:
case op_call_eval:
case op_construct:
case op_get_by_id:
case op_get_by_id_out_of_line:
case op_get_by_id_self:
case op_get_by_id_proto:
case op_get_by_id_chain:
case op_get_by_id_getter_self:
case op_get_by_id_getter_proto:
case op_get_by_id_getter_chain:
case op_get_by_id_custom_self:
case op_get_by_id_custom_proto:
case op_get_by_id_custom_chain:
case op_get_by_id_generic:
case op_get_array_length:
case op_get_string_length:
case op_check_has_instance:
case op_instanceof:
case op_get_by_val:
case op_get_argument_by_val:
case op_get_by_pname:
case op_get_arguments_length:
case op_typeof:
//.........这里部分代码省略.........