Ignore:
Timestamp:
Sep 24, 2012, 9:30:20 PM (13 years ago)
Author:
[email protected]
Message:

Deleting the classic interpreter and cleaning up some build options.
https://bugs.webkit.org/show_bug.cgi?id=96969.

Reviewed by Geoffrey Garen.

Source/JavaScriptCore:

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::dump):
(JSC::CodeBlock::finalizeUnconditionally):
(JSC::CodeBlock::stronglyVisitStrongReferences):
(JSC):

  • bytecode/Instruction.h:

(JSC::Instruction::Instruction):

  • interpreter/AbstractPC.cpp:

(JSC::AbstractPC::AbstractPC):

  • interpreter/AbstractPC.h:

(AbstractPC):

  • interpreter/CallFrame.h:

(ExecState):

  • interpreter/Interpreter.cpp:

(JSC):
(JSC::Interpreter::Interpreter):
(JSC::Interpreter::~Interpreter):
(JSC::Interpreter::initialize):
(JSC::Interpreter::isOpcode):
(JSC::Interpreter::unwindCallFrame):
(JSC::getLineNumberForCallFrame):
(JSC::getCallerInfo):
(JSC::getSourceURLFromCallFrame):
(JSC::Interpreter::execute):
(JSC::Interpreter::executeCall):
(JSC::Interpreter::executeConstruct):
(JSC::Interpreter::retrieveArgumentsFromVMCode):
(JSC::Interpreter::retrieveCallerFromVMCode):
(JSC::Interpreter::retrieveLastCaller):

  • interpreter/Interpreter.h:

(JSC::Interpreter::getOpcodeID):
(Interpreter):

  • jit/ExecutableAllocatorFixedVMPool.cpp:

(JSC::FixedVMPoolExecutableAllocator::FixedVMPoolExecutableAllocator):

  • offlineasm/asm.rb:
  • offlineasm/offsets.rb:
  • runtime/Executable.cpp:

(JSC::EvalExecutable::compileInternal):
(JSC::ProgramExecutable::compileInternal):
(JSC::FunctionExecutable::compileForCallInternal):
(JSC::FunctionExecutable::compileForConstructInternal):

  • runtime/Executable.h:

(JSC::NativeExecutable::create):
(NativeExecutable):
(JSC::NativeExecutable::finishCreation):

  • runtime/JSGlobalData.cpp:

(JSC):
(JSC::JSGlobalData::JSGlobalData):
(JSC::JSGlobalData::getHostFunction):

  • runtime/JSGlobalData.h:

(JSGlobalData):
(JSC::JSGlobalData::canUseJIT):
(JSC::JSGlobalData::canUseRegExpJIT):

  • runtime/Options.cpp:

(JSC::Options::initialize):

Source/WebKit/blackberry:

  • WebCoreSupport/AboutDataEnableFeatures.in:

Source/WTF:

  • wtf/OSAllocatorPosix.cpp:

(WTF::OSAllocator::reserveAndCommit):

  • wtf/Platform.h:
Location:
trunk/Source/JavaScriptCore/interpreter
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/interpreter/AbstractPC.cpp

    r127202 r129453  
    4646    }
    4747#endif
    48    
    49 #if ENABLE(CLASSIC_INTERPRETER)
    50     UNUSED_PARAM(globalData);
    51     m_pointer = exec->returnVPC();
    52     m_mode = Interpreter;
    53 #endif
    5448}
    5549
  • trunk/Source/JavaScriptCore/interpreter/AbstractPC.h

    r108020 r129453  
    6161#endif
    6262
    63 #if ENABLE(CLASSIC_INTERPRETER)
    64     AbstractPC(Instruction* vPC)
    65         : m_pointer(vPC)
    66         , m_mode(Interpreter)
    67     {
    68     }
    69    
    70     bool hasInterpreterReturnAddress() const { return m_mode == Interpreter; }
    71     Instruction* interpreterReturnAddress() const
    72     {
    73         ASSERT(hasInterpreterReturnAddress());
    74         return static_cast<Instruction*>(m_pointer);
    75     }
    76 #endif
    77    
    7863    bool isSet() const { return m_mode != None; }
    7964    bool operator!() const { return !isSet(); }
  • trunk/Source/JavaScriptCore/interpreter/CallFrame.h

    r128832 r129453  
    149149        }
    150150#endif
    151 #if ENABLE(CLASSIC_INTERPRETER)
    152         Instruction* returnVPC() const { return this[RegisterFile::ReturnPC].vPC(); }
    153 #endif
    154151#if USE(JSVALUE32_64)
    155152        Instruction* currentVPC() const
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r129432 r129453  
    7373#endif
    7474
    75 #define WTF_USE_GCC_COMPUTED_GOTO_WORKAROUND ((ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER) || ENABLE(LLINT)) && !defined(__llvm__))
     75#define WTF_USE_GCC_COMPUTED_GOTO_WORKAROUND (ENABLE(LLINT) && !defined(__llvm__))
    7676
    7777using namespace std;
     
    8888    return sc->localDepth();
    8989}
    90 
    91 #if ENABLE(CLASSIC_INTERPRETER)
    92 static NEVER_INLINE JSValue concatenateStrings(ExecState* exec, Register* strings, unsigned count)
    93 {
    94     return jsString(exec, strings, count);
    95 }
    96 
    97 #endif // ENABLE(CLASSIC_INTERPRETER)
    9890
    9991ALWAYS_INLINE CallFrame* Interpreter::slideRegisterWindowForCall(CodeBlock* newCodeBlock, RegisterFile* registerFile, CallFrame* callFrame, size_t registerOffset, int argumentCountIncludingThis)
     
    123115    return newCallFrame;
    124116}
    125 
    126 #if ENABLE(CLASSIC_INTERPRETER)
    127 static NEVER_INLINE bool isInvalidParamForIn(CallFrame* callFrame, JSValue value, JSValue& exceptionData)
    128 {
    129     if (value.isObject())
    130         return false;
    131     exceptionData = createInvalidParamError(callFrame, "in" , value);
    132     return true;
    133 }
    134 #endif
    135117
    136118JSValue eval(CallFrame* callFrame)
     
    269251    , m_initialized(false)
    270252#endif
    271     , m_classicEnabled(false)
    272253{
    273254}
     
    275256Interpreter::~Interpreter()
    276257{
    277 #if ENABLE(LLINT) && ENABLE(COMPUTED_GOTO_OPCODES)
    278     if (m_classicEnabled)
    279         delete[] m_opcodeTable;
    280 #endif
    281258}
    282259
     
    285262    UNUSED_PARAM(canUseJIT);
    286263
    287     // If we have LLInt, then we shouldn't be building any kind of classic interpreter.
    288 #if ENABLE(LLINT) && ENABLE(CLASSIC_INTERPRETER)
    289 #error "Building both LLInt and the Classic Interpreter is not supported because it doesn't make sense."
    290 #endif
    291 
    292 #if ENABLE(COMPUTED_GOTO_OPCODES)
    293 #if ENABLE(LLINT)
     264#if ENABLE(COMPUTED_GOTO_OPCODES) && ENABLE(LLINT)
    294265    m_opcodeTable = LLInt::opcodeMap();
    295266    for (int i = 0; i < numOpcodeIDs; ++i)
    296267        m_opcodeIDTable.add(m_opcodeTable[i], static_cast<OpcodeID>(i));
    297     m_classicEnabled = false;
    298 
    299 #elif ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
    300     if (canUseJIT) {
    301         // If the JIT is present, don't use jump destinations for opcodes.
    302         for (int i = 0; i < numOpcodeIDs; ++i) {
    303             Opcode opcode = bitwise_cast<void*>(static_cast<uintptr_t>(i));
    304             m_opcodeTable[i] = opcode;
    305         }
    306         m_classicEnabled = false;
    307     } else {
    308         privateExecute(InitializeAndReturn, 0, 0);
    309        
    310         for (int i = 0; i < numOpcodeIDs; ++i)
    311             m_opcodeIDTable.add(m_opcodeTable[i], static_cast<OpcodeID>(i));
    312        
    313         m_classicEnabled = true;
    314     }
    315 #endif // ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
    316 
    317 #else // !ENABLE(COMPUTED_GOTO_OPCODES)
    318 #if ENABLE(CLASSIC_INTERPRETER)
    319     m_classicEnabled = true;
    320 #else
    321     m_classicEnabled = false;
    322 #endif
    323 #endif // !ENABLE(COMPUTED_GOTO_OPCODES)
     268#endif
    324269
    325270#if !ASSERT_DISABLED
     
    435380#if ENABLE(COMPUTED_GOTO_OPCODES)
    436381#if !ENABLE(LLINT)
    437     if (!m_classicEnabled)
    438         return static_cast<OpcodeID>(bitwise_cast<uintptr_t>(opcode)) <= op_end;
    439 #endif
     382    return static_cast<OpcodeID>(bitwise_cast<uintptr_t>(opcode)) <= op_end;
     383#else
    440384    return opcode != HashTraits<Opcode>::emptyValue()
    441385        && !HashTraits<Opcode>::isDeletedValue(opcode)
    442386        && m_opcodeIDTable.contains(opcode);
     387#endif
    443388#else
    444389    return opcode >= 0 && opcode <= op_end;
     
    485430    // information the JIT reports the bytecodeOffset for the returnPC
    486431    // to be at the beginning of the opcode that has caused the call.
    487     // In the interpreter we have an actual return address, which is
    488     // the beginning of next instruction to execute. To get an offset
    489     // inside the call instruction that triggered the exception we
    490     // have to subtract 1.
    491 #if ENABLE(JIT) && ENABLE(CLASSIC_INTERPRETER)
    492     if (callerFrame->globalData().canUseJIT())
    493         bytecodeOffset = codeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
    494     else
    495         bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnVPC()) - 1;
    496 #elif ENABLE(JIT) || ENABLE(LLINT)
     432#if ENABLE(JIT) || ENABLE(LLINT)
    497433    bytecodeOffset = codeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
    498 #else
    499     bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnVPC()) - 1;
    500434#endif
    501435
     
    563497    if (!codeBlock)
    564498        return -1;
    565 #if ENABLE(CLASSIC_INTERPRETER)
    566     if (!globalData->canUseJIT())
    567         return codeBlock->lineNumberForBytecodeOffset(callFrame->bytecodeOffsetForNonDFGCode() - 1);
    568 #endif
    569499#if ENABLE(JIT) || ENABLE(LLINT)
    570500#if ENABLE(DFG_JIT)
     
    573503#endif
    574504    return codeBlock->lineNumberForBytecodeOffset(callFrame->bytecodeOffsetForNonDFGCode());
    575 #else
    576     return -1;
    577505#endif
    578506}
     
    605533        // Don't need to deal with inline callframes here as by definition we haven't
    606534        // inlined a call with an intervening native call frame.
    607 #if ENABLE(CLASSIC_INTERPRETER)
    608         if (!globalData->canUseJIT()) {
    609             bytecodeOffset = callerFrame->bytecodeOffsetForNonDFGCode();
    610             lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset - 1);
    611             return callerFrame;
    612         }
    613 #endif
    614535#if ENABLE(JIT) || ENABLE(LLINT)
    615536#if ENABLE(DFG_JIT)
     
    622543#endif
    623544    } else {
    624 #if ENABLE(CLASSIC_INTERPRETER)
    625         if (!globalData->canUseJIT()) {
    626             bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnVPC());
    627             lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset - 1);
    628             return callerFrame;
    629         }
    630 #endif
    631545#if ENABLE(JIT) || ENABLE(LLINT)
    632546    #if ENABLE(DFG_JIT)
     
    666580{
    667581    ASSERT(!callFrame->hasHostCallFrameFlag());
    668 #if ENABLE(CLASSIC_INTERPRETER)
    669 #if ENABLE(JIT)
    670     if (callFrame->globalData().canUseJIT())
    671         return callFrame->codeBlock()->ownerExecutable()->sourceURL();
    672 #endif
    673     return callFrame->codeBlock()->source()->url();
    674 
    675 #else
    676582    return callFrame->codeBlock()->ownerExecutable()->sourceURL();
    677 #endif
    678583}
    679584
     
    982887#if ENABLE(LLINT_C_LOOP)
    983888        result = LLInt::CLoop::execute(newCallFrame, llint_program_prologue);
    984 #else // !ENABLE(LLINT_C_LOOP)
    985 #if ENABLE(JIT)
    986         if (!classicEnabled())
    987             result = program->generatedJITCode().execute(&m_registerFile, newCallFrame, scope->globalData());
    988         else
     889#elif ENABLE(JIT)
     890        result = program->generatedJITCode().execute(&m_registerFile, newCallFrame, scope->globalData());
    989891#endif // ENABLE(JIT)
    990             result = privateExecute(Normal, &m_registerFile, newCallFrame);
    991 #endif // !ENABLE(LLINT_C_LOOP)
    992892
    993893        m_reentryDepth--;
     
    1058958#if ENABLE(LLINT_C_LOOP)
    1059959            result = LLInt::CLoop::execute(newCallFrame, llint_function_for_call_prologue);
    1060 #else // ENABLE(LLINT_C_LOOP)
    1061 #if ENABLE(JIT)
    1062             if (!classicEnabled())
    1063                 result = callData.js.functionExecutable->generatedJITCodeForCall().execute(&m_registerFile, newCallFrame, callDataScope->globalData());
    1064             else
     960#elif ENABLE(JIT)
     961            result = callData.js.functionExecutable->generatedJITCodeForCall().execute(&m_registerFile, newCallFrame, callDataScope->globalData());
    1065962#endif // ENABLE(JIT)
    1066                 result = privateExecute(Normal, &m_registerFile, newCallFrame);
    1067 #endif // !ENABLE(LLINT_C_LOOP)
    1068963
    1069964            m_reentryDepth--;
     
    11571052#if ENABLE(LLINT_C_LOOP)
    11581053            result = LLInt::CLoop::execute(newCallFrame, llint_function_for_construct_prologue);
    1159 #else // !ENABLE(LLINT_C_LOOP)
    1160 #if ENABLE(JIT)
    1161             if (!classicEnabled())
    1162                 result = constructData.js.functionExecutable->generatedJITCodeForConstruct().execute(&m_registerFile, newCallFrame, constructDataScope->globalData());
    1163             else
     1054#elif ENABLE(JIT)
     1055            result = constructData.js.functionExecutable->generatedJITCodeForConstruct().execute(&m_registerFile, newCallFrame, constructDataScope->globalData());
    11641056#endif // ENABLE(JIT)
    1165                 result = privateExecute(Normal, &m_registerFile, newCallFrame);
    1166 #endif // !ENABLE(LLINT_C_LOOP)
    11671057            m_reentryDepth--;
    11681058        }
     
    12641154#if ENABLE(LLINT_C_LOOP)
    12651155        result = LLInt::CLoop::execute(closure.newCallFrame, llint_function_for_call_prologue);
    1266 #else // !ENABLE(LLINT_C_LOOP)
    1267 #if ENABLE(JIT)
    1268 #if ENABLE(CLASSIC_INTERPRETER)
    1269         if (closure.newCallFrame->globalData().canUseJIT())
    1270 #endif
    1271             result = closure.functionExecutable->generatedJITCodeForCall().execute(&m_registerFile, closure.newCallFrame, closure.globalData);
    1272 #if ENABLE(CLASSIC_INTERPRETER)
    1273         else
    1274 #endif
     1156#elif ENABLE(JIT)
     1157        result = closure.functionExecutable->generatedJITCodeForCall().execute(&m_registerFile, closure.newCallFrame, closure.globalData);
    12751158#endif // ENABLE(JIT)
    1276 #if ENABLE(CLASSIC_INTERPRETER)
    1277             result = privateExecute(Normal, &m_registerFile, closure.newCallFrame);
    1278 #endif
    1279 #endif // !ENABLE(LLINT_C_LOOP)
    1280 
    12811159        m_reentryDepth--;
    12821160    }
     
    13691247#if ENABLE(LLINT_C_LOOP)
    13701248        result = LLInt::CLoop::execute(newCallFrame, llint_eval_prologue);
    1371 #else // !ENABLE(LLINT_C_LOOP)
    1372 #if ENABLE(JIT)
    1373 #if ENABLE(CLASSIC_INTERPRETER)
    1374         if (callFrame->globalData().canUseJIT())
    1375 #endif
    1376             result = eval->generatedJITCode().execute(&m_registerFile, newCallFrame, scope->globalData());
    1377 #if ENABLE(CLASSIC_INTERPRETER)
    1378         else
    1379 #endif
     1249#elif ENABLE(JIT)
     1250        result = eval->generatedJITCode().execute(&m_registerFile, newCallFrame, scope->globalData());
    13801251#endif // ENABLE(JIT)
    1381 #if ENABLE(CLASSIC_INTERPRETER)
    1382             result = privateExecute(Normal, &m_registerFile, newCallFrame);
    1383 #endif
    1384 #endif // !ENABLE(LLINT_C_LOOP)
    13851252        m_reentryDepth--;
    13861253    }
     
    14211288}
    14221289   
    1423 #if ENABLE(CLASSIC_INTERPRETER)
    1424 NEVER_INLINE JSScope* Interpreter::createNameScope(CallFrame* callFrame, const Instruction* vPC)
    1425 {
    1426     CodeBlock* codeBlock = callFrame->codeBlock();
    1427     Identifier& property = codeBlock->identifier(vPC[1].u.operand);
    1428     JSValue value = callFrame->r(vPC[2].u.operand).jsValue();
    1429     unsigned attributes = vPC[3].u.operand;
    1430     JSNameScope* scope = JSNameScope::create(callFrame, property, value, attributes);
    1431     return scope;
    1432 }
    1433 
    1434 NEVER_INLINE void Interpreter::tryCachePutByID(CallFrame* callFrame, CodeBlock* codeBlock, Instruction* vPC, JSValue baseValue, const PutPropertySlot& slot)
    1435 {
    1436     // Recursive invocation may already have specialized this instruction.
    1437     if (vPC[0].u.opcode != getOpcode(op_put_by_id))
    1438         return;
    1439 
    1440     if (!baseValue.isCell())
    1441         return;
    1442 
    1443     // Uncacheable: give up.
    1444     if (!slot.isCacheable()) {
    1445         vPC[0] = getOpcode(op_put_by_id_generic);
    1446         return;
    1447     }
    1448    
    1449     JSCell* baseCell = baseValue.asCell();
    1450     Structure* structure = baseCell->structure();
    1451 
    1452     if (structure->isUncacheableDictionary() || structure->typeInfo().prohibitsPropertyCaching()) {
    1453         vPC[0] = getOpcode(op_put_by_id_generic);
    1454         return;
    1455     }
    1456 
    1457     // Cache miss: record Structure to compare against next time.
    1458     Structure* lastStructure = vPC[4].u.structure.get();
    1459     if (structure != lastStructure) {
    1460         // First miss: record Structure to compare against next time.
    1461         if (!lastStructure) {
    1462             vPC[4].u.structure.set(callFrame->globalData(), codeBlock->ownerExecutable(), structure);
    1463             return;
    1464         }
    1465 
    1466         // Second miss: give up.
    1467         vPC[0] = getOpcode(op_put_by_id_generic);
    1468         return;
    1469     }
    1470 
    1471     // Cache hit: Specialize instruction and ref Structures.
    1472 
    1473     // If baseCell != slot.base(), then baseCell must be a proxy for another object.
    1474     if (baseCell != slot.base()) {
    1475         vPC[0] = getOpcode(op_put_by_id_generic);
    1476         return;
    1477     }
    1478 
    1479     // Structure transition, cache transition info
    1480     if (slot.type() == PutPropertySlot::NewProperty) {
    1481         if (structure->isDictionary()) {
    1482             vPC[0] = getOpcode(op_put_by_id_generic);
    1483             return;
    1484         }
    1485 
    1486         // put_by_id_transition checks the prototype chain for setters.
    1487         normalizePrototypeChain(callFrame, baseCell);
    1488         JSCell* owner = codeBlock->ownerExecutable();
    1489         JSGlobalData& globalData = callFrame->globalData();
    1490         // Get the prototype here because the call to prototypeChain could cause a
    1491         // GC allocation, which we don't want to happen while we're in the middle of
    1492         // initializing the union.
    1493         StructureChain* prototypeChain = structure->prototypeChain(callFrame);
    1494         vPC[0] = getOpcode(op_put_by_id_transition);
    1495         vPC[4].u.structure.set(globalData, owner, structure->previousID());
    1496         vPC[5].u.structure.set(globalData, owner, structure);
    1497         vPC[6].u.structureChain.set(callFrame->globalData(), codeBlock->ownerExecutable(), prototypeChain);
    1498         ASSERT(vPC[6].u.structureChain);
    1499         vPC[7] = slot.cachedOffset();
    1500         return;
    1501     }
    1502 
    1503     vPC[0] = getOpcode(op_put_by_id_replace);
    1504     vPC[5] = slot.cachedOffset();
    1505 }
    1506 
    1507 NEVER_INLINE void Interpreter::uncachePutByID(CodeBlock*, Instruction* vPC)
    1508 {
    1509     vPC[0] = getOpcode(op_put_by_id);
    1510     vPC[4] = 0;
    1511 }
    1512 
    1513 NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock* codeBlock, Instruction* vPC, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot)
    1514 {
    1515     // Recursive invocation may already have specialized this instruction.
    1516     if (vPC[0].u.opcode != getOpcode(op_get_by_id))
    1517         return;
    1518 
    1519     // FIXME: Cache property access for immediates.
    1520     if (!baseValue.isCell()) {
    1521         vPC[0] = getOpcode(op_get_by_id_generic);
    1522         return;
    1523     }
    1524 
    1525     if (isJSArray(baseValue) && propertyName == callFrame->propertyNames().length) {
    1526         vPC[0] = getOpcode(op_get_array_length);
    1527         return;
    1528     }
    1529 
    1530     if (isJSString(baseValue) && propertyName == callFrame->propertyNames().length) {
    1531         vPC[0] = getOpcode(op_get_string_length);
    1532         return;
    1533     }
    1534 
    1535     // Uncacheable: give up.
    1536     if (!slot.isCacheable()) {
    1537         vPC[0] = getOpcode(op_get_by_id_generic);
    1538         return;
    1539     }
    1540 
    1541     Structure* structure = baseValue.asCell()->structure();
    1542 
    1543     if (structure->isUncacheableDictionary() || structure->typeInfo().prohibitsPropertyCaching()) {
    1544         vPC[0] = getOpcode(op_get_by_id_generic);
    1545         return;
    1546     }
    1547 
    1548     // Cache miss
    1549     Structure* lastStructure = vPC[4].u.structure.get();
    1550     if (structure != lastStructure) {
    1551         // First miss: record Structure to compare against next time.
    1552         if (!lastStructure) {
    1553             vPC[4].u.structure.set(callFrame->globalData(), codeBlock->ownerExecutable(), structure);
    1554             return;
    1555         }
    1556 
    1557         // Second miss: give up.
    1558         vPC[0] = getOpcode(op_get_by_id_generic);
    1559         return;
    1560     }
    1561 
    1562     // Cache hit: Specialize instruction and ref Structures.
    1563 
    1564     if (slot.slotBase() == baseValue) {
    1565         switch (slot.cachedPropertyType()) {
    1566         case PropertySlot::Getter:
    1567             vPC[0] = getOpcode(op_get_by_id_getter_self);
    1568             vPC[5] = slot.cachedOffset();
    1569             break;
    1570         case PropertySlot::Custom:
    1571             vPC[0] = getOpcode(op_get_by_id_custom_self);
    1572             vPC[5] = slot.customGetter();
    1573             break;
    1574         default:
    1575             vPC[0] = getOpcode(op_get_by_id_self);
    1576             vPC[5] = slot.cachedOffset();
    1577             break;
    1578         }
    1579         return;
    1580     }
    1581 
    1582     if (structure->isDictionary()) {
    1583         vPC[0] = getOpcode(op_get_by_id_generic);
    1584         return;
    1585     }
    1586 
    1587     if (slot.slotBase() == structure->prototypeForLookup(callFrame)) {
    1588         ASSERT(slot.slotBase().isObject());
    1589 
    1590         JSObject* baseObject = asObject(slot.slotBase());
    1591         PropertyOffset offset = slot.cachedOffset();
    1592 
    1593         // Since we're accessing a prototype in a loop, it's a good bet that it
    1594         // should not be treated as a dictionary.
    1595         if (baseObject->structure()->isDictionary()) {
    1596             baseObject->flattenDictionaryObject(callFrame->globalData());
    1597             offset = baseObject->structure()->get(callFrame->globalData(), propertyName);
    1598         }
    1599 
    1600         ASSERT(!baseObject->structure()->isUncacheableDictionary());
    1601        
    1602         switch (slot.cachedPropertyType()) {
    1603         case PropertySlot::Getter:
    1604             vPC[0] = getOpcode(op_get_by_id_getter_proto);
    1605             vPC[6] = offset;
    1606             break;
    1607         case PropertySlot::Custom:
    1608             vPC[0] = getOpcode(op_get_by_id_custom_proto);
    1609             vPC[6] = slot.customGetter();
    1610             break;
    1611         default:
    1612             vPC[0] = getOpcode(op_get_by_id_proto);
    1613             vPC[6] = offset;
    1614             break;
    1615         }
    1616         vPC[5].u.structure.set(callFrame->globalData(), codeBlock->ownerExecutable(), baseObject->structure());
    1617         return;
    1618     }
    1619 
    1620     PropertyOffset offset = slot.cachedOffset();
    1621     size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset);
    1622     if (!count) {
    1623         vPC[0] = getOpcode(op_get_by_id_generic);
    1624         return;
    1625     }
    1626 
    1627    
    1628     StructureChain* prototypeChain = structure->prototypeChain(callFrame);
    1629     switch (slot.cachedPropertyType()) {
    1630     case PropertySlot::Getter:
    1631         vPC[0] = getOpcode(op_get_by_id_getter_chain);
    1632         vPC[7] = offset;
    1633         break;
    1634     case PropertySlot::Custom:
    1635         vPC[0] = getOpcode(op_get_by_id_custom_chain);
    1636         vPC[7] = slot.customGetter();
    1637         break;
    1638     default:
    1639         vPC[0] = getOpcode(op_get_by_id_chain);
    1640         vPC[7] = offset;
    1641         break;
    1642     }
    1643     vPC[4].u.structure.set(callFrame->globalData(), codeBlock->ownerExecutable(), structure);
    1644     vPC[5].u.structureChain.set(callFrame->globalData(), codeBlock->ownerExecutable(), prototypeChain);
    1645     vPC[6] = count;
    1646 }
    1647 
    1648 NEVER_INLINE void Interpreter::uncacheGetByID(CodeBlock*, Instruction* vPC)
    1649 {
    1650     vPC[0] = getOpcode(op_get_by_id);
    1651     vPC[4] = 0;
    1652 }
    1653 
    1654 #endif // ENABLE(CLASSIC_INTERPRETER)
    1655 
    1656 #if !ENABLE(LLINT_C_LOOP)
    1657 
    1658 JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFile, CallFrame* callFrame)
    1659 {
    1660     // One-time initialization of our address tables. We have to put this code
    1661     // here because our labels are only in scope inside this function.
    1662     if (UNLIKELY(flag == InitializeAndReturn)) {
    1663         #if ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
    1664             #define LIST_OPCODE_LABEL(id, length) &&id,
    1665                 static Opcode labels[] = { FOR_EACH_OPCODE_ID(LIST_OPCODE_LABEL) };
    1666                 for (size_t i = 0; i < WTF_ARRAY_LENGTH(labels); ++i)
    1667                     m_opcodeTable[i] = labels[i];
    1668             #undef LIST_OPCODE_LABEL
    1669         #endif // ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
    1670         return JSValue();
    1671     }
    1672    
    1673     ASSERT(m_initialized);
    1674     ASSERT(m_classicEnabled);
    1675    
    1676 #if ENABLE(JIT)
    1677 #if ENABLE(CLASSIC_INTERPRETER)
    1678     // Mixing Interpreter + JIT is not supported.
    1679     if (callFrame->globalData().canUseJIT())
    1680 #endif
    1681         ASSERT_NOT_REACHED();
    1682 #endif
    1683 
    1684 #if !ENABLE(CLASSIC_INTERPRETER)
    1685     UNUSED_PARAM(registerFile);
    1686     UNUSED_PARAM(callFrame);
    1687     return JSValue();
    1688 #else
    1689 
    1690     ASSERT(callFrame->globalData().topCallFrame == callFrame);
    1691 
    1692     JSGlobalData* globalData = &callFrame->globalData();
    1693     JSValue exceptionValue;
    1694     HandlerInfo* handler = 0;
    1695     CallFrame** topCallFrameSlot = &globalData->topCallFrame;
    1696 
    1697     CodeBlock* codeBlock = callFrame->codeBlock();
    1698     Instruction* vPC = codeBlock->instructions().begin();
    1699     unsigned tickCount = globalData->timeoutChecker.ticksUntilNextCheck();
    1700     JSValue functionReturnValue;
    1701 
    1702 #define CHECK_FOR_EXCEPTION() \
    1703     do { \
    1704         if (UNLIKELY(globalData->exception != JSValue())) { \
    1705             exceptionValue = globalData->exception; \
    1706             goto vm_throw; \
    1707         } \
    1708     } while (0)
    1709 
    1710 #if ENABLE(OPCODE_STATS)
    1711     OpcodeStats::resetLastInstruction();
    1712 #endif
    1713 
    1714 #define CHECK_FOR_TIMEOUT() \
    1715     if (!--tickCount) { \
    1716         if (globalData->terminator.shouldTerminate() || globalData->timeoutChecker.didTimeOut(callFrame)) { \
    1717             exceptionValue = jsNull(); \
    1718             goto vm_throw; \
    1719         } \
    1720         tickCount = globalData->timeoutChecker.ticksUntilNextCheck(); \
    1721     }
    1722    
    1723 #if ENABLE(OPCODE_SAMPLING)
    1724     #define SAMPLE(codeBlock, vPC) m_sampler->sample(codeBlock, vPC)
    1725 #else
    1726     #define SAMPLE(codeBlock, vPC)
    1727 #endif
    1728 
    1729 #define UPDATE_BYTECODE_OFFSET() \
    1730     do {\
    1731         callFrame->setBytecodeOffsetForNonDFGCode(vPC - codeBlock->instructions().data() + 1);\
    1732     } while (0)
    1733 
    1734 #if ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
    1735     #define NEXT_INSTRUCTION() SAMPLE(codeBlock, vPC); goto *vPC->u.opcode
    1736 #if ENABLE(OPCODE_STATS)
    1737     #define DEFINE_OPCODE(opcode) \
    1738         opcode:\
    1739             OpcodeStats::recordInstruction(opcode);\
    1740             UPDATE_BYTECODE_OFFSET();
    1741 #else
    1742     #define DEFINE_OPCODE(opcode) opcode: UPDATE_BYTECODE_OFFSET();
    1743 #endif // !ENABLE(OPCODE_STATS)
    1744     NEXT_INSTRUCTION();
    1745 #else // !ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
    1746     #define NEXT_INSTRUCTION() SAMPLE(codeBlock, vPC); goto interpreterLoopStart
    1747 #if ENABLE(OPCODE_STATS)
    1748     #define DEFINE_OPCODE(opcode) \
    1749         case opcode:\
    1750             OpcodeStats::recordInstruction(opcode);\
    1751             UPDATE_BYTECODE_OFFSET();
    1752 #else
    1753     #define DEFINE_OPCODE(opcode) case opcode: UPDATE_BYTECODE_OFFSET();
    1754 #endif
    1755     while (1) { // iterator loop begins
    1756     interpreterLoopStart:;
    1757     switch (vPC->u.opcode)
    1758 #endif // !ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
    1759     {
    1760     DEFINE_OPCODE(op_new_object) {
    1761         /* new_object dst(r)
    1762 
    1763            Constructs a new empty Object instance using the original
    1764            constructor, and puts the result in register dst.
    1765         */
    1766         int dst = vPC[1].u.operand;
    1767         callFrame->uncheckedR(dst) = JSValue(constructEmptyObject(callFrame));
    1768 
    1769         vPC += OPCODE_LENGTH(op_new_object);
    1770         NEXT_INSTRUCTION();
    1771     }
    1772     DEFINE_OPCODE(op_new_array) {
    1773         /* new_array dst(r) firstArg(r) argCount(n)
    1774 
    1775            Constructs a new Array instance using the original
    1776            constructor, and puts the result in register dst.
    1777            The array will contain argCount elements with values
    1778            taken from registers starting at register firstArg.
    1779         */
    1780         int dst = vPC[1].u.operand;
    1781         int firstArg = vPC[2].u.operand;
    1782         int argCount = vPC[3].u.operand;
    1783         callFrame->uncheckedR(dst) = JSValue(constructArray(callFrame, reinterpret_cast<JSValue*>(&callFrame->registers()[firstArg]), argCount));
    1784 
    1785         vPC += OPCODE_LENGTH(op_new_array);
    1786         NEXT_INSTRUCTION();
    1787     }
    1788     DEFINE_OPCODE(op_new_array_buffer) {
    1789         /* new_array_buffer dst(r) index(n) argCount(n)
    1790          
    1791          Constructs a new Array instance using the original
    1792          constructor, and puts the result in register dst.
    1793          The array be initialized with the values from constantBuffer[index]
    1794          */
    1795         int dst = vPC[1].u.operand;
    1796         int firstArg = vPC[2].u.operand;
    1797         int argCount = vPC[3].u.operand;
    1798         callFrame->uncheckedR(dst) = JSValue(constructArray(callFrame, codeBlock->constantBuffer(firstArg), argCount));
    1799        
    1800         vPC += OPCODE_LENGTH(op_new_array);
    1801         NEXT_INSTRUCTION();
    1802     }
    1803     DEFINE_OPCODE(op_new_regexp) {
    1804         /* new_regexp dst(r) regExp(re)
    1805 
    1806            Constructs a new RegExp instance using the original
    1807            constructor from regexp regExp, and puts the result in
    1808            register dst.
    1809         */
    1810         int dst = vPC[1].u.operand;
    1811         RegExp* regExp = codeBlock->regexp(vPC[2].u.operand);
    1812         if (!regExp->isValid()) {
    1813             exceptionValue = createSyntaxError(callFrame, "Invalid flags supplied to RegExp constructor.");
    1814             goto vm_throw;
    1815         }
    1816         callFrame->uncheckedR(dst) = JSValue(RegExpObject::create(*globalData, callFrame->lexicalGlobalObject(), callFrame->scope()->globalObject()->regExpStructure(), regExp));
    1817 
    1818         vPC += OPCODE_LENGTH(op_new_regexp);
    1819         NEXT_INSTRUCTION();
    1820     }
    1821     DEFINE_OPCODE(op_mov) {
    1822         /* mov dst(r) src(r)
    1823 
    1824            Copies register src to register dst.
    1825         */
    1826         int dst = vPC[1].u.operand;
    1827         int src = vPC[2].u.operand;
    1828        
    1829         callFrame->uncheckedR(dst) = callFrame->r(src);
    1830 
    1831         vPC += OPCODE_LENGTH(op_mov);
    1832         NEXT_INSTRUCTION();
    1833     }
    1834     DEFINE_OPCODE(op_eq) {
    1835         /* eq dst(r) src1(r) src2(r)
    1836 
    1837            Checks whether register src1 and register src2 are equal,
    1838            as with the ECMAScript '==' operator, and puts the result
    1839            as a boolean in register dst.
    1840         */
    1841         int dst = vPC[1].u.operand;
    1842         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
    1843         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
    1844         if (src1.isInt32() && src2.isInt32())
    1845             callFrame->uncheckedR(dst) = jsBoolean(src1.asInt32() == src2.asInt32());
    1846         else {
    1847             JSValue result = jsBoolean(JSValue::equalSlowCase(callFrame, src1, src2));
    1848             CHECK_FOR_EXCEPTION();
    1849             callFrame->uncheckedR(dst) = result;
    1850         }
    1851 
    1852         vPC += OPCODE_LENGTH(op_eq);
    1853         NEXT_INSTRUCTION();
    1854     }
    1855     DEFINE_OPCODE(op_eq_null) {
    1856         /* eq_null dst(r) src(r)
    1857 
    1858            Checks whether register src is null, as with the ECMAScript '!='
    1859            operator, and puts the result as a boolean in register dst.
    1860         */
    1861         int dst = vPC[1].u.operand;
    1862         JSValue src = callFrame->r(vPC[2].u.operand).jsValue();
    1863 
    1864         if (src.isUndefinedOrNull()) {
    1865             callFrame->uncheckedR(dst) = jsBoolean(true);
    1866             vPC += OPCODE_LENGTH(op_eq_null);
    1867             NEXT_INSTRUCTION();
    1868         }
    1869        
    1870         callFrame->uncheckedR(dst) = jsBoolean(src.isCell() && src.asCell()->structure()->masqueradesAsUndefined(callFrame->lexicalGlobalObject()));
    1871         vPC += OPCODE_LENGTH(op_eq_null);
    1872         NEXT_INSTRUCTION();
    1873     }
    1874     DEFINE_OPCODE(op_neq) {
    1875         /* neq dst(r) src1(r) src2(r)
    1876 
    1877            Checks whether register src1 and register src2 are not
    1878            equal, as with the ECMAScript '!=' operator, and puts the
    1879            result as a boolean in register dst.
    1880         */
    1881         int dst = vPC[1].u.operand;
    1882         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
    1883         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
    1884         if (src1.isInt32() && src2.isInt32())
    1885             callFrame->uncheckedR(dst) = jsBoolean(src1.asInt32() != src2.asInt32());
    1886         else {
    1887             JSValue result = jsBoolean(!JSValue::equalSlowCase(callFrame, src1, src2));
    1888             CHECK_FOR_EXCEPTION();
    1889             callFrame->uncheckedR(dst) = result;
    1890         }
    1891 
    1892         vPC += OPCODE_LENGTH(op_neq);
    1893         NEXT_INSTRUCTION();
    1894     }
    1895     DEFINE_OPCODE(op_neq_null) {
    1896         /* neq_null dst(r) src(r)
    1897 
    1898            Checks whether register src is not null, as with the ECMAScript '!='
    1899            operator, and puts the result as a boolean in register dst.
    1900         */
    1901         int dst = vPC[1].u.operand;
    1902         JSValue src = callFrame->r(vPC[2].u.operand).jsValue();
    1903 
    1904         if (src.isUndefinedOrNull()) {
    1905             callFrame->uncheckedR(dst) = jsBoolean(false);
    1906             vPC += OPCODE_LENGTH(op_neq_null);
    1907             NEXT_INSTRUCTION();
    1908         }
    1909        
    1910         callFrame->uncheckedR(dst) = jsBoolean(!src.isCell() || !src.asCell()->structure()->masqueradesAsUndefined(callFrame->lexicalGlobalObject()));
    1911         vPC += OPCODE_LENGTH(op_neq_null);
    1912         NEXT_INSTRUCTION();
    1913     }
    1914     DEFINE_OPCODE(op_stricteq) {
    1915         /* stricteq dst(r) src1(r) src2(r)
    1916 
    1917            Checks whether register src1 and register src2 are strictly
    1918            equal, as with the ECMAScript '===' operator, and puts the
    1919            result as a boolean in register dst.
    1920         */
    1921         int dst = vPC[1].u.operand;
    1922         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
    1923         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
    1924         bool result = JSValue::strictEqual(callFrame, src1, src2);
    1925         CHECK_FOR_EXCEPTION();
    1926         callFrame->uncheckedR(dst) = jsBoolean(result);
    1927 
    1928         vPC += OPCODE_LENGTH(op_stricteq);
    1929         NEXT_INSTRUCTION();
    1930     }
    1931     DEFINE_OPCODE(op_nstricteq) {
    1932         /* nstricteq dst(r) src1(r) src2(r)
    1933 
    1934            Checks whether register src1 and register src2 are not
    1935            strictly equal, as with the ECMAScript '!==' operator, and
    1936            puts the result as a boolean in register dst.
    1937         */
    1938         int dst = vPC[1].u.operand;
    1939         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
    1940         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
    1941         bool result = !JSValue::strictEqual(callFrame, src1, src2);
    1942         CHECK_FOR_EXCEPTION();
    1943         callFrame->uncheckedR(dst) = jsBoolean(result);
    1944 
    1945         vPC += OPCODE_LENGTH(op_nstricteq);
    1946         NEXT_INSTRUCTION();
    1947     }
    1948     DEFINE_OPCODE(op_less) {
    1949         /* less dst(r) src1(r) src2(r)
    1950 
    1951            Checks whether register src1 is less than register src2, as
    1952            with the ECMAScript '<' operator, and puts the result as
    1953            a boolean in register dst.
    1954         */
    1955         int dst = vPC[1].u.operand;
    1956         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
    1957         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
    1958         JSValue result = jsBoolean(jsLess<true>(callFrame, src1, src2));
    1959         CHECK_FOR_EXCEPTION();
    1960         callFrame->uncheckedR(dst) = result;
    1961 
    1962         vPC += OPCODE_LENGTH(op_less);
    1963         NEXT_INSTRUCTION();
    1964     }
    1965     DEFINE_OPCODE(op_lesseq) {
    1966         /* lesseq dst(r) src1(r) src2(r)
    1967 
    1968            Checks whether register src1 is less than or equal to
    1969            register src2, as with the ECMAScript '<=' operator, and
    1970            puts the result as a boolean in register dst.
    1971         */
    1972         int dst = vPC[1].u.operand;
    1973         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
    1974         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
    1975         JSValue result = jsBoolean(jsLessEq<true>(callFrame, src1, src2));
    1976         CHECK_FOR_EXCEPTION();
    1977         callFrame->uncheckedR(dst) = result;
    1978 
    1979         vPC += OPCODE_LENGTH(op_lesseq);
    1980         NEXT_INSTRUCTION();
    1981     }
    1982     DEFINE_OPCODE(op_greater) {
    1983         /* greater dst(r) src1(r) src2(r)
    1984 
    1985            Checks whether register src1 is greater than register src2, as
    1986            with the ECMAScript '>' operator, and puts the result as
    1987            a boolean in register dst.
    1988         */
    1989         int dst = vPC[1].u.operand;
    1990         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
    1991         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
    1992         JSValue result = jsBoolean(jsLess<false>(callFrame, src2, src1));
    1993         CHECK_FOR_EXCEPTION();
    1994         callFrame->uncheckedR(dst) = result;
    1995 
    1996         vPC += OPCODE_LENGTH(op_greater);
    1997         NEXT_INSTRUCTION();
    1998     }
    1999     DEFINE_OPCODE(op_greatereq) {
    2000         /* greatereq dst(r) src1(r) src2(r)
    2001 
    2002            Checks whether register src1 is greater than or equal to
    2003            register src2, as with the ECMAScript '>=' operator, and
    2004            puts the result as a boolean in register dst.
    2005         */
    2006         int dst = vPC[1].u.operand;
    2007         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
    2008         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
    2009         JSValue result = jsBoolean(jsLessEq<false>(callFrame, src2, src1));
    2010         CHECK_FOR_EXCEPTION();
    2011         callFrame->uncheckedR(dst) = result;
    2012 
    2013         vPC += OPCODE_LENGTH(op_greatereq);
    2014         NEXT_INSTRUCTION();
    2015     }
    2016     DEFINE_OPCODE(op_pre_inc) {
    2017         /* pre_inc srcDst(r)
    2018 
    2019            Converts register srcDst to number, adds one, and puts the result
    2020            back in register srcDst.
    2021         */
    2022         int srcDst = vPC[1].u.operand;
    2023         JSValue v = callFrame->r(srcDst).jsValue();
    2024         if (v.isInt32() && v.asInt32() < INT_MAX)
    2025             callFrame->uncheckedR(srcDst) = jsNumber(v.asInt32() + 1);
    2026         else {
    2027             JSValue result = jsNumber(v.toNumber(callFrame) + 1);
    2028             CHECK_FOR_EXCEPTION();
    2029             callFrame->uncheckedR(srcDst) = result;
    2030         }
    2031 
    2032         vPC += OPCODE_LENGTH(op_pre_inc);
    2033         NEXT_INSTRUCTION();
    2034     }
    2035     DEFINE_OPCODE(op_pre_dec) {
    2036         /* pre_dec srcDst(r)
    2037 
    2038            Converts register srcDst to number, subtracts one, and puts the result
    2039            back in register srcDst.
    2040         */
    2041         int srcDst = vPC[1].u.operand;
    2042         JSValue v = callFrame->r(srcDst).jsValue();
    2043         if (v.isInt32() && v.asInt32() > INT_MIN)
    2044             callFrame->uncheckedR(srcDst) = jsNumber(v.asInt32() - 1);
    2045         else {
    2046             JSValue result = jsNumber(v.toNumber(callFrame) - 1);
    2047             CHECK_FOR_EXCEPTION();
    2048             callFrame->uncheckedR(srcDst) = result;
    2049         }
    2050 
    2051         vPC += OPCODE_LENGTH(op_pre_dec);
    2052         NEXT_INSTRUCTION();
    2053     }
    2054     DEFINE_OPCODE(op_post_inc) {
    2055         /* post_inc dst(r) srcDst(r)
    2056 
    2057            Converts register srcDst to number. The number itself is
    2058            written to register dst, and the number plus one is written
    2059            back to register srcDst.
    2060         */
    2061         int dst = vPC[1].u.operand;
    2062         int srcDst = vPC[2].u.operand;
    2063         JSValue v = callFrame->r(srcDst).jsValue();
    2064         if (v.isInt32() && v.asInt32() < INT_MAX) {
    2065             callFrame->uncheckedR(srcDst) = jsNumber(v.asInt32() + 1);
    2066             callFrame->uncheckedR(dst) = v;
    2067         } else {
    2068             double number = callFrame->r(srcDst).jsValue().toNumber(callFrame);
    2069             CHECK_FOR_EXCEPTION();
    2070             callFrame->uncheckedR(srcDst) = jsNumber(number + 1);
    2071             callFrame->uncheckedR(dst) = jsNumber(number);
    2072         }
    2073 
    2074         vPC += OPCODE_LENGTH(op_post_inc);
    2075         NEXT_INSTRUCTION();
    2076     }
    2077     DEFINE_OPCODE(op_post_dec) {
    2078         /* post_dec dst(r) srcDst(r)
    2079 
    2080            Converts register srcDst to number. The number itself is
    2081            written to register dst, and the number minus one is written
    2082            back to register srcDst.
    2083         */
    2084         int dst = vPC[1].u.operand;
    2085         int srcDst = vPC[2].u.operand;
    2086         JSValue v = callFrame->r(srcDst).jsValue();
    2087         if (v.isInt32() && v.asInt32() > INT_MIN) {
    2088             callFrame->uncheckedR(srcDst) = jsNumber(v.asInt32() - 1);
    2089             callFrame->uncheckedR(dst) = v;
    2090         } else {
    2091             double number = callFrame->r(srcDst).jsValue().toNumber(callFrame);
    2092             CHECK_FOR_EXCEPTION();
    2093             callFrame->uncheckedR(srcDst) = jsNumber(number - 1);
    2094             callFrame->uncheckedR(dst) = jsNumber(number);
    2095         }
    2096 
    2097         vPC += OPCODE_LENGTH(op_post_dec);
    2098         NEXT_INSTRUCTION();
    2099     }
    2100     DEFINE_OPCODE(op_to_jsnumber) {
    2101         /* to_jsnumber dst(r) src(r)
    2102 
    2103            Converts register src to number, and puts the result
    2104            in register dst.
    2105         */
    2106         int dst = vPC[1].u.operand;
    2107         int src = vPC[2].u.operand;
    2108 
    2109         JSValue srcVal = callFrame->r(src).jsValue();
    2110 
    2111         if (LIKELY(srcVal.isNumber()))
    2112             callFrame->uncheckedR(dst) = callFrame->r(src);
    2113         else {
    2114             double number = srcVal.toNumber(callFrame);
    2115             CHECK_FOR_EXCEPTION();
    2116             callFrame->uncheckedR(dst) = jsNumber(number);
    2117         }
    2118 
    2119         vPC += OPCODE_LENGTH(op_to_jsnumber);
    2120         NEXT_INSTRUCTION();
    2121     }
    2122     DEFINE_OPCODE(op_negate) {
    2123         /* negate dst(r) src(r)
    2124 
    2125            Converts register src to number, negates it, and puts the
    2126            result in register dst.
    2127         */
    2128         int dst = vPC[1].u.operand;
    2129         JSValue src = callFrame->r(vPC[2].u.operand).jsValue();
    2130         if (src.isInt32() && (src.asInt32() & 0x7fffffff)) // non-zero and no overflow
    2131             callFrame->uncheckedR(dst) = jsNumber(-src.asInt32());
    2132         else {
    2133             JSValue result = jsNumber(-src.toNumber(callFrame));
    2134             CHECK_FOR_EXCEPTION();
    2135             callFrame->uncheckedR(dst) = result;
    2136         }
    2137 
    2138         vPC += OPCODE_LENGTH(op_negate);
    2139         NEXT_INSTRUCTION();
    2140     }
    2141     DEFINE_OPCODE(op_add) {
    2142         /* add dst(r) src1(r) src2(r)
    2143 
    2144            Adds register src1 and register src2, and puts the result
    2145            in register dst. (JS add may be string concatenation or
    2146            numeric add, depending on the types of the operands.)
    2147         */
    2148         int dst = vPC[1].u.operand;
    2149         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
    2150         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
    2151         if (src1.isInt32() && src2.isInt32() && !((src1.asInt32() | src2.asInt32()) & 0xc0000000)) // no overflow
    2152             callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() + src2.asInt32());
    2153         else {
    2154             JSValue result = jsAdd(callFrame, src1, src2);
    2155             CHECK_FOR_EXCEPTION();
    2156             callFrame->uncheckedR(dst) = result;
    2157         }
    2158         vPC += OPCODE_LENGTH(op_add);
    2159         NEXT_INSTRUCTION();
    2160     }
    2161     DEFINE_OPCODE(op_mul) {
    2162         /* mul dst(r) src1(r) src2(r)
    2163 
    2164            Multiplies register src1 and register src2 (converted to
    2165            numbers), and puts the product in register dst.
    2166         */
    2167         int dst = vPC[1].u.operand;
    2168         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
    2169         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
    2170         if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | src2.asInt32()) >> 15) // no overflow
    2171                 callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() * src2.asInt32());
    2172         else {
    2173             JSValue result = jsNumber(src1.toNumber(callFrame) * src2.toNumber(callFrame));
    2174             CHECK_FOR_EXCEPTION();
    2175             callFrame->uncheckedR(dst) = result;
    2176         }
    2177 
    2178         vPC += OPCODE_LENGTH(op_mul);
    2179         NEXT_INSTRUCTION();
    2180     }
    2181     DEFINE_OPCODE(op_div) {
    2182         /* div dst(r) dividend(r) divisor(r)
    2183 
    2184            Divides register dividend (converted to number) by the
    2185            register divisor (converted to number), and puts the
    2186            quotient in register dst.
    2187         */
    2188         int dst = vPC[1].u.operand;
    2189         JSValue dividend = callFrame->r(vPC[2].u.operand).jsValue();
    2190         JSValue divisor = callFrame->r(vPC[3].u.operand).jsValue();
    2191 
    2192         JSValue result = jsNumber(dividend.toNumber(callFrame) / divisor.toNumber(callFrame));
    2193         CHECK_FOR_EXCEPTION();
    2194         callFrame->uncheckedR(dst) = result;
    2195 
    2196         vPC += OPCODE_LENGTH(op_div);
    2197         NEXT_INSTRUCTION();
    2198     }
    2199     DEFINE_OPCODE(op_mod) {
    2200         /* mod dst(r) dividend(r) divisor(r)
    2201 
    2202            Divides register dividend (converted to number) by
    2203            register divisor (converted to number), and puts the
    2204            remainder in register dst.
    2205         */
    2206         int dst = vPC[1].u.operand;
    2207         JSValue dividend = callFrame->r(vPC[2].u.operand).jsValue();
    2208         JSValue divisor = callFrame->r(vPC[3].u.operand).jsValue();
    2209 
    2210         if (dividend.isInt32() && divisor.isInt32() && divisor.asInt32() != 0 && divisor.asInt32() != -1) {
    2211             JSValue result = jsNumber(dividend.asInt32() % divisor.asInt32());
    2212             ASSERT(result);
    2213             callFrame->uncheckedR(dst) = result;
    2214             vPC += OPCODE_LENGTH(op_mod);
    2215             NEXT_INSTRUCTION();
    2216         }
    2217 
    2218         // Conversion to double must happen outside the call to fmod since the
    2219         // order of argument evaluation is not guaranteed.
    2220         double d1 = dividend.toNumber(callFrame);
    2221         double d2 = divisor.toNumber(callFrame);
    2222         JSValue result = jsNumber(fmod(d1, d2));
    2223         CHECK_FOR_EXCEPTION();
    2224         callFrame->uncheckedR(dst) = result;
    2225         vPC += OPCODE_LENGTH(op_mod);
    2226         NEXT_INSTRUCTION();
    2227     }
    2228     DEFINE_OPCODE(op_sub) {
    2229         /* sub dst(r) src1(r) src2(r)
    2230 
    2231            Subtracts register src2 (converted to number) from register
    2232            src1 (converted to number), and puts the difference in
    2233            register dst.
    2234         */
    2235         int dst = vPC[1].u.operand;
    2236         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
    2237         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
    2238         if (src1.isInt32() && src2.isInt32() && !((src1.asInt32() | src2.asInt32()) & 0xc0000000)) // no overflow
    2239             callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() - src2.asInt32());
    2240         else {
    2241             JSValue result = jsNumber(src1.toNumber(callFrame) - src2.toNumber(callFrame));
    2242             CHECK_FOR_EXCEPTION();
    2243             callFrame->uncheckedR(dst) = result;
    2244         }
    2245         vPC += OPCODE_LENGTH(op_sub);
    2246         NEXT_INSTRUCTION();
    2247     }
    2248     DEFINE_OPCODE(op_lshift) {
    2249         /* lshift dst(r) val(r) shift(r)
    2250 
    2251            Performs left shift of register val (converted to int32) by
    2252            register shift (converted to uint32), and puts the result
    2253            in register dst.
    2254         */
    2255         int dst = vPC[1].u.operand;
    2256         JSValue val = callFrame->r(vPC[2].u.operand).jsValue();
    2257         JSValue shift = callFrame->r(vPC[3].u.operand).jsValue();
    2258 
    2259         if (val.isInt32() && shift.isInt32())
    2260             callFrame->uncheckedR(dst) = jsNumber(val.asInt32() << (shift.asInt32() & 0x1f));
    2261         else {
    2262             JSValue result = jsNumber((val.toInt32(callFrame)) << (shift.toUInt32(callFrame) & 0x1f));
    2263             CHECK_FOR_EXCEPTION();
    2264             callFrame->uncheckedR(dst) = result;
    2265         }
    2266 
    2267         vPC += OPCODE_LENGTH(op_lshift);
    2268         NEXT_INSTRUCTION();
    2269     }
    2270     DEFINE_OPCODE(op_rshift) {
    2271         /* rshift dst(r) val(r) shift(r)
    2272 
    2273            Performs arithmetic right shift of register val (converted
    2274            to int32) by register shift (converted to
    2275            uint32), and puts the result in register dst.
    2276         */
    2277         int dst = vPC[1].u.operand;
    2278         JSValue val = callFrame->r(vPC[2].u.operand).jsValue();
    2279         JSValue shift = callFrame->r(vPC[3].u.operand).jsValue();
    2280 
    2281         if (val.isInt32() && shift.isInt32())
    2282             callFrame->uncheckedR(dst) = jsNumber(val.asInt32() >> (shift.asInt32() & 0x1f));
    2283         else {
    2284             JSValue result = jsNumber((val.toInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
    2285             CHECK_FOR_EXCEPTION();
    2286             callFrame->uncheckedR(dst) = result;
    2287         }
    2288 
    2289         vPC += OPCODE_LENGTH(op_rshift);
    2290         NEXT_INSTRUCTION();
    2291     }
    2292     DEFINE_OPCODE(op_urshift) {
    2293         /* rshift dst(r) val(r) shift(r)
    2294 
    2295            Performs logical right shift of register val (converted
    2296            to uint32) by register shift (converted to
    2297            uint32), and puts the result in register dst.
    2298         */
    2299         int dst = vPC[1].u.operand;
    2300         JSValue val = callFrame->r(vPC[2].u.operand).jsValue();
    2301         JSValue shift = callFrame->r(vPC[3].u.operand).jsValue();
    2302         if (val.isUInt32() && shift.isInt32())
    2303             callFrame->uncheckedR(dst) = jsNumber(val.asInt32() >> (shift.asInt32() & 0x1f));
    2304         else {
    2305             JSValue result = jsNumber((val.toUInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
    2306             CHECK_FOR_EXCEPTION();
    2307             callFrame->uncheckedR(dst) = result;
    2308         }
    2309 
    2310         vPC += OPCODE_LENGTH(op_urshift);
    2311         NEXT_INSTRUCTION();
    2312     }
    2313     DEFINE_OPCODE(op_bitand) {
    2314         /* bitand dst(r) src1(r) src2(r)
    2315 
    2316            Computes bitwise AND of register src1 (converted to int32)
    2317            and register src2 (converted to int32), and puts the result
    2318            in register dst.
    2319         */
    2320         int dst = vPC[1].u.operand;
    2321         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
    2322         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
    2323         if (src1.isInt32() && src2.isInt32())
    2324             callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() & src2.asInt32());
    2325         else {
    2326             JSValue result = jsNumber(src1.toInt32(callFrame) & src2.toInt32(callFrame));
    2327             CHECK_FOR_EXCEPTION();
    2328             callFrame->uncheckedR(dst) = result;
    2329         }
    2330 
    2331         vPC += OPCODE_LENGTH(op_bitand);
    2332         NEXT_INSTRUCTION();
    2333     }
    2334     DEFINE_OPCODE(op_bitxor) {
    2335         /* bitxor dst(r) src1(r) src2(r)
    2336 
    2337            Computes bitwise XOR of register src1 (converted to int32)
    2338            and register src2 (converted to int32), and puts the result
    2339            in register dst.
    2340         */
    2341         int dst = vPC[1].u.operand;
    2342         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
    2343         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
    2344         if (src1.isInt32() && src2.isInt32())
    2345             callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() ^ src2.asInt32());
    2346         else {
    2347             JSValue result = jsNumber(src1.toInt32(callFrame) ^ src2.toInt32(callFrame));
    2348             CHECK_FOR_EXCEPTION();
    2349             callFrame->uncheckedR(dst) = result;
    2350         }
    2351 
    2352         vPC += OPCODE_LENGTH(op_bitxor);
    2353         NEXT_INSTRUCTION();
    2354     }
    2355     DEFINE_OPCODE(op_bitor) {
    2356         /* bitor dst(r) src1(r) src2(r)
    2357 
    2358            Computes bitwise OR of register src1 (converted to int32)
    2359            and register src2 (converted to int32), and puts the
    2360            result in register dst.
    2361         */
    2362         int dst = vPC[1].u.operand;
    2363         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
    2364         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
    2365         if (src1.isInt32() && src2.isInt32())
    2366             callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() | src2.asInt32());
    2367         else {
    2368             JSValue result = jsNumber(src1.toInt32(callFrame) | src2.toInt32(callFrame));
    2369             CHECK_FOR_EXCEPTION();
    2370             callFrame->uncheckedR(dst) = result;
    2371         }
    2372 
    2373         vPC += OPCODE_LENGTH(op_bitor);
    2374         NEXT_INSTRUCTION();
    2375     }
    2376     DEFINE_OPCODE(op_not) {
    2377         /* not dst(r) src(r)
    2378 
    2379            Computes logical NOT of register src (converted to
    2380            boolean), and puts the result in register dst.
    2381         */
    2382         int dst = vPC[1].u.operand;
    2383         int src = vPC[2].u.operand;
    2384         JSValue result = jsBoolean(!callFrame->r(src).jsValue().toBoolean(callFrame));
    2385         CHECK_FOR_EXCEPTION();
    2386         callFrame->uncheckedR(dst) = result;
    2387 
    2388         vPC += OPCODE_LENGTH(op_not);
    2389         NEXT_INSTRUCTION();
    2390     }
    2391     DEFINE_OPCODE(op_check_has_instance) {
    2392         /* check_has_instance constructor(r)
    2393 
    2394            Check 'constructor' is an object with the internal property
    2395            [HasInstance] (i.e. is a function ... *shakes head sadly at
    2396            JSC API*). Raises an exception if register constructor is not
    2397            an valid parameter for instanceof.
    2398         */
    2399         int dst = vPC[1].u.operand;
    2400         int value = vPC[2].u.operand;
    2401         int base = vPC[3].u.operand;
    2402         int target = vPC[4].u.operand;
    2403 
    2404         JSValue baseVal = callFrame->r(base).jsValue();
    2405 
    2406         if (baseVal.isObject()) {
    2407             TypeInfo info = asObject(baseVal)->structure()->typeInfo();
    2408             if (info.implementsDefaultHasInstance()) {
    2409                 vPC += OPCODE_LENGTH(op_check_has_instance);
    2410                 NEXT_INSTRUCTION();
    2411             }
    2412             if (info.implementsHasInstance()) {
    2413                 JSValue baseVal = callFrame->r(base).jsValue();
    2414                 bool result = asObject(baseVal)->methodTable()->customHasInstance(asObject(baseVal), callFrame, callFrame->r(value).jsValue());
    2415                 CHECK_FOR_EXCEPTION();
    2416                 callFrame->uncheckedR(dst) = jsBoolean(result);
    2417 
    2418                 vPC += target;
    2419                 NEXT_INSTRUCTION();
    2420             }
    2421         }
    2422 
    2423         exceptionValue = createInvalidParamError(callFrame, "instanceof" , baseVal);
    2424         goto vm_throw;
    2425     }
    2426     DEFINE_OPCODE(op_instanceof) {
    2427         /* instanceof dst(r) value(r) constructor(r) constructorProto(r)
    2428 
    2429            Tests whether register value is an instance of register
    2430            constructor, and puts the boolean result in register
    2431            dst. Register constructorProto must contain the "prototype"
    2432            property (not the actual prototype) of the object in
    2433            register constructor. This lookup is separated so that
    2434            polymorphic inline caching can apply.
    2435 
    2436            Raises an exception if register constructor is not an
    2437            object.
    2438         */
    2439         int dst = vPC[1].u.operand;
    2440         int value = vPC[2].u.operand;
    2441         int baseProto = vPC[3].u.operand;
    2442 
    2443         bool result = JSObject::defaultHasInstance(callFrame, callFrame->r(value).jsValue(), callFrame->r(baseProto).jsValue());
    2444         CHECK_FOR_EXCEPTION();
    2445         callFrame->uncheckedR(dst) = jsBoolean(result);
    2446 
    2447         vPC += OPCODE_LENGTH(op_instanceof);
    2448         NEXT_INSTRUCTION();
    2449     }
    2450     DEFINE_OPCODE(op_typeof) {
    2451         /* typeof dst(r) src(r)
    2452 
    2453            Determines the type string for src according to ECMAScript
    2454            rules, and puts the result in register dst.
    2455         */
    2456         int dst = vPC[1].u.operand;
    2457         int src = vPC[2].u.operand;
    2458         callFrame->uncheckedR(dst) = JSValue(jsTypeStringForValue(callFrame, callFrame->r(src).jsValue()));
    2459 
    2460         vPC += OPCODE_LENGTH(op_typeof);
    2461         NEXT_INSTRUCTION();
    2462     }
    2463     DEFINE_OPCODE(op_is_undefined) {
    2464         /* is_undefined dst(r) src(r)
    2465 
    2466            Determines whether the type string for src according to
    2467            the ECMAScript rules is "undefined", and puts the result
    2468            in register dst.
    2469         */
    2470         int dst = vPC[1].u.operand;
    2471         int src = vPC[2].u.operand;
    2472         JSValue v = callFrame->r(src).jsValue();
    2473         callFrame->uncheckedR(dst) = jsBoolean(v.isCell() ? v.asCell()->structure()->masqueradesAsUndefined(callFrame->lexicalGlobalObject()) : v.isUndefined());
    2474 
    2475         vPC += OPCODE_LENGTH(op_is_undefined);
    2476         NEXT_INSTRUCTION();
    2477     }
    2478     DEFINE_OPCODE(op_is_boolean) {
    2479         /* is_boolean dst(r) src(r)
    2480 
    2481            Determines whether the type string for src according to
    2482            the ECMAScript rules is "boolean", and puts the result
    2483            in register dst.
    2484         */
    2485         int dst = vPC[1].u.operand;
    2486         int src = vPC[2].u.operand;
    2487         callFrame->uncheckedR(dst) = jsBoolean(callFrame->r(src).jsValue().isBoolean());
    2488 
    2489         vPC += OPCODE_LENGTH(op_is_boolean);
    2490         NEXT_INSTRUCTION();
    2491     }
    2492     DEFINE_OPCODE(op_is_number) {
    2493         /* is_number dst(r) src(r)
    2494 
    2495            Determines whether the type string for src according to
    2496            the ECMAScript rules is "number", and puts the result
    2497            in register dst.
    2498         */
    2499         int dst = vPC[1].u.operand;
    2500         int src = vPC[2].u.operand;
    2501         callFrame->uncheckedR(dst) = jsBoolean(callFrame->r(src).jsValue().isNumber());
    2502 
    2503         vPC += OPCODE_LENGTH(op_is_number);
    2504         NEXT_INSTRUCTION();
    2505     }
    2506     DEFINE_OPCODE(op_is_string) {
    2507         /* is_string dst(r) src(r)
    2508 
    2509            Determines whether the type string for src according to
    2510            the ECMAScript rules is "string", and puts the result
    2511            in register dst.
    2512         */
    2513         int dst = vPC[1].u.operand;
    2514         int src = vPC[2].u.operand;
    2515         callFrame->uncheckedR(dst) = jsBoolean(callFrame->r(src).jsValue().isString());
    2516 
    2517         vPC += OPCODE_LENGTH(op_is_string);
    2518         NEXT_INSTRUCTION();
    2519     }
    2520     DEFINE_OPCODE(op_is_object) {
    2521         /* is_object dst(r) src(r)
    2522 
    2523            Determines whether the type string for src according to
    2524            the ECMAScript rules is "object", and puts the result
    2525            in register dst.
    2526         */
    2527         int dst = vPC[1].u.operand;
    2528         int src = vPC[2].u.operand;
    2529         callFrame->uncheckedR(dst) = jsBoolean(jsIsObjectType(callFrame, callFrame->r(src).jsValue()));
    2530 
    2531         vPC += OPCODE_LENGTH(op_is_object);
    2532         NEXT_INSTRUCTION();
    2533     }
    2534     DEFINE_OPCODE(op_is_function) {
    2535         /* is_function dst(r) src(r)
    2536 
    2537            Determines whether the type string for src according to
    2538            the ECMAScript rules is "function", and puts the result
    2539            in register dst.
    2540         */
    2541         int dst = vPC[1].u.operand;
    2542         int src = vPC[2].u.operand;
    2543         callFrame->uncheckedR(dst) = jsBoolean(jsIsFunctionType(callFrame->r(src).jsValue()));
    2544 
    2545         vPC += OPCODE_LENGTH(op_is_function);
    2546         NEXT_INSTRUCTION();
    2547     }
    2548     DEFINE_OPCODE(op_in) {
    2549         /* in dst(r) property(r) base(r)
    2550 
    2551            Tests whether register base has a property named register
    2552            property, and puts the boolean result in register dst.
    2553 
    2554            Raises an exception if register constructor is not an
    2555            object.
    2556         */
    2557         int dst = vPC[1].u.operand;
    2558         int property = vPC[2].u.operand;
    2559         int base = vPC[3].u.operand;
    2560 
    2561         JSValue baseVal = callFrame->r(base).jsValue();
    2562         if (isInvalidParamForIn(callFrame, baseVal, exceptionValue))
    2563             goto vm_throw;
    2564 
    2565         JSObject* baseObj = asObject(baseVal);
    2566 
    2567         JSValue propName = callFrame->r(property).jsValue();
    2568 
    2569         uint32_t i;
    2570         if (propName.getUInt32(i))
    2571             callFrame->uncheckedR(dst) = jsBoolean(baseObj->hasProperty(callFrame, i));
    2572         else if (isName(propName))
    2573             callFrame->uncheckedR(dst) = jsBoolean(baseObj->hasProperty(callFrame, jsCast<NameInstance*>(propName.asCell())->privateName()));
    2574         else {
    2575             Identifier property(callFrame, propName.toString(callFrame)->value(callFrame));
    2576             CHECK_FOR_EXCEPTION();
    2577             callFrame->uncheckedR(dst) = jsBoolean(baseObj->hasProperty(callFrame, property));
    2578         }
    2579 
    2580         vPC += OPCODE_LENGTH(op_in);
    2581         NEXT_INSTRUCTION();
    2582     }
    2583     DEFINE_OPCODE(op_resolve) {
    2584         /* resolve dst(r) property(id)
    2585 
    2586            Looks up the property named by identifier property in the
    2587            scope chain, and writes the resulting value to register
    2588            dst. If the property is not found, raises an exception.
    2589         */
    2590         int dst = vPC[1].u.operand;
    2591         int property = vPC[2].u.operand;
    2592         Identifier& ident = callFrame->codeBlock()->identifier(property);
    2593 
    2594         JSValue result = JSScope::resolve(callFrame, ident);
    2595         CHECK_FOR_EXCEPTION();
    2596         callFrame->uncheckedR(dst) = result;
    2597 
    2598         vPC += OPCODE_LENGTH(op_resolve);
    2599         NEXT_INSTRUCTION();
    2600     }
    2601     DEFINE_OPCODE(op_resolve_skip) {
    2602         /* resolve_skip dst(r) property(id) skip(n)
    2603 
    2604          Looks up the property named by identifier property in the
    2605          scope chain skipping the top 'skip' levels, and writes the resulting
    2606          value to register dst. If the property is not found, raises an exception.
    2607          */
    2608         int dst = vPC[1].u.operand;
    2609         int property = vPC[2].u.operand;
    2610         int skip = vPC[3].u.operand;
    2611         Identifier& ident = callFrame->codeBlock()->identifier(property);
    2612 
    2613         JSValue result = JSScope::resolveSkip(callFrame, ident, skip);
    2614         CHECK_FOR_EXCEPTION();
    2615         callFrame->uncheckedR(dst) = result;
    2616 
    2617         vPC += OPCODE_LENGTH(op_resolve_skip);
    2618         NEXT_INSTRUCTION();
    2619     }
    2620     DEFINE_OPCODE(op_resolve_global) {
    2621         /* resolve_skip dst(r) globalObject(c) property(id) structure(sID) offset(n)
    2622          
    2623            Performs a dynamic property lookup for the given property, on the provided
    2624            global object.  If structure matches the Structure of the global then perform
    2625            a fast lookup using the case offset, otherwise fall back to a full resolve and
    2626            cache the new structure and offset
    2627          */
    2628         int dst = vPC[1].u.operand;
    2629         int property = vPC[2].u.operand;
    2630         Identifier& ident = callFrame->codeBlock()->identifier(property);
    2631 
    2632         JSValue result = JSScope::resolveGlobal(
    2633             callFrame,
    2634             ident,
    2635             callFrame->lexicalGlobalObject(),
    2636             &vPC[3].u.structure,
    2637             &vPC[4].u.operand
    2638         );
    2639         CHECK_FOR_EXCEPTION();
    2640         callFrame->uncheckedR(dst) = result;
    2641 
    2642         vPC += OPCODE_LENGTH(op_resolve_global);
    2643         NEXT_INSTRUCTION();
    2644     }
    2645     DEFINE_OPCODE(op_resolve_global_dynamic) {
    2646         /* resolve_skip dst(r) globalObject(c) property(id) structure(sID) offset(n), depth(n)
    2647          
    2648          Performs a dynamic property lookup for the given property, on the provided
    2649          global object.  If structure matches the Structure of the global then perform
    2650          a fast lookup using the case offset, otherwise fall back to a full resolve and
    2651          cache the new structure and offset.
    2652          
    2653          This walks through n levels of the scope chain to verify that none of those levels
    2654          in the scope chain include dynamically added properties.
    2655          */
    2656         int dst = vPC[1].u.operand;
    2657         int property = vPC[2].u.operand;
    2658         int skip = vPC[5].u.operand;
    2659         Identifier& ident = callFrame->codeBlock()->identifier(property);
    2660 
    2661         JSValue result = JSScope::resolveGlobalDynamic(callFrame, ident, skip, &vPC[3].u.structure, &vPC[4].u.operand);
    2662         CHECK_FOR_EXCEPTION();
    2663         callFrame->uncheckedR(dst) = result;
    2664 
    2665         vPC += OPCODE_LENGTH(op_resolve_global_dynamic);
    2666         NEXT_INSTRUCTION();
    2667     }
    2668     DEFINE_OPCODE(op_get_global_var) {
    2669         /* get_global_var dst(r) globalObject(c) registerPointer(n)
    2670 
    2671            Gets the global var at global slot index and places it in register dst.
    2672          */
    2673         int dst = vPC[1].u.operand;
    2674         WriteBarrier<Unknown>* registerPointer = vPC[2].u.registerPointer;
    2675 
    2676         callFrame->uncheckedR(dst) = registerPointer->get();
    2677         vPC += OPCODE_LENGTH(op_get_global_var);
    2678         NEXT_INSTRUCTION();
    2679     }
    2680     DEFINE_OPCODE(op_get_global_var_watchable) {
    2681         /* get_global_var_watchable dst(r) globalObject(c) registerPointer(n)
    2682 
    2683            Gets the global var at global slot index and places it in register dst.
    2684          */
    2685         int dst = vPC[1].u.operand;
    2686         WriteBarrier<Unknown>* registerPointer = vPC[2].u.registerPointer;
    2687 
    2688         callFrame->uncheckedR(dst) = registerPointer->get();
    2689         vPC += OPCODE_LENGTH(op_get_global_var_watchable);
    2690         NEXT_INSTRUCTION();
    2691     }
    2692     DEFINE_OPCODE(op_init_global_const)
    2693     DEFINE_OPCODE(op_put_global_var) {
    2694         /* put_global_var globalObject(c) registerPointer(n) value(r)
    2695          
    2696            Puts value into global slot index.
    2697          */
    2698         JSGlobalObject* scope = codeBlock->globalObject();
    2699         ASSERT(scope->isGlobalObject());
    2700         WriteBarrier<Unknown>* registerPointer = vPC[1].u.registerPointer;
    2701         int value = vPC[2].u.operand;
    2702        
    2703         registerPointer->set(*globalData, scope, callFrame->r(value).jsValue());
    2704         vPC += OPCODE_LENGTH(op_put_global_var);
    2705         NEXT_INSTRUCTION();
    2706     }
    2707     DEFINE_OPCODE(op_init_global_const_check)
    2708     DEFINE_OPCODE(op_put_global_var_check) {
    2709         /* put_global_var_check globalObject(c) registerPointer(n) value(r)
    2710          
    2711            Puts value into global slot index. In JIT configurations this will
    2712            perform a watchpoint check. If we're running with the old interpreter,
    2713            this is not necessary; the interpreter never uses these watchpoints.
    2714          */
    2715         JSGlobalObject* scope = codeBlock->globalObject();
    2716         ASSERT(scope->isGlobalObject());
    2717         WriteBarrier<Unknown>* registerPointer = vPC[1].u.registerPointer;
    2718         int value = vPC[2].u.operand;
    2719        
    2720         registerPointer->set(*globalData, scope, callFrame->r(value).jsValue());
    2721         vPC += OPCODE_LENGTH(op_put_global_var_check);
    2722         NEXT_INSTRUCTION();
    2723     }
    2724     DEFINE_OPCODE(op_get_scoped_var) {
    2725         /* get_scoped_var dst(r) index(n) skip(n)
    2726 
    2727          Loads the contents of the index-th local from the scope skip nodes from
    2728          the top of the scope chain, and places it in register dst.
    2729          */
    2730         int dst = vPC[1].u.operand;
    2731         int index = vPC[2].u.operand;
    2732         int skip = vPC[3].u.operand;
    2733 
    2734         JSScope* scope = callFrame->scope();
    2735         ScopeChainIterator iter = scope->begin();
    2736         ScopeChainIterator end = scope->end();
    2737         ASSERT_UNUSED(end, iter != end);
    2738         ASSERT(codeBlock == callFrame->codeBlock());
    2739         bool checkTopLevel = codeBlock->codeType() == FunctionCode && codeBlock->needsFullScopeChain();
    2740         ASSERT(skip || !checkTopLevel);
    2741         if (checkTopLevel && skip--) {
    2742             if (callFrame->r(codeBlock->activationRegister()).jsValue())
    2743                 ++iter;
    2744         }
    2745         while (skip--) {
    2746             ++iter;
    2747             ASSERT_UNUSED(end, iter != end);
    2748         }
    2749         ASSERT(iter->isVariableObject());
    2750         JSVariableObject* variableObject = jsCast<JSVariableObject*>(iter.get());
    2751         callFrame->uncheckedR(dst) = variableObject->registerAt(index).get();
    2752         ASSERT(callFrame->r(dst).jsValue());
    2753         vPC += OPCODE_LENGTH(op_get_scoped_var);
    2754         NEXT_INSTRUCTION();
    2755     }
    2756     DEFINE_OPCODE(op_put_scoped_var) {
    2757         /* put_scoped_var index(n) skip(n) value(r)
    2758 
    2759          */
    2760         int index = vPC[1].u.operand;
    2761         int skip = vPC[2].u.operand;
    2762         int value = vPC[3].u.operand;
    2763 
    2764         JSScope* scope = callFrame->scope();
    2765         ScopeChainIterator iter = scope->begin();
    2766         ScopeChainIterator end = scope->end();
    2767         ASSERT(codeBlock == callFrame->codeBlock());
    2768         ASSERT_UNUSED(end, iter != end);
    2769         bool checkTopLevel = codeBlock->codeType() == FunctionCode && codeBlock->needsFullScopeChain();
    2770         ASSERT(skip || !checkTopLevel);
    2771         if (checkTopLevel && skip--) {
    2772             if (callFrame->r(codeBlock->activationRegister()).jsValue())
    2773                 ++iter;
    2774         }
    2775         while (skip--) {
    2776             ++iter;
    2777             ASSERT_UNUSED(end, iter != end);
    2778         }
    2779 
    2780         ASSERT(iter->isVariableObject());
    2781         JSVariableObject* variableObject = jsCast<JSVariableObject*>(iter.get());
    2782         ASSERT(callFrame->r(value).jsValue());
    2783         variableObject->registerAt(index).set(*globalData, variableObject, callFrame->r(value).jsValue());
    2784         vPC += OPCODE_LENGTH(op_put_scoped_var);
    2785         NEXT_INSTRUCTION();
    2786     }
    2787     DEFINE_OPCODE(op_resolve_base) {
    2788         /* resolve_base dst(r) property(id) isStrict(bool)
    2789 
    2790            Searches the scope chain for an object containing
    2791            identifier property, and if one is found, writes it to
    2792            register dst. If none is found and isStrict is false, the
    2793            outermost scope (which will be the global object) is
    2794            stored in register dst.
    2795         */
    2796         int dst = vPC[1].u.operand;
    2797         int property = vPC[2].u.operand;
    2798         bool isStrict = vPC[3].u.operand;
    2799         Identifier& ident = callFrame->codeBlock()->identifier(property);
    2800 
    2801         JSValue result = JSScope::resolveBase(callFrame, ident, isStrict);
    2802         CHECK_FOR_EXCEPTION();
    2803         callFrame->uncheckedR(dst) = result;
    2804 
    2805         vPC += OPCODE_LENGTH(op_resolve_base);
    2806         NEXT_INSTRUCTION();
    2807     }
    2808     DEFINE_OPCODE(op_ensure_property_exists) {
    2809         /* ensure_property_exists base(r) property(id)
    2810 
    2811            Throws an exception if property does not exist on base
    2812          */
    2813         int base = vPC[1].u.operand;
    2814         int property = vPC[2].u.operand;
    2815         Identifier& ident = codeBlock->identifier(property);
    2816        
    2817         JSValue baseVal = callFrame->r(base).jsValue();
    2818         JSObject* baseObject = asObject(baseVal);
    2819         PropertySlot slot(baseVal);
    2820         if (!baseObject->getPropertySlot(callFrame, ident, slot)) {
    2821             exceptionValue = createErrorForInvalidGlobalAssignment(callFrame, ident.string());
    2822             goto vm_throw;
    2823         }
    2824 
    2825         vPC += OPCODE_LENGTH(op_ensure_property_exists);
    2826         NEXT_INSTRUCTION();
    2827     }
    2828     DEFINE_OPCODE(op_resolve_with_base) {
    2829         /* resolve_with_base baseDst(r) propDst(r) property(id)
    2830 
    2831            Searches the scope chain for an object containing
    2832            identifier property, and if one is found, writes it to
    2833            register srcDst, and the retrieved property value to register
    2834            propDst. If the property is not found, raises an exception.
    2835 
    2836            This is more efficient than doing resolve_base followed by
    2837            resolve, or resolve_base followed by get_by_id, as it
    2838            avoids duplicate hash lookups.
    2839         */
    2840         int baseDst = vPC[1].u.operand;
    2841         int propDst = vPC[2].u.operand;
    2842         int property = vPC[3].u.operand;
    2843         Identifier& ident = codeBlock->identifier(property);
    2844 
    2845         JSValue prop = JSScope::resolveWithBase(callFrame, ident, &callFrame->uncheckedR(baseDst));
    2846         CHECK_FOR_EXCEPTION();
    2847         callFrame->uncheckedR(propDst) = prop;
    2848 
    2849         vPC += OPCODE_LENGTH(op_resolve_with_base);
    2850         NEXT_INSTRUCTION();
    2851     }
    2852     DEFINE_OPCODE(op_resolve_with_this) {
    2853         /* resolve_with_this thisDst(r) propDst(r) property(id)
    2854 
    2855            Searches the scope chain for an object containing
    2856            identifier property, and if one is found, writes the
    2857            retrieved property value to register propDst, and the
    2858            this object to pass in a call to thisDst.
    2859 
    2860            If the property is not found, raises an exception.
    2861         */
    2862         int thisDst = vPC[1].u.operand;
    2863         int propDst = vPC[2].u.operand;
    2864         int property = vPC[3].u.operand;
    2865         Identifier& ident = codeBlock->identifier(property);
    2866 
    2867         JSValue prop = JSScope::resolveWithThis(callFrame, ident, &callFrame->uncheckedR(thisDst));
    2868         CHECK_FOR_EXCEPTION();
    2869         callFrame->uncheckedR(propDst) = prop;
    2870 
    2871         vPC += OPCODE_LENGTH(op_resolve_with_this);
    2872         NEXT_INSTRUCTION();
    2873     }
    2874     DEFINE_OPCODE(op_get_by_id_out_of_line)
    2875     DEFINE_OPCODE(op_get_by_id) {
    2876         /* get_by_id dst(r) base(r) property(id) structure(sID) nop(n) nop(n) nop(n)
    2877 
    2878            Generic property access: Gets the property named by identifier
    2879            property from the value base, and puts the result in register dst.
    2880         */
    2881         int dst = vPC[1].u.operand;
    2882         int base = vPC[2].u.operand;
    2883         int property = vPC[3].u.operand;
    2884 
    2885         Identifier& ident = codeBlock->identifier(property);
    2886         JSValue baseValue = callFrame->r(base).jsValue();
    2887         PropertySlot slot(baseValue);
    2888         JSValue result = baseValue.get(callFrame, ident, slot);
    2889         CHECK_FOR_EXCEPTION();
    2890 
    2891         tryCacheGetByID(callFrame, codeBlock, vPC, baseValue, ident, slot);
    2892 
    2893         callFrame->uncheckedR(dst) = result;
    2894         vPC += OPCODE_LENGTH(op_get_by_id);
    2895         NEXT_INSTRUCTION();
    2896     }
    2897     DEFINE_OPCODE(op_get_by_id_self) {
    2898         /* op_get_by_id_self dst(r) base(r) property(id) structure(sID) offset(n) nop(n) nop(n)
    2899 
    2900            Cached property access: Attempts to get a cached property from the
    2901            value base. If the cache misses, op_get_by_id_self reverts to
    2902            op_get_by_id.
    2903         */
    2904         int base = vPC[2].u.operand;
    2905         JSValue baseValue = callFrame->r(base).jsValue();
    2906 
    2907         if (LIKELY(baseValue.isCell())) {
    2908             JSCell* baseCell = baseValue.asCell();
    2909             Structure* structure = vPC[4].u.structure.get();
    2910 
    2911             if (LIKELY(baseCell->structure() == structure)) {
    2912                 ASSERT(baseCell->isObject());
    2913                 JSObject* baseObject = asObject(baseCell);
    2914                 int dst = vPC[1].u.operand;
    2915                 int offset = vPC[5].u.operand;
    2916 
    2917                 ASSERT(baseObject->get(callFrame, codeBlock->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset));
    2918                 callFrame->uncheckedR(dst) = JSValue(baseObject->getDirectOffset(offset));
    2919 
    2920                 vPC += OPCODE_LENGTH(op_get_by_id_self);
    2921                 NEXT_INSTRUCTION();
    2922             }
    2923         }
    2924 
    2925         uncacheGetByID(codeBlock, vPC);
    2926         NEXT_INSTRUCTION();
    2927     }
    2928     DEFINE_OPCODE(op_get_by_id_proto) {
    2929         /* op_get_by_id_proto dst(r) base(r) property(id) structure(sID) prototypeStructure(sID) offset(n) nop(n)
    2930 
    2931            Cached property access: Attempts to get a cached property from the
    2932            value base's prototype. If the cache misses, op_get_by_id_proto
    2933            reverts to op_get_by_id.
    2934         */
    2935         int base = vPC[2].u.operand;
    2936         JSValue baseValue = callFrame->r(base).jsValue();
    2937 
    2938         if (LIKELY(baseValue.isCell())) {
    2939             JSCell* baseCell = baseValue.asCell();
    2940             Structure* structure = vPC[4].u.structure.get();
    2941 
    2942             if (LIKELY(baseCell->structure() == structure)) {
    2943                 ASSERT(structure->prototypeForLookup(callFrame).isObject());
    2944                 JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame));
    2945                 Structure* prototypeStructure = vPC[5].u.structure.get();
    2946 
    2947                 if (LIKELY(protoObject->structure() == prototypeStructure)) {
    2948                     int dst = vPC[1].u.operand;
    2949                     int offset = vPC[6].u.operand;
    2950 
    2951                     ASSERT(protoObject->get(callFrame, codeBlock->identifier(vPC[3].u.operand)) == protoObject->getDirectOffset(offset));
    2952                     ASSERT(baseValue.get(callFrame, codeBlock->identifier(vPC[3].u.operand)) == protoObject->getDirectOffset(offset));
    2953                     callFrame->uncheckedR(dst) = JSValue(protoObject->getDirectOffset(offset));
    2954 
    2955                     vPC += OPCODE_LENGTH(op_get_by_id_proto);
    2956                     NEXT_INSTRUCTION();
    2957                 }
    2958             }
    2959         }
    2960 
    2961         uncacheGetByID(codeBlock, vPC);
    2962         NEXT_INSTRUCTION();
    2963     }
    2964 #if USE(GCC_COMPUTED_GOTO_WORKAROUND)
    2965     goto *(&&skip_id_getter_proto);
    2966 #endif
    2967     DEFINE_OPCODE(op_get_by_id_getter_proto) {
    2968         /* op_get_by_id_getter_proto dst(r) base(r) property(id) structure(sID) prototypeStructure(sID) offset(n) nop(n)
    2969          
    2970          Cached property access: Attempts to get a cached getter property from the
    2971          value base's prototype. If the cache misses, op_get_by_id_getter_proto
    2972          reverts to op_get_by_id.
    2973          */
    2974         int base = vPC[2].u.operand;
    2975         JSValue baseValue = callFrame->r(base).jsValue();
    2976        
    2977         if (LIKELY(baseValue.isCell())) {
    2978             JSCell* baseCell = baseValue.asCell();
    2979             Structure* structure = vPC[4].u.structure.get();
    2980            
    2981             if (LIKELY(baseCell->structure() == structure)) {
    2982                 ASSERT(structure->prototypeForLookup(callFrame).isObject());
    2983                 JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame));
    2984                 Structure* prototypeStructure = vPC[5].u.structure.get();
    2985                
    2986                 if (LIKELY(protoObject->structure() == prototypeStructure)) {
    2987                     int dst = vPC[1].u.operand;
    2988                     int offset = vPC[6].u.operand;
    2989                     if (GetterSetter* getterSetter = asGetterSetter(protoObject->getDirectOffset(offset).asCell())) {
    2990                         JSObject* getter = getterSetter->getter();
    2991                         CallData callData;
    2992                         CallType callType = getter->methodTable()->getCallData(getter, callData);
    2993                         JSValue result = call(callFrame, getter, callType, callData, asObject(baseCell), ArgList());
    2994                         CHECK_FOR_EXCEPTION();
    2995                         callFrame->uncheckedR(dst) = result;
    2996                     } else
    2997                         callFrame->uncheckedR(dst) = jsUndefined();
    2998                     vPC += OPCODE_LENGTH(op_get_by_id_getter_proto);
    2999                     NEXT_INSTRUCTION();
    3000                 }
    3001             }
    3002         }
    3003         uncacheGetByID(codeBlock, vPC);
    3004         NEXT_INSTRUCTION();
    3005     }
    3006 #if USE(GCC_COMPUTED_GOTO_WORKAROUND)
    3007     skip_id_getter_proto:
    3008 #endif
    3009 #if USE(GCC_COMPUTED_GOTO_WORKAROUND)
    3010     goto *(&&skip_id_custom_proto);
    3011 #endif
    3012     DEFINE_OPCODE(op_get_by_id_custom_proto) {
    3013         /* op_get_by_id_custom_proto dst(r) base(r) property(id) structure(sID) prototypeStructure(sID) offset(n) nop(n)
    3014          
    3015          Cached property access: Attempts to use a cached named property getter
    3016          from the value base's prototype. If the cache misses, op_get_by_id_custom_proto
    3017          reverts to op_get_by_id.
    3018          */
    3019         int base = vPC[2].u.operand;
    3020         JSValue baseValue = callFrame->r(base).jsValue();
    3021        
    3022         if (LIKELY(baseValue.isCell())) {
    3023             JSCell* baseCell = baseValue.asCell();
    3024             Structure* structure = vPC[4].u.structure.get();
    3025            
    3026             if (LIKELY(baseCell->structure() == structure)) {
    3027                 ASSERT(structure->prototypeForLookup(callFrame).isObject());
    3028                 JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame));
    3029                 Structure* prototypeStructure = vPC[5].u.structure.get();
    3030                
    3031                 if (LIKELY(protoObject->structure() == prototypeStructure)) {
    3032                     int dst = vPC[1].u.operand;
    3033                     int property = vPC[3].u.operand;
    3034                     Identifier& ident = codeBlock->identifier(property);
    3035                    
    3036                     PropertySlot::GetValueFunc getter = vPC[6].u.getterFunc;
    3037                     JSValue result = getter(callFrame, protoObject, ident);
    3038                     CHECK_FOR_EXCEPTION();
    3039                     callFrame->uncheckedR(dst) = result;
    3040                     vPC += OPCODE_LENGTH(op_get_by_id_custom_proto);
    3041                     NEXT_INSTRUCTION();
    3042                 }
    3043             }
    3044         }
    3045         uncacheGetByID(codeBlock, vPC);
    3046         NEXT_INSTRUCTION();
    3047     }
    3048 #if USE(GCC_COMPUTED_GOTO_WORKAROUND)
    3049     skip_id_custom_proto:
    3050 #endif
    3051 #if USE(GCC_COMPUTED_GOTO_WORKAROUND)
    3052     goto *(&&skip_get_by_id_chain);
    3053 #endif
    3054     DEFINE_OPCODE(op_get_by_id_chain) {
    3055         /* op_get_by_id_chain dst(r) base(r) property(id) structure(sID) structureChain(chain) count(n) offset(n)
    3056 
    3057            Cached property access: Attempts to get a cached property from the
    3058            value base's prototype chain. If the cache misses, op_get_by_id_chain
    3059            reverts to op_get_by_id.
    3060         */
    3061         int base = vPC[2].u.operand;
    3062         JSValue baseValue = callFrame->r(base).jsValue();
    3063 
    3064         if (LIKELY(baseValue.isCell())) {
    3065             JSCell* baseCell = baseValue.asCell();
    3066             Structure* structure = vPC[4].u.structure.get();
    3067 
    3068             if (LIKELY(baseCell->structure() == structure)) {
    3069                 WriteBarrier<Structure>* it = vPC[5].u.structureChain->head();
    3070                 size_t count = vPC[6].u.operand;
    3071                 WriteBarrier<Structure>* end = it + count;
    3072 
    3073                 while (true) {
    3074                     JSObject* baseObject = asObject(baseCell->structure()->prototypeForLookup(callFrame));
    3075 
    3076                     if (UNLIKELY(baseObject->structure() != (*it).get()))
    3077                         break;
    3078 
    3079                     if (++it == end) {
    3080                         int dst = vPC[1].u.operand;
    3081                         int offset = vPC[7].u.operand;
    3082 
    3083                         ASSERT(baseObject->get(callFrame, codeBlock->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset));
    3084                         ASSERT(baseValue.get(callFrame, codeBlock->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset));
    3085                         callFrame->uncheckedR(dst) = JSValue(baseObject->getDirectOffset(offset));
    3086 
    3087                         vPC += OPCODE_LENGTH(op_get_by_id_chain);
    3088                         NEXT_INSTRUCTION();
    3089                     }
    3090 
    3091                     // Update baseCell, so that next time around the loop we'll pick up the prototype's prototype.
    3092                     baseCell = baseObject;
    3093                 }
    3094             }
    3095         }
    3096 
    3097         uncacheGetByID(codeBlock, vPC);
    3098         NEXT_INSTRUCTION();
    3099     }
    3100 #if USE(GCC_COMPUTED_GOTO_WORKAROUND)
    3101     skip_get_by_id_chain:
    3102     goto *(&&skip_id_getter_self);
    3103 #endif
    3104     DEFINE_OPCODE(op_get_by_id_getter_self) {
    3105         /* op_get_by_id_self dst(r) base(r) property(id) structure(sID) offset(n) nop(n) nop(n)
    3106          
    3107          Cached property access: Attempts to get a cached property from the
    3108          value base. If the cache misses, op_get_by_id_getter_self reverts to
    3109          op_get_by_id.
    3110          */
    3111         int base = vPC[2].u.operand;
    3112         JSValue baseValue = callFrame->r(base).jsValue();
    3113        
    3114         if (LIKELY(baseValue.isCell())) {
    3115             JSCell* baseCell = baseValue.asCell();
    3116             Structure* structure = vPC[4].u.structure.get();
    3117            
    3118             if (LIKELY(baseCell->structure() == structure)) {
    3119                 ASSERT(baseCell->isObject());
    3120                 JSObject* baseObject = asObject(baseCell);
    3121                 int dst = vPC[1].u.operand;
    3122                 int offset = vPC[5].u.operand;
    3123 
    3124                 if (GetterSetter* getterSetter = asGetterSetter(baseObject->getDirectOffset(offset).asCell())) {
    3125                     JSObject* getter = getterSetter->getter();
    3126                     CallData callData;
    3127                     CallType callType = getter->methodTable()->getCallData(getter, callData);
    3128                     JSValue result = call(callFrame, getter, callType, callData, baseObject, ArgList());
    3129                     CHECK_FOR_EXCEPTION();
    3130                     callFrame->uncheckedR(dst) = result;
    3131                 } else
    3132                     callFrame->uncheckedR(dst) = jsUndefined();
    3133 
    3134                 vPC += OPCODE_LENGTH(op_get_by_id_getter_self);
    3135                 NEXT_INSTRUCTION();
    3136             }
    3137         }
    3138         uncacheGetByID(codeBlock, vPC);
    3139         NEXT_INSTRUCTION();
    3140     }
    3141 #if USE(GCC_COMPUTED_GOTO_WORKAROUND)
    3142     skip_id_getter_self:
    3143 #endif
    3144 #if USE(GCC_COMPUTED_GOTO_WORKAROUND)
    3145     goto *(&&skip_id_custom_self);
    3146 #endif
    3147     DEFINE_OPCODE(op_get_by_id_custom_self) {
    3148         /* op_get_by_id_custom_self dst(r) base(r) property(id) structure(sID) offset(n) nop(n) nop(n)
    3149          
    3150          Cached property access: Attempts to use a cached named property getter
    3151          from the value base. If the cache misses, op_get_by_id_custom_self reverts to
    3152          op_get_by_id.
    3153          */
    3154         int base = vPC[2].u.operand;
    3155         JSValue baseValue = callFrame->r(base).jsValue();
    3156        
    3157         if (LIKELY(baseValue.isCell())) {
    3158             JSCell* baseCell = baseValue.asCell();
    3159             Structure* structure = vPC[4].u.structure.get();
    3160            
    3161             if (LIKELY(baseCell->structure() == structure)) {
    3162                 ASSERT(baseCell->isObject());
    3163                 int dst = vPC[1].u.operand;
    3164                 int property = vPC[3].u.operand;
    3165                 Identifier& ident = codeBlock->identifier(property);
    3166 
    3167                 PropertySlot::GetValueFunc getter = vPC[5].u.getterFunc;
    3168                 JSValue result = getter(callFrame, baseValue, ident);
    3169                 CHECK_FOR_EXCEPTION();
    3170                 callFrame->uncheckedR(dst) = result;
    3171                 vPC += OPCODE_LENGTH(op_get_by_id_custom_self);
    3172                 NEXT_INSTRUCTION();
    3173             }
    3174         }
    3175         uncacheGetByID(codeBlock, vPC);
    3176         NEXT_INSTRUCTION();
    3177     }
    3178 #if USE(GCC_COMPUTED_GOTO_WORKAROUND)
    3179 skip_id_custom_self:
    3180 #endif
    3181     DEFINE_OPCODE(op_get_by_id_generic) {
    3182         /* op_get_by_id_generic dst(r) base(r) property(id) nop(sID) nop(n) nop(n) nop(n)
    3183 
    3184            Generic property access: Gets the property named by identifier
    3185            property from the value base, and puts the result in register dst.
    3186         */
    3187         int dst = vPC[1].u.operand;
    3188         int base = vPC[2].u.operand;
    3189         int property = vPC[3].u.operand;
    3190 
    3191         Identifier& ident = codeBlock->identifier(property);
    3192         JSValue baseValue = callFrame->r(base).jsValue();
    3193         PropertySlot slot(baseValue);
    3194         JSValue result = baseValue.get(callFrame, ident, slot);
    3195         CHECK_FOR_EXCEPTION();
    3196 
    3197         callFrame->uncheckedR(dst) = result;
    3198         vPC += OPCODE_LENGTH(op_get_by_id_generic);
    3199         NEXT_INSTRUCTION();
    3200     }
    3201 #if USE(GCC_COMPUTED_GOTO_WORKAROUND)
    3202     goto *(&&skip_id_getter_chain);
    3203 #endif
    3204     DEFINE_OPCODE(op_get_by_id_getter_chain) {
    3205         /* op_get_by_id_getter_chain dst(r) base(r) property(id) structure(sID) structureChain(chain) count(n) offset(n)
    3206          
    3207          Cached property access: Attempts to get a cached property from the
    3208          value base's prototype chain. If the cache misses, op_get_by_id_getter_chain
    3209          reverts to op_get_by_id.
    3210          */
    3211         int base = vPC[2].u.operand;
    3212         JSValue baseValue = callFrame->r(base).jsValue();
    3213        
    3214         if (LIKELY(baseValue.isCell())) {
    3215             JSCell* baseCell = baseValue.asCell();
    3216             Structure* structure = vPC[4].u.structure.get();
    3217            
    3218             if (LIKELY(baseCell->structure() == structure)) {
    3219                 WriteBarrier<Structure>* it = vPC[5].u.structureChain->head();
    3220                 size_t count = vPC[6].u.operand;
    3221                 WriteBarrier<Structure>* end = it + count;
    3222                
    3223                 while (true) {
    3224                     JSObject* baseObject = asObject(baseCell->structure()->prototypeForLookup(callFrame));
    3225                    
    3226                     if (UNLIKELY(baseObject->structure() != (*it).get()))
    3227                         break;
    3228                    
    3229                     if (++it == end) {
    3230                         int dst = vPC[1].u.operand;
    3231                         int offset = vPC[7].u.operand;
    3232                         if (GetterSetter* getterSetter = asGetterSetter(baseObject->getDirectOffset(offset).asCell())) {
    3233                             JSObject* getter = getterSetter->getter();
    3234                             CallData callData;
    3235                             CallType callType = getter->methodTable()->getCallData(getter, callData);
    3236                             JSValue result = call(callFrame, getter, callType, callData, baseValue, ArgList());
    3237                             CHECK_FOR_EXCEPTION();
    3238                             callFrame->uncheckedR(dst) = result;
    3239                         } else
    3240                             callFrame->uncheckedR(dst) = jsUndefined();
    3241                         vPC += OPCODE_LENGTH(op_get_by_id_getter_chain);
    3242                         NEXT_INSTRUCTION();
    3243                     }
    3244                    
    3245                     // Update baseCell, so that next time around the loop we'll pick up the prototype's prototype.
    3246                     baseCell = baseObject;
    3247                 }
    3248             }
    3249         }
    3250         uncacheGetByID(codeBlock, vPC);
    3251         NEXT_INSTRUCTION();
    3252     }
    3253 #if USE(GCC_COMPUTED_GOTO_WORKAROUND)
    3254     skip_id_getter_chain:
    3255 #endif
    3256 #if USE(GCC_COMPUTED_GOTO_WORKAROUND)
    3257     goto *(&&skip_id_custom_chain);
    3258 #endif
    3259     DEFINE_OPCODE(op_get_by_id_custom_chain) {
    3260         /* op_get_by_id_custom_chain dst(r) base(r) property(id) structure(sID) structureChain(chain) count(n) offset(n)
    3261          
    3262          Cached property access: Attempts to use a cached named property getter on the
    3263          value base's prototype chain. If the cache misses, op_get_by_id_custom_chain
    3264          reverts to op_get_by_id.
    3265          */
    3266         int base = vPC[2].u.operand;
    3267         JSValue baseValue = callFrame->r(base).jsValue();
    3268        
    3269         if (LIKELY(baseValue.isCell())) {
    3270             JSCell* baseCell = baseValue.asCell();
    3271             Structure* structure = vPC[4].u.structure.get();
    3272            
    3273             if (LIKELY(baseCell->structure() == structure)) {
    3274                 WriteBarrier<Structure>* it = vPC[5].u.structureChain->head();
    3275                 size_t count = vPC[6].u.operand;
    3276                 WriteBarrier<Structure>* end = it + count;
    3277                
    3278                 while (true) {
    3279                     JSObject* baseObject = asObject(baseCell->structure()->prototypeForLookup(callFrame));
    3280                    
    3281                     if (UNLIKELY(baseObject->structure() != (*it).get()))
    3282                         break;
    3283                    
    3284                     if (++it == end) {
    3285                         int dst = vPC[1].u.operand;
    3286                         int property = vPC[3].u.operand;
    3287                         Identifier& ident = codeBlock->identifier(property);
    3288                        
    3289                         PropertySlot::GetValueFunc getter = vPC[7].u.getterFunc;
    3290                         JSValue result = getter(callFrame, baseObject, ident);
    3291                         CHECK_FOR_EXCEPTION();
    3292                         callFrame->uncheckedR(dst) = result;
    3293                         vPC += OPCODE_LENGTH(op_get_by_id_custom_chain);
    3294                         NEXT_INSTRUCTION();
    3295                     }
    3296                    
    3297                     // Update baseCell, so that next time around the loop we'll pick up the prototype's prototype.
    3298                     baseCell = baseObject;
    3299                 }
    3300             }
    3301         }
    3302         uncacheGetByID(codeBlock, vPC);
    3303         NEXT_INSTRUCTION();
    3304     }
    3305 #if USE(GCC_COMPUTED_GOTO_WORKAROUND)
    3306     skip_id_custom_chain:
    3307     goto *(&&skip_get_array_length);
    3308 #endif
    3309     DEFINE_OPCODE(op_get_array_length) {
    3310         /* op_get_array_length dst(r) base(r) property(id) nop(sID) nop(n) nop(n) nop(n)
    3311 
    3312            Cached property access: Gets the length of the array in register base,
    3313            and puts the result in register dst. If register base does not hold
    3314            an array, op_get_array_length reverts to op_get_by_id.
    3315         */
    3316 
    3317         int base = vPC[2].u.operand;
    3318         JSValue baseValue = callFrame->r(base).jsValue();
    3319         if (LIKELY(isJSArray(baseValue))) {
    3320             int dst = vPC[1].u.operand;
    3321             callFrame->uncheckedR(dst) = jsNumber(asArray(baseValue)->length());
    3322             vPC += OPCODE_LENGTH(op_get_array_length);
    3323             NEXT_INSTRUCTION();
    3324         }
    3325 
    3326         uncacheGetByID(codeBlock, vPC);
    3327         NEXT_INSTRUCTION();
    3328     }
    3329 #if USE(GCC_COMPUTED_GOTO_WORKAROUND)
    3330     skip_get_array_length:
    3331     goto *(&&skip_get_string_length);
    3332 #endif
    3333     DEFINE_OPCODE(op_get_string_length) {
    3334         /* op_get_string_length dst(r) base(r) property(id) nop(sID) nop(n) nop(n) nop(n)
    3335 
    3336            Cached property access: Gets the length of the string in register base,
    3337            and puts the result in register dst. If register base does not hold
    3338            a string, op_get_string_length reverts to op_get_by_id.
    3339         */
    3340 
    3341         int base = vPC[2].u.operand;
    3342         JSValue baseValue = callFrame->r(base).jsValue();
    3343         if (LIKELY(isJSString(baseValue))) {
    3344             int dst = vPC[1].u.operand;
    3345             callFrame->uncheckedR(dst) = jsNumber(asString(baseValue)->length());
    3346             vPC += OPCODE_LENGTH(op_get_string_length);
    3347             NEXT_INSTRUCTION();
    3348         }
    3349 
    3350         uncacheGetByID(codeBlock, vPC);
    3351         NEXT_INSTRUCTION();
    3352     }
    3353 #if USE(GCC_COMPUTED_GOTO_WORKAROUND)
    3354     skip_get_string_length:
    3355     goto *(&&skip_put_by_id);
    3356 #endif
    3357     DEFINE_OPCODE(op_put_by_id_out_of_line)
    3358     DEFINE_OPCODE(op_put_by_id) {
    3359         /* put_by_id base(r) property(id) value(r) nop(n) nop(n) nop(n) nop(n) direct(b)
    3360 
    3361            Generic property access: Sets the property named by identifier
    3362            property, belonging to register base, to register value.
    3363 
    3364            Unlike many opcodes, this one does not write any output to
    3365            the register file.
    3366 
    3367            The "direct" flag should only be set this put_by_id is to initialize
    3368            an object literal.
    3369         */
    3370 
    3371         int base = vPC[1].u.operand;
    3372         int property = vPC[2].u.operand;
    3373         int value = vPC[3].u.operand;
    3374         int direct = vPC[8].u.operand;
    3375 
    3376         JSValue baseValue = callFrame->r(base).jsValue();
    3377         Identifier& ident = codeBlock->identifier(property);
    3378         PutPropertySlot slot(codeBlock->isStrictMode());
    3379         if (direct) {
    3380             ASSERT(baseValue.isObject());
    3381             asObject(baseValue)->putDirect(*globalData, ident, callFrame->r(value).jsValue(), slot);
    3382         } else
    3383             baseValue.put(callFrame, ident, callFrame->r(value).jsValue(), slot);
    3384         CHECK_FOR_EXCEPTION();
    3385 
    3386         tryCachePutByID(callFrame, codeBlock, vPC, baseValue, slot);
    3387 
    3388         vPC += OPCODE_LENGTH(op_put_by_id);
    3389         NEXT_INSTRUCTION();
    3390     }
    3391 #if USE(GCC_COMPUTED_GOTO_WORKAROUND)
    3392       skip_put_by_id:
    3393 #endif
    3394     DEFINE_OPCODE(op_put_by_id_transition_direct)
    3395     DEFINE_OPCODE(op_put_by_id_transition_normal)
    3396     DEFINE_OPCODE(op_put_by_id_transition_direct_out_of_line)
    3397     DEFINE_OPCODE(op_put_by_id_transition_normal_out_of_line)
    3398     DEFINE_OPCODE(op_put_by_id_transition) {
    3399         /* op_put_by_id_transition base(r) property(id) value(r) oldStructure(sID) newStructure(sID) structureChain(chain) offset(n) direct(b)
    3400          
    3401            Cached property access: Attempts to set a new property with a cached transition
    3402            property named by identifier property, belonging to register base,
    3403            to register value. If the cache misses, op_put_by_id_transition
    3404            reverts to op_put_by_id_generic.
    3405          
    3406            Unlike many opcodes, this one does not write any output to
    3407            the register file.
    3408          */
    3409         int base = vPC[1].u.operand;
    3410         JSValue baseValue = callFrame->r(base).jsValue();
    3411        
    3412         if (LIKELY(baseValue.isCell())) {
    3413             JSCell* baseCell = baseValue.asCell();
    3414             Structure* oldStructure = vPC[4].u.structure.get();
    3415             Structure* newStructure = vPC[5].u.structure.get();
    3416            
    3417             if (LIKELY(baseCell->structure() == oldStructure)) {
    3418                 ASSERT(baseCell->isObject());
    3419                 JSObject* baseObject = asObject(baseCell);
    3420                 int direct = vPC[8].u.operand;
    3421                
    3422                 if (!direct) {
    3423                     WriteBarrier<Structure>* it = vPC[6].u.structureChain->head();
    3424 
    3425                     JSValue proto = baseObject->structure()->prototypeForLookup(callFrame);
    3426                     while (!proto.isNull()) {
    3427                         if (UNLIKELY(asObject(proto)->structure() != (*it).get())) {
    3428                             uncachePutByID(codeBlock, vPC);
    3429                             NEXT_INSTRUCTION();
    3430                         }
    3431                         ++it;
    3432                         proto = asObject(proto)->structure()->prototypeForLookup(callFrame);
    3433                     }
    3434                 }
    3435                 baseObject->setStructureAndReallocateStorageIfNecessary(*globalData, newStructure);
    3436 
    3437                 int value = vPC[3].u.operand;
    3438                 int offset = vPC[7].u.operand;
    3439                 ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(*globalData, codeBlock->identifier(vPC[2].u.operand))) == offset);
    3440                 baseObject->putDirectOffset(callFrame->globalData(), offset, callFrame->r(value).jsValue());
    3441 
    3442                 vPC += OPCODE_LENGTH(op_put_by_id_transition);
    3443                 NEXT_INSTRUCTION();
    3444             }
    3445         }
    3446        
    3447         uncachePutByID(codeBlock, vPC);
    3448         NEXT_INSTRUCTION();
    3449     }
    3450     DEFINE_OPCODE(op_put_by_id_replace) {
    3451         /* op_put_by_id_replace base(r) property(id) value(r) structure(sID) offset(n) nop(n) nop(n) direct(b)
    3452 
    3453            Cached property access: Attempts to set a pre-existing, cached
    3454            property named by identifier property, belonging to register base,
    3455            to register value. If the cache misses, op_put_by_id_replace
    3456            reverts to op_put_by_id.
    3457 
    3458            Unlike many opcodes, this one does not write any output to
    3459            the register file.
    3460         */
    3461         int base = vPC[1].u.operand;
    3462         JSValue baseValue = callFrame->r(base).jsValue();
    3463 
    3464         if (LIKELY(baseValue.isCell())) {
    3465             JSCell* baseCell = baseValue.asCell();
    3466             Structure* structure = vPC[4].u.structure.get();
    3467 
    3468             if (LIKELY(baseCell->structure() == structure)) {
    3469                 ASSERT(baseCell->isObject());
    3470                 JSObject* baseObject = asObject(baseCell);
    3471                 int value = vPC[3].u.operand;
    3472                 int offset = vPC[5].u.operand;
    3473                
    3474                 ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(*globalData, codeBlock->identifier(vPC[2].u.operand))) == offset);
    3475                 baseObject->putDirectOffset(callFrame->globalData(), offset, callFrame->r(value).jsValue());
    3476 
    3477                 vPC += OPCODE_LENGTH(op_put_by_id_replace);
    3478                 NEXT_INSTRUCTION();
    3479             }
    3480         }
    3481 
    3482         uncachePutByID(codeBlock, vPC);
    3483         NEXT_INSTRUCTION();
    3484     }
    3485     DEFINE_OPCODE(op_put_by_id_generic) {
    3486         /* op_put_by_id_generic base(r) property(id) value(r) nop(n) nop(n) nop(n) nop(n) direct(b)
    3487 
    3488            Generic property access: Sets the property named by identifier
    3489            property, belonging to register base, to register value.
    3490 
    3491            Unlike many opcodes, this one does not write any output to
    3492            the register file.
    3493         */
    3494         int base = vPC[1].u.operand;
    3495         int property = vPC[2].u.operand;
    3496         int value = vPC[3].u.operand;
    3497         int direct = vPC[8].u.operand;
    3498 
    3499         JSValue baseValue = callFrame->r(base).jsValue();
    3500         Identifier& ident = codeBlock->identifier(property);
    3501         PutPropertySlot slot(codeBlock->isStrictMode());
    3502         if (direct) {
    3503             ASSERT(baseValue.isObject());
    3504             asObject(baseValue)->putDirect(*globalData, ident, callFrame->r(value).jsValue(), slot);
    3505         } else
    3506             baseValue.put(callFrame, ident, callFrame->r(value).jsValue(), slot);
    3507         CHECK_FOR_EXCEPTION();
    3508 
    3509         vPC += OPCODE_LENGTH(op_put_by_id_generic);
    3510         NEXT_INSTRUCTION();
    3511     }
    3512     DEFINE_OPCODE(op_del_by_id) {
    3513         /* del_by_id dst(r) base(r) property(id)
    3514 
    3515            Converts register base to Object, deletes the property
    3516            named by identifier property from the object, and writes a
    3517            boolean indicating success (if true) or failure (if false)
    3518            to register dst.
    3519         */
    3520         int dst = vPC[1].u.operand;
    3521         int base = vPC[2].u.operand;
    3522         int property = vPC[3].u.operand;
    3523 
    3524         JSObject* baseObj = callFrame->r(base).jsValue().toObject(callFrame);
    3525         Identifier& ident = codeBlock->identifier(property);
    3526         bool result = baseObj->methodTable()->deleteProperty(baseObj, callFrame, ident);
    3527         if (!result && codeBlock->isStrictMode()) {
    3528             exceptionValue = createTypeError(callFrame, "Unable to delete property.");
    3529             goto vm_throw;
    3530         }
    3531         CHECK_FOR_EXCEPTION();
    3532         callFrame->uncheckedR(dst) = jsBoolean(result);
    3533         vPC += OPCODE_LENGTH(op_del_by_id);
    3534         NEXT_INSTRUCTION();
    3535     }
    3536     DEFINE_OPCODE(op_get_by_pname) {
    3537         int dst = vPC[1].u.operand;
    3538         int base = vPC[2].u.operand;
    3539         int property = vPC[3].u.operand;
    3540         int expected = vPC[4].u.operand;
    3541         int iter = vPC[5].u.operand;
    3542         int i = vPC[6].u.operand;
    3543 
    3544         JSValue baseValue = callFrame->r(base).jsValue();
    3545         JSPropertyNameIterator* it = callFrame->r(iter).propertyNameIterator();
    3546         JSValue subscript = callFrame->r(property).jsValue();
    3547         JSValue expectedSubscript = callFrame->r(expected).jsValue();
    3548         int index = callFrame->r(i).i() - 1;
    3549         JSValue result;
    3550         PropertyOffset offset = 0;
    3551         if (subscript == expectedSubscript && baseValue.isCell() && (baseValue.asCell()->structure() == it->cachedStructure()) && it->getOffset(index, offset)) {
    3552             callFrame->uncheckedR(dst) = JSValue(asObject(baseValue)->getDirectOffset(offset));
    3553             vPC += OPCODE_LENGTH(op_get_by_pname);
    3554             NEXT_INSTRUCTION();
    3555         }
    3556         {
    3557             Identifier propertyName(callFrame, subscript.toString(callFrame)->value(callFrame));
    3558             result = baseValue.get(callFrame, propertyName);
    3559         }
    3560         CHECK_FOR_EXCEPTION();
    3561         callFrame->uncheckedR(dst) = result;
    3562         vPC += OPCODE_LENGTH(op_get_by_pname);
    3563         NEXT_INSTRUCTION();
    3564     }
    3565     DEFINE_OPCODE(op_get_arguments_length) {
    3566         int dst = vPC[1].u.operand;
    3567         int argumentsRegister = vPC[2].u.operand;
    3568         int property = vPC[3].u.operand;
    3569         JSValue arguments = callFrame->r(argumentsRegister).jsValue();
    3570         if (arguments) {
    3571             Identifier& ident = codeBlock->identifier(property);
    3572             PropertySlot slot(arguments);
    3573             JSValue result = arguments.get(callFrame, ident, slot);
    3574             CHECK_FOR_EXCEPTION();
    3575             callFrame->uncheckedR(dst) = result;
    3576         } else
    3577             callFrame->uncheckedR(dst) = jsNumber(callFrame->argumentCount());
    3578 
    3579         vPC += OPCODE_LENGTH(op_get_arguments_length);
    3580         NEXT_INSTRUCTION();
    3581     }
    3582     DEFINE_OPCODE(op_get_argument_by_val) {
    3583         int dst = vPC[1].u.operand;
    3584         int argumentsRegister = vPC[2].u.operand;
    3585         int property = vPC[3].u.operand;
    3586         JSValue arguments = callFrame->r(argumentsRegister).jsValue();
    3587         JSValue subscript = callFrame->r(property).jsValue();
    3588         if (!arguments && subscript.isUInt32() && subscript.asUInt32() < callFrame->argumentCount()) {
    3589             callFrame->uncheckedR(dst) = callFrame->argument(subscript.asUInt32());
    3590             vPC += OPCODE_LENGTH(op_get_argument_by_val);
    3591             NEXT_INSTRUCTION();
    3592         }
    3593         if (!arguments) {
    3594             Arguments* arguments = Arguments::create(*globalData, callFrame);
    3595             callFrame->uncheckedR(argumentsRegister) = JSValue(arguments);
    3596             callFrame->uncheckedR(unmodifiedArgumentsRegister(argumentsRegister)) = JSValue(arguments);
    3597         }
    3598         // fallthrough
    3599     }
    3600     DEFINE_OPCODE(op_get_by_val) {
    3601         /* get_by_val dst(r) base(r) property(r)
    3602 
    3603            Converts register base to Object, gets the property named
    3604            by register property from the object, and puts the result
    3605            in register dst. property is nominally converted to string
    3606            but numbers are treated more efficiently.
    3607         */
    3608         int dst = vPC[1].u.operand;
    3609         int base = vPC[2].u.operand;
    3610         int property = vPC[3].u.operand;
    3611        
    3612         JSValue baseValue = callFrame->r(base).jsValue();
    3613         JSValue subscript = callFrame->r(property).jsValue();
    3614 
    3615         JSValue result;
    3616 
    3617         if (LIKELY(subscript.isUInt32())) {
    3618             uint32_t i = subscript.asUInt32();
    3619             if (isJSArray(baseValue)) {
    3620                 JSArray* jsArray = asArray(baseValue);
    3621                 if (jsArray->canGetIndexQuickly(i))
    3622                     result = jsArray->getIndexQuickly(i);
    3623                 else
    3624                     result = jsArray->JSArray::get(callFrame, i);
    3625             } else if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
    3626                 result = asString(baseValue)->getIndex(callFrame, i);
    3627             else
    3628                 result = baseValue.get(callFrame, i);
    3629         } else if (isName(subscript))
    3630             result = baseValue.get(callFrame, jsCast<NameInstance*>(subscript.asCell())->privateName());
    3631         else {
    3632             Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
    3633             result = baseValue.get(callFrame, property);
    3634         }
    3635 
    3636         CHECK_FOR_EXCEPTION();
    3637         callFrame->uncheckedR(dst) = result;
    3638         vPC += OPCODE_LENGTH(op_get_by_val);
    3639         NEXT_INSTRUCTION();
    3640     }
    3641     DEFINE_OPCODE(op_put_by_val) {
    3642         /* put_by_val base(r) property(r) value(r)
    3643 
    3644            Sets register value on register base as the property named
    3645            by register property. Base is converted to object
    3646            first. register property is nominally converted to string
    3647            but numbers are treated more efficiently.
    3648 
    3649            Unlike many opcodes, this one does not write any output to
    3650            the register file.
    3651         */
    3652         int base = vPC[1].u.operand;
    3653         int property = vPC[2].u.operand;
    3654         int value = vPC[3].u.operand;
    3655 
    3656         JSValue baseValue = callFrame->r(base).jsValue();
    3657         JSValue subscript = callFrame->r(property).jsValue();
    3658 
    3659         if (LIKELY(subscript.isUInt32())) {
    3660             uint32_t i = subscript.asUInt32();
    3661             if (isJSArray(baseValue)) {
    3662                 JSArray* jsArray = asArray(baseValue);
    3663                 if (jsArray->canSetIndexQuickly(i))
    3664                     jsArray->setIndexQuickly(*globalData, i, callFrame->r(value).jsValue());
    3665                 else
    3666                     jsArray->JSArray::putByIndex(jsArray, callFrame, i, callFrame->r(value).jsValue(), codeBlock->isStrictMode());
    3667             } else
    3668                 baseValue.putByIndex(callFrame, i, callFrame->r(value).jsValue(), codeBlock->isStrictMode());
    3669         } else if (isName(subscript)) {
    3670             PutPropertySlot slot(codeBlock->isStrictMode());
    3671             baseValue.put(callFrame, jsCast<NameInstance*>(subscript.asCell())->privateName(), callFrame->r(value).jsValue(), slot);
    3672         } else {
    3673             Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
    3674             if (!globalData->exception) { // Don't put to an object if toString threw an exception.
    3675                 PutPropertySlot slot(codeBlock->isStrictMode());
    3676                 baseValue.put(callFrame, property, callFrame->r(value).jsValue(), slot);
    3677             }
    3678         }
    3679 
    3680         CHECK_FOR_EXCEPTION();
    3681         vPC += OPCODE_LENGTH(op_put_by_val);
    3682         NEXT_INSTRUCTION();
    3683     }
    3684     DEFINE_OPCODE(op_del_by_val) {
    3685         /* del_by_val dst(r) base(r) property(r)
    3686 
    3687            Converts register base to Object, deletes the property
    3688            named by register property from the object, and writes a
    3689            boolean indicating success (if true) or failure (if false)
    3690            to register dst.
    3691         */
    3692         int dst = vPC[1].u.operand;
    3693         int base = vPC[2].u.operand;
    3694         int property = vPC[3].u.operand;
    3695 
    3696         JSObject* baseObj = callFrame->r(base).jsValue().toObject(callFrame); // may throw
    3697 
    3698         JSValue subscript = callFrame->r(property).jsValue();
    3699         bool result;
    3700         uint32_t i;
    3701         if (subscript.getUInt32(i))
    3702             result = baseObj->methodTable()->deletePropertyByIndex(baseObj, callFrame, i);
    3703         else if (isName(subscript))
    3704             result = baseObj->methodTable()->deleteProperty(baseObj, callFrame, jsCast<NameInstance*>(subscript.asCell())->privateName());
    3705         else {
    3706             CHECK_FOR_EXCEPTION();
    3707             Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
    3708             CHECK_FOR_EXCEPTION();
    3709             result = baseObj->methodTable()->deleteProperty(baseObj, callFrame, property);
    3710         }
    3711         if (!result && codeBlock->isStrictMode()) {
    3712             exceptionValue = createTypeError(callFrame, "Unable to delete property.");
    3713             goto vm_throw;
    3714         }
    3715         CHECK_FOR_EXCEPTION();
    3716         callFrame->uncheckedR(dst) = jsBoolean(result);
    3717         vPC += OPCODE_LENGTH(op_del_by_val);
    3718         NEXT_INSTRUCTION();
    3719     }
    3720     DEFINE_OPCODE(op_put_by_index) {
    3721         /* put_by_index base(r) property(n) value(r)
    3722 
    3723            Sets register value on register base as the property named
    3724            by the immediate number property. Base is converted to
    3725            object first.
    3726 
    3727            Unlike many opcodes, this one does not write any output to
    3728            the register file.
    3729 
    3730            This opcode is mainly used to initialize array literals.
    3731         */
    3732         int base = vPC[1].u.operand;
    3733         unsigned property = vPC[2].u.operand;
    3734         int value = vPC[3].u.operand;
    3735 
    3736         JSValue arrayValue = callFrame->r(base).jsValue();
    3737         ASSERT(isJSArray(arrayValue));
    3738         asArray(arrayValue)->putDirectIndex(callFrame, property, callFrame->r(value).jsValue());
    3739 
    3740         vPC += OPCODE_LENGTH(op_put_by_index);
    3741         NEXT_INSTRUCTION();
    3742     }
    3743     DEFINE_OPCODE(op_loop) {
    3744         /* loop target(offset)
    3745          
    3746            Jumps unconditionally to offset target from the current
    3747            instruction.
    3748 
    3749            Additionally this loop instruction may terminate JS execution is
    3750            the JS timeout is reached.
    3751          */
    3752 #if ENABLE(OPCODE_STATS)
    3753         OpcodeStats::resetLastInstruction();
    3754 #endif
    3755         int target = vPC[1].u.operand;
    3756         CHECK_FOR_TIMEOUT();
    3757         vPC += target;
    3758         NEXT_INSTRUCTION();
    3759     }
    3760     DEFINE_OPCODE(op_jmp) {
    3761         /* jmp target(offset)
    3762 
    3763            Jumps unconditionally to offset target from the current
    3764            instruction.
    3765         */
    3766 #if ENABLE(OPCODE_STATS)
    3767         OpcodeStats::resetLastInstruction();
    3768 #endif
    3769         int target = vPC[1].u.operand;
    3770 
    3771         vPC += target;
    3772         NEXT_INSTRUCTION();
    3773     }
    3774     DEFINE_OPCODE(op_loop_hint) {
    3775         // This is a no-op unless we intend on doing OSR from the interpreter.
    3776         vPC += OPCODE_LENGTH(op_loop_hint);
    3777         NEXT_INSTRUCTION();
    3778     }
    3779     DEFINE_OPCODE(op_loop_if_true) {
    3780         /* loop_if_true cond(r) target(offset)
    3781          
    3782            Jumps to offset target from the current instruction, if and
    3783            only if register cond converts to boolean as true.
    3784 
    3785            Additionally this loop instruction may terminate JS execution is
    3786            the JS timeout is reached.
    3787          */
    3788         int cond = vPC[1].u.operand;
    3789         int target = vPC[2].u.operand;
    3790         if (callFrame->r(cond).jsValue().toBoolean(callFrame)) {
    3791             vPC += target;
    3792             CHECK_FOR_TIMEOUT();
    3793             NEXT_INSTRUCTION();
    3794         }
    3795        
    3796         vPC += OPCODE_LENGTH(op_loop_if_true);
    3797         NEXT_INSTRUCTION();
    3798     }
    3799     DEFINE_OPCODE(op_loop_if_false) {
    3800         /* loop_if_true cond(r) target(offset)
    3801          
    3802            Jumps to offset target from the current instruction, if and
    3803            only if register cond converts to boolean as false.
    3804 
    3805            Additionally this loop instruction may terminate JS execution is
    3806            the JS timeout is reached.
    3807          */
    3808         int cond = vPC[1].u.operand;
    3809         int target = vPC[2].u.operand;
    3810         if (!callFrame->r(cond).jsValue().toBoolean(callFrame)) {
    3811             vPC += target;
    3812             CHECK_FOR_TIMEOUT();
    3813             NEXT_INSTRUCTION();
    3814         }
    3815        
    3816         vPC += OPCODE_LENGTH(op_loop_if_true);
    3817         NEXT_INSTRUCTION();
    3818     }
    3819     DEFINE_OPCODE(op_jtrue) {
    3820         /* jtrue cond(r) target(offset)
    3821 
    3822            Jumps to offset target from the current instruction, if and
    3823            only if register cond converts to boolean as true.
    3824         */
    3825         int cond = vPC[1].u.operand;
    3826         int target = vPC[2].u.operand;
    3827         if (callFrame->r(cond).jsValue().toBoolean(callFrame)) {
    3828             vPC += target;
    3829             NEXT_INSTRUCTION();
    3830         }
    3831 
    3832         vPC += OPCODE_LENGTH(op_jtrue);
    3833         NEXT_INSTRUCTION();
    3834     }
    3835     DEFINE_OPCODE(op_jfalse) {
    3836         /* jfalse cond(r) target(offset)
    3837 
    3838            Jumps to offset target from the current instruction, if and
    3839            only if register cond converts to boolean as false.
    3840         */
    3841         int cond = vPC[1].u.operand;
    3842         int target = vPC[2].u.operand;
    3843         if (!callFrame->r(cond).jsValue().toBoolean(callFrame)) {
    3844             vPC += target;
    3845             NEXT_INSTRUCTION();
    3846         }
    3847 
    3848         vPC += OPCODE_LENGTH(op_jfalse);
    3849         NEXT_INSTRUCTION();
    3850     }
    3851     DEFINE_OPCODE(op_jeq_null) {
    3852         /* jeq_null src(r) target(offset)
    3853 
    3854            Jumps to offset target from the current instruction, if and
    3855            only if register src is null.
    3856         */
    3857         int src = vPC[1].u.operand;
    3858         int target = vPC[2].u.operand;
    3859         JSValue srcValue = callFrame->r(src).jsValue();
    3860 
    3861         if (srcValue.isUndefinedOrNull() || (srcValue.isCell() && srcValue.asCell()->structure()->masqueradesAsUndefined(callFrame->lexicalGlobalObject()))) {
    3862             vPC += target;
    3863             NEXT_INSTRUCTION();
    3864         }
    3865 
    3866         vPC += OPCODE_LENGTH(op_jeq_null);
    3867         NEXT_INSTRUCTION();
    3868     }
    3869     DEFINE_OPCODE(op_jneq_null) {
    3870         /* jneq_null src(r) target(offset)
    3871 
    3872            Jumps to offset target from the current instruction, if and
    3873            only if register src is not null.
    3874         */
    3875         int src = vPC[1].u.operand;
    3876         int target = vPC[2].u.operand;
    3877         JSValue srcValue = callFrame->r(src).jsValue();
    3878 
    3879         if (!srcValue.isUndefinedOrNull() && (!srcValue.isCell() || !(srcValue.asCell()->structure()->masqueradesAsUndefined(callFrame->lexicalGlobalObject())))) {
    3880             vPC += target;
    3881             NEXT_INSTRUCTION();
    3882         }
    3883 
    3884         vPC += OPCODE_LENGTH(op_jneq_null);
    3885         NEXT_INSTRUCTION();
    3886     }
    3887     DEFINE_OPCODE(op_jneq_ptr) {
    3888         /* jneq_ptr src(r) ptr(jsCell) target(offset)
    3889          
    3890            Jumps to offset target from the current instruction, if the value r is equal
    3891            to ptr, using pointer equality.
    3892          */
    3893         int src = vPC[1].u.operand;
    3894         int target = vPC[3].u.operand;
    3895         JSValue srcValue = callFrame->r(src).jsValue();
    3896         if (srcValue != vPC[2].u.jsCell.get()) {
    3897             vPC += target;
    3898             NEXT_INSTRUCTION();
    3899         }
    3900 
    3901         vPC += OPCODE_LENGTH(op_jneq_ptr);
    3902         NEXT_INSTRUCTION();
    3903     }
    3904     DEFINE_OPCODE(op_loop_if_less) {
    3905         /* loop_if_less src1(r) src2(r) target(offset)
    3906 
    3907            Checks whether register src1 is less than register src2, as
    3908            with the ECMAScript '<' operator, and then jumps to offset
    3909            target from the current instruction, if and only if the
    3910            result of the comparison is true.
    3911 
    3912            Additionally this loop instruction may terminate JS execution is
    3913            the JS timeout is reached.
    3914          */
    3915         JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
    3916         JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
    3917         int target = vPC[3].u.operand;
    3918        
    3919         bool result = jsLess<true>(callFrame, src1, src2);
    3920         CHECK_FOR_EXCEPTION();
    3921        
    3922         if (result) {
    3923             vPC += target;
    3924             CHECK_FOR_TIMEOUT();
    3925             NEXT_INSTRUCTION();
    3926         }
    3927        
    3928         vPC += OPCODE_LENGTH(op_loop_if_less);
    3929         NEXT_INSTRUCTION();
    3930     }
    3931     DEFINE_OPCODE(op_loop_if_lesseq) {
    3932         /* loop_if_lesseq src1(r) src2(r) target(offset)
    3933 
    3934            Checks whether register src1 is less than or equal to register
    3935            src2, as with the ECMAScript '<=' operator, and then jumps to
    3936            offset target from the current instruction, if and only if the
    3937            result of the comparison is true.
    3938 
    3939            Additionally this loop instruction may terminate JS execution is
    3940            the JS timeout is reached.
    3941         */
    3942         JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
    3943         JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
    3944         int target = vPC[3].u.operand;
    3945        
    3946         bool result = jsLessEq<true>(callFrame, src1, src2);
    3947         CHECK_FOR_EXCEPTION();
    3948        
    3949         if (result) {
    3950             vPC += target;
    3951             CHECK_FOR_TIMEOUT();
    3952             NEXT_INSTRUCTION();
    3953         }
    3954        
    3955         vPC += OPCODE_LENGTH(op_loop_if_lesseq);
    3956         NEXT_INSTRUCTION();
    3957     }
    3958     DEFINE_OPCODE(op_loop_if_greater) {
    3959         /* loop_if_greater src1(r) src2(r) target(offset)
    3960 
    3961            Checks whether register src1 is greater than register src2, as
    3962            with the ECMAScript '>' operator, and then jumps to offset
    3963            target from the current instruction, if and only if the
    3964            result of the comparison is true.
    3965 
    3966            Additionally this loop instruction may terminate JS execution is
    3967            the JS timeout is reached.
    3968          */
    3969         JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
    3970         JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
    3971         int target = vPC[3].u.operand;
    3972        
    3973         bool result = jsLess<false>(callFrame, src2, src1);
    3974         CHECK_FOR_EXCEPTION();
    3975        
    3976         if (result) {
    3977             vPC += target;
    3978             CHECK_FOR_TIMEOUT();
    3979             NEXT_INSTRUCTION();
    3980         }
    3981        
    3982         vPC += OPCODE_LENGTH(op_loop_if_greater);
    3983         NEXT_INSTRUCTION();
    3984     }
    3985     DEFINE_OPCODE(op_loop_if_greatereq) {
    3986         /* loop_if_greatereq src1(r) src2(r) target(offset)
    3987 
    3988            Checks whether register src1 is greater than or equal to register
    3989            src2, as with the ECMAScript '>=' operator, and then jumps to
    3990            offset target from the current instruction, if and only if the
    3991            result of the comparison is true.
    3992 
    3993            Additionally this loop instruction may terminate JS execution is
    3994            the JS timeout is reached.
    3995         */
    3996         JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
    3997         JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
    3998         int target = vPC[3].u.operand;
    3999        
    4000         bool result = jsLessEq<false>(callFrame, src2, src1);
    4001         CHECK_FOR_EXCEPTION();
    4002        
    4003         if (result) {
    4004             vPC += target;
    4005             CHECK_FOR_TIMEOUT();
    4006             NEXT_INSTRUCTION();
    4007         }
    4008        
    4009         vPC += OPCODE_LENGTH(op_loop_if_greatereq);
    4010         NEXT_INSTRUCTION();
    4011     }
    4012     DEFINE_OPCODE(op_jless) {
    4013         /* jless src1(r) src2(r) target(offset)
    4014 
    4015            Checks whether register src1 is less than register src2, as
    4016            with the ECMAScript '<' operator, and then jumps to offset
    4017            target from the current instruction, if and only if the
    4018            result of the comparison is true.
    4019         */
    4020         JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
    4021         JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
    4022         int target = vPC[3].u.operand;
    4023 
    4024         bool result = jsLess<true>(callFrame, src1, src2);
    4025         CHECK_FOR_EXCEPTION();
    4026        
    4027         if (result) {
    4028             vPC += target;
    4029             NEXT_INSTRUCTION();
    4030         }
    4031 
    4032         vPC += OPCODE_LENGTH(op_jless);
    4033         NEXT_INSTRUCTION();
    4034     }
    4035     DEFINE_OPCODE(op_jlesseq) {
    4036         /* jlesseq src1(r) src2(r) target(offset)
    4037          
    4038          Checks whether register src1 is less than or equal to
    4039          register src2, as with the ECMAScript '<=' operator,
    4040          and then jumps to offset target from the current instruction,
    4041          if and only if the result of the comparison is true.
    4042          */
    4043         JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
    4044         JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
    4045         int target = vPC[3].u.operand;
    4046        
    4047         bool result = jsLessEq<true>(callFrame, src1, src2);
    4048         CHECK_FOR_EXCEPTION();
    4049        
    4050         if (result) {
    4051             vPC += target;
    4052             NEXT_INSTRUCTION();
    4053         }
    4054        
    4055         vPC += OPCODE_LENGTH(op_jlesseq);
    4056         NEXT_INSTRUCTION();
    4057     }
    4058     DEFINE_OPCODE(op_jgreater) {
    4059         /* jgreater src1(r) src2(r) target(offset)
    4060 
    4061            Checks whether register src1 is greater than register src2, as
    4062            with the ECMAScript '>' operator, and then jumps to offset
    4063            target from the current instruction, if and only if the
    4064            result of the comparison is true.
    4065         */
    4066         JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
    4067         JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
    4068         int target = vPC[3].u.operand;
    4069 
    4070         bool result = jsLess<false>(callFrame, src2, src1);
    4071         CHECK_FOR_EXCEPTION();
    4072        
    4073         if (result) {
    4074             vPC += target;
    4075             NEXT_INSTRUCTION();
    4076         }
    4077 
    4078         vPC += OPCODE_LENGTH(op_jgreater);
    4079         NEXT_INSTRUCTION();
    4080     }
    4081     DEFINE_OPCODE(op_jgreatereq) {
    4082         /* jgreatereq src1(r) src2(r) target(offset)
    4083          
    4084          Checks whether register src1 is greater than or equal to
    4085          register src2, as with the ECMAScript '>=' operator,
    4086          and then jumps to offset target from the current instruction,
    4087          if and only if the result of the comparison is true.
    4088          */
    4089         JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
    4090         JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
    4091         int target = vPC[3].u.operand;
    4092        
    4093         bool result = jsLessEq<false>(callFrame, src2, src1);
    4094         CHECK_FOR_EXCEPTION();
    4095        
    4096         if (result) {
    4097             vPC += target;
    4098             NEXT_INSTRUCTION();
    4099         }
    4100        
    4101         vPC += OPCODE_LENGTH(op_jgreatereq);
    4102         NEXT_INSTRUCTION();
    4103     }
    4104     DEFINE_OPCODE(op_jnless) {
    4105         /* jnless src1(r) src2(r) target(offset)
    4106 
    4107            Checks whether register src1 is less than register src2, as
    4108            with the ECMAScript '<' operator, and then jumps to offset
    4109            target from the current instruction, if and only if the
    4110            result of the comparison is false.
    4111         */
    4112         JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
    4113         JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
    4114         int target = vPC[3].u.operand;
    4115 
    4116         bool result = jsLess<true>(callFrame, src1, src2);
    4117         CHECK_FOR_EXCEPTION();
    4118        
    4119         if (!result) {
    4120             vPC += target;
    4121             NEXT_INSTRUCTION();
    4122         }
    4123 
    4124         vPC += OPCODE_LENGTH(op_jnless);
    4125         NEXT_INSTRUCTION();
    4126     }
    4127     DEFINE_OPCODE(op_jnlesseq) {
    4128         /* jnlesseq src1(r) src2(r) target(offset)
    4129 
    4130            Checks whether register src1 is less than or equal to
    4131            register src2, as with the ECMAScript '<=' operator,
    4132            and then jumps to offset target from the current instruction,
    4133            if and only if theresult of the comparison is false.
    4134         */
    4135         JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
    4136         JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
    4137         int target = vPC[3].u.operand;
    4138 
    4139         bool result = jsLessEq<true>(callFrame, src1, src2);
    4140         CHECK_FOR_EXCEPTION();
    4141        
    4142         if (!result) {
    4143             vPC += target;
    4144             NEXT_INSTRUCTION();
    4145         }
    4146 
    4147         vPC += OPCODE_LENGTH(op_jnlesseq);
    4148         NEXT_INSTRUCTION();
    4149     }
    4150     DEFINE_OPCODE(op_jngreater) {
    4151         /* jngreater src1(r) src2(r) target(offset)
    4152 
    4153            Checks whether register src1 is greater than register src2, as
    4154            with the ECMAScript '>' operator, and then jumps to offset
    4155            target from the current instruction, if and only if the
    4156            result of the comparison is false.
    4157         */
    4158         JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
    4159         JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
    4160         int target = vPC[3].u.operand;
    4161 
    4162         bool result = jsLess<false>(callFrame, src2, src1);
    4163         CHECK_FOR_EXCEPTION();
    4164        
    4165         if (!result) {
    4166             vPC += target;
    4167             NEXT_INSTRUCTION();
    4168         }
    4169 
    4170         vPC += OPCODE_LENGTH(op_jngreater);
    4171         NEXT_INSTRUCTION();
    4172     }
    4173     DEFINE_OPCODE(op_jngreatereq) {
    4174         /* jngreatereq src1(r) src2(r) target(offset)
    4175 
    4176            Checks whether register src1 is greater than or equal to
    4177            register src2, as with the ECMAScript '>=' operator,
    4178            and then jumps to offset target from the current instruction,
    4179            if and only if theresult of the comparison is false.
    4180         */
    4181         JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
    4182         JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
    4183         int target = vPC[3].u.operand;
    4184 
    4185         bool result = jsLessEq<false>(callFrame, src2, src1);
    4186         CHECK_FOR_EXCEPTION();
    4187        
    4188         if (!result) {
    4189             vPC += target;
    4190             NEXT_INSTRUCTION();
    4191         }
    4192 
    4193         vPC += OPCODE_LENGTH(op_jngreatereq);
    4194         NEXT_INSTRUCTION();
    4195     }
    4196     DEFINE_OPCODE(op_switch_imm) {
    4197         /* switch_imm tableIndex(n) defaultOffset(offset) scrutinee(r)
    4198 
    4199            Performs a range checked switch on the scrutinee value, using
    4200            the tableIndex-th immediate switch jump table.  If the scrutinee value
    4201            is an immediate number in the range covered by the referenced jump
    4202            table, and the value at jumpTable[scrutinee value] is non-zero, then
    4203            that value is used as the jump offset, otherwise defaultOffset is used.
    4204          */
    4205         int tableIndex = vPC[1].u.operand;
    4206         int defaultOffset = vPC[2].u.operand;
    4207         JSValue scrutinee = callFrame->r(vPC[3].u.operand).jsValue();
    4208         if (scrutinee.isInt32())
    4209             vPC += codeBlock->immediateSwitchJumpTable(tableIndex).offsetForValue(scrutinee.asInt32(), defaultOffset);
    4210         else if (scrutinee.isDouble() && scrutinee.asDouble() == static_cast<int32_t>(scrutinee.asDouble()))
    4211             vPC += codeBlock->immediateSwitchJumpTable(tableIndex).offsetForValue(static_cast<int32_t>(scrutinee.asDouble()), defaultOffset);
    4212         else
    4213             vPC += defaultOffset;
    4214         NEXT_INSTRUCTION();
    4215     }
    4216     DEFINE_OPCODE(op_switch_char) {
    4217         /* switch_char tableIndex(n) defaultOffset(offset) scrutinee(r)
    4218 
    4219            Performs a range checked switch on the scrutinee value, using
    4220            the tableIndex-th character switch jump table.  If the scrutinee value
    4221            is a single character string in the range covered by the referenced jump
    4222            table, and the value at jumpTable[scrutinee value] is non-zero, then
    4223            that value is used as the jump offset, otherwise defaultOffset is used.
    4224          */
    4225         int tableIndex = vPC[1].u.operand;
    4226         int defaultOffset = vPC[2].u.operand;
    4227         JSValue scrutinee = callFrame->r(vPC[3].u.operand).jsValue();
    4228         if (!scrutinee.isString())
    4229             vPC += defaultOffset;
    4230         else {
    4231             StringImpl* value = asString(scrutinee)->value(callFrame).impl();
    4232             if (value->length() != 1)
    4233                 vPC += defaultOffset;
    4234             else
    4235                 vPC += codeBlock->characterSwitchJumpTable(tableIndex).offsetForValue((*value)[0], defaultOffset);
    4236         }
    4237         NEXT_INSTRUCTION();
    4238     }
    4239     DEFINE_OPCODE(op_switch_string) {
    4240         /* switch_string tableIndex(n) defaultOffset(offset) scrutinee(r)
    4241 
    4242            Performs a sparse hashmap based switch on the value in the scrutinee
    4243            register, using the tableIndex-th string switch jump table.  If the
    4244            scrutinee value is a string that exists as a key in the referenced
    4245            jump table, then the value associated with the string is used as the
    4246            jump offset, otherwise defaultOffset is used.
    4247          */
    4248         int tableIndex = vPC[1].u.operand;
    4249         int defaultOffset = vPC[2].u.operand;
    4250         JSValue scrutinee = callFrame->r(vPC[3].u.operand).jsValue();
    4251         if (!scrutinee.isString())
    4252             vPC += defaultOffset;
    4253         else
    4254             vPC += codeBlock->stringSwitchJumpTable(tableIndex).offsetForValue(asString(scrutinee)->value(callFrame).impl(), defaultOffset);
    4255         NEXT_INSTRUCTION();
    4256     }
    4257     DEFINE_OPCODE(op_new_func) {
    4258         /* new_func dst(r) func(f)
    4259 
    4260            Constructs a new Function instance from function func and
    4261            the current scope chain using the original Function
    4262            constructor, using the rules for function declarations, and
    4263            puts the result in register dst.
    4264         */
    4265         int dst = vPC[1].u.operand;
    4266         int func = vPC[2].u.operand;
    4267         int shouldCheck = vPC[3].u.operand;
    4268         ASSERT(codeBlock->codeType() != FunctionCode || !codeBlock->needsFullScopeChain() || callFrame->r(codeBlock->activationRegister()).jsValue());
    4269         if (!shouldCheck || !callFrame->r(dst).jsValue())
    4270             callFrame->uncheckedR(dst) = JSValue(JSFunction::create(callFrame, codeBlock->functionDecl(func), callFrame->scope()));
    4271 
    4272         vPC += OPCODE_LENGTH(op_new_func);
    4273         NEXT_INSTRUCTION();
    4274     }
    4275     DEFINE_OPCODE(op_new_func_exp) {
    4276         /* new_func_exp dst(r) func(f)
    4277 
    4278            Constructs a new Function instance from function func and
    4279            the current scope chain using the original Function
    4280            constructor, using the rules for function expressions, and
    4281            puts the result in register dst.
    4282         */
    4283         int dst = vPC[1].u.operand;
    4284         int funcIndex = vPC[2].u.operand;
    4285        
    4286         ASSERT(codeBlock->codeType() != FunctionCode || !codeBlock->needsFullScopeChain() || callFrame->r(codeBlock->activationRegister()).jsValue());
    4287         FunctionExecutable* function = codeBlock->functionExpr(funcIndex);
    4288         JSFunction* func = JSFunction::create(callFrame, function, callFrame->scope());
    4289 
    4290         callFrame->uncheckedR(dst) = JSValue(func);
    4291 
    4292         vPC += OPCODE_LENGTH(op_new_func_exp);
    4293         NEXT_INSTRUCTION();
    4294     }
    4295     DEFINE_OPCODE(op_call_eval) {
    4296         /* call_eval func(r) argCount(n) registerOffset(n)
    4297 
    4298            Call a function named "eval" with no explicit "this" value
    4299            (which may therefore be the eval operator). If register
    4300            thisVal is the global object, and register func contains
    4301            that global object's original global eval function, then
    4302            perform the eval operator in local scope (interpreting
    4303            the argument registers as for the "call"
    4304            opcode). Otherwise, act exactly as the "call" opcode would.
    4305          */
    4306 
    4307         int func = vPC[1].u.operand;
    4308         int argCount = vPC[2].u.operand;
    4309         int registerOffset = vPC[3].u.operand;
    4310        
    4311         ASSERT(codeBlock->codeType() != FunctionCode || !codeBlock->needsFullScopeChain() || callFrame->r(codeBlock->activationRegister()).jsValue());
    4312         JSValue funcVal = callFrame->r(func).jsValue();
    4313 
    4314         if (isHostFunction(funcVal, globalFuncEval)) {
    4315             CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset);
    4316             newCallFrame->init(0, vPC + OPCODE_LENGTH(op_call_eval), callFrame->scope(), callFrame, argCount, jsCast<JSFunction*>(funcVal));
    4317 
    4318             JSValue result = eval(newCallFrame);
    4319             if ((exceptionValue = globalData->exception))
    4320                 goto vm_throw;
    4321             functionReturnValue = result;
    4322 
    4323             vPC += OPCODE_LENGTH(op_call_eval);
    4324             NEXT_INSTRUCTION();
    4325         }
    4326 
    4327         // We didn't find the blessed version of eval, so process this
    4328         // instruction as a normal function call.
    4329         // fall through to op_call
    4330     }
    4331     DEFINE_OPCODE(op_call) {
    4332         /* call func(r) argCount(n) registerOffset(n)
    4333 
    4334            Perform a function call.
    4335            
    4336            registerOffset is the distance the callFrame pointer should move
    4337            before the VM initializes the new call frame's header.
    4338            
    4339            dst is where op_ret should store its result.
    4340          */
    4341 
    4342         int func = vPC[1].u.operand;
    4343         int argCount = vPC[2].u.operand;
    4344         int registerOffset = vPC[3].u.operand;
    4345 
    4346         JSValue v = callFrame->r(func).jsValue();
    4347 
    4348         CallData callData;
    4349         CallType callType = getCallData(v, callData);
    4350 
    4351         if (callType == CallTypeJS) {
    4352             JSScope* callDataScope = callData.js.scope;
    4353 
    4354             JSObject* error = callData.js.functionExecutable->compileForCall(callFrame, callDataScope);
    4355             if (UNLIKELY(!!error)) {
    4356                 exceptionValue = error;
    4357                 goto vm_throw;
    4358             }
    4359 
    4360             CallFrame* previousCallFrame = callFrame;
    4361             CodeBlock* newCodeBlock = &callData.js.functionExecutable->generatedBytecodeForCall();
    4362             callFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, callFrame, registerOffset, argCount);
    4363             if (UNLIKELY(!callFrame)) {
    4364                 callFrame = previousCallFrame;
    4365                 exceptionValue = createStackOverflowError(callFrame);
    4366                 goto vm_throw;
    4367             }
    4368 
    4369             callFrame->init(newCodeBlock, vPC + OPCODE_LENGTH(op_call), callDataScope, previousCallFrame, argCount, jsCast<JSFunction*>(v));
    4370             codeBlock = newCodeBlock;
    4371             ASSERT(codeBlock == callFrame->codeBlock());
    4372             *topCallFrameSlot = callFrame;
    4373             vPC = newCodeBlock->instructions().begin();
    4374 
    4375 #if ENABLE(OPCODE_STATS)
    4376             OpcodeStats::resetLastInstruction();
    4377 #endif
    4378 
    4379             NEXT_INSTRUCTION();
    4380         }
    4381 
    4382         if (callType == CallTypeHost) {
    4383             JSScope* scope = callFrame->scope();
    4384             CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset);
    4385             newCallFrame->init(0, vPC + OPCODE_LENGTH(op_call), scope, callFrame, argCount, asObject(v));
    4386             JSValue returnValue;
    4387             {
    4388                 *topCallFrameSlot = newCallFrame;
    4389                 SamplingTool::HostCallRecord callRecord(m_sampler.get());
    4390                 returnValue = JSValue::decode(callData.native.function(newCallFrame));
    4391                 *topCallFrameSlot = callFrame;
    4392             }
    4393             CHECK_FOR_EXCEPTION();
    4394 
    4395             functionReturnValue = returnValue;
    4396 
    4397             vPC += OPCODE_LENGTH(op_call);
    4398             NEXT_INSTRUCTION();
    4399         }
    4400 
    4401         ASSERT(callType == CallTypeNone);
    4402 
    4403         exceptionValue = createNotAFunctionError(callFrame, v);
    4404         goto vm_throw;
    4405     }
    4406     DEFINE_OPCODE(op_call_varargs) {
    4407         /* call_varargs callee(r) thisValue(r) arguments(r) firstFreeRegister(n)
    4408          
    4409          Perform a function call with a dynamic set of arguments.
    4410          
    4411          registerOffset is the distance the callFrame pointer should move
    4412          before the VM initializes the new call frame's header, excluding
    4413          space for arguments.
    4414          
    4415          dst is where op_ret should store its result.
    4416          */
    4417        
    4418         JSValue v = callFrame->r(vPC[1].u.operand).jsValue();
    4419         JSValue thisValue = callFrame->r(vPC[2].u.operand).jsValue();
    4420         JSValue arguments = callFrame->r(vPC[3].u.operand).jsValue();
    4421         int firstFreeRegister = vPC[4].u.operand;
    4422 
    4423         CallFrame* newCallFrame = loadVarargs(callFrame, registerFile, thisValue, arguments, firstFreeRegister);
    4424         if ((exceptionValue = globalData->exception))
    4425             goto vm_throw;
    4426         int argCount = newCallFrame->argumentCountIncludingThis();
    4427 
    4428         CallData callData;
    4429         CallType callType = getCallData(v, callData);
    4430        
    4431         if (callType == CallTypeJS) {
    4432             JSScope* callDataScope = callData.js.scope;
    4433 
    4434             JSObject* error = callData.js.functionExecutable->compileForCall(callFrame, callDataScope);
    4435             if (UNLIKELY(!!error)) {
    4436                 exceptionValue = error;
    4437                 goto vm_throw;
    4438             }
    4439 
    4440             CodeBlock* newCodeBlock = &callData.js.functionExecutable->generatedBytecodeForCall();
    4441             newCallFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, newCallFrame, 0, argCount);
    4442             if (UNLIKELY(!newCallFrame)) {
    4443                 exceptionValue = createStackOverflowError(callFrame);
    4444                 goto vm_throw;
    4445             }
    4446 
    4447             newCallFrame->init(newCodeBlock, vPC + OPCODE_LENGTH(op_call_varargs), callDataScope, callFrame, argCount, jsCast<JSFunction*>(v));
    4448             codeBlock = newCodeBlock;
    4449             callFrame = newCallFrame;
    4450             ASSERT(codeBlock == callFrame->codeBlock());
    4451             *topCallFrameSlot = callFrame;
    4452             vPC = newCodeBlock->instructions().begin();
    4453 
    4454 #if ENABLE(OPCODE_STATS)
    4455             OpcodeStats::resetLastInstruction();
    4456 #endif
    4457            
    4458             NEXT_INSTRUCTION();
    4459         }
    4460        
    4461         if (callType == CallTypeHost) {
    4462             JSScope* scope = callFrame->scope();
    4463             newCallFrame->init(0, vPC + OPCODE_LENGTH(op_call_varargs), scope, callFrame, argCount, asObject(v));
    4464            
    4465             JSValue returnValue;
    4466             {
    4467                 *topCallFrameSlot = newCallFrame;
    4468                 SamplingTool::HostCallRecord callRecord(m_sampler.get());
    4469                 returnValue = JSValue::decode(callData.native.function(newCallFrame));
    4470                 *topCallFrameSlot = callFrame;
    4471             }
    4472             CHECK_FOR_EXCEPTION();
    4473            
    4474             functionReturnValue = returnValue;
    4475            
    4476             vPC += OPCODE_LENGTH(op_call_varargs);
    4477             NEXT_INSTRUCTION();
    4478         }
    4479        
    4480         ASSERT(callType == CallTypeNone);
    4481        
    4482         exceptionValue = createNotAFunctionError(callFrame, v);
    4483         goto vm_throw;
    4484     }
    4485     DEFINE_OPCODE(op_tear_off_activation) {
    4486         /* tear_off_activation activation(r)
    4487 
    4488            Copy locals and named parameters from the register file to the heap.
    4489            Point the bindings in 'activation' to this new backing store.
    4490 
    4491            This opcode appears before op_ret in functions that require full scope chains.
    4492         */
    4493 
    4494         int activation = vPC[1].u.operand;
    4495         ASSERT(codeBlock->needsFullScopeChain());
    4496         JSValue activationValue = callFrame->r(activation).jsValue();
    4497         if (activationValue)
    4498             asActivation(activationValue)->tearOff(*globalData);
    4499 
    4500         vPC += OPCODE_LENGTH(op_tear_off_activation);
    4501         NEXT_INSTRUCTION();
    4502     }
    4503     DEFINE_OPCODE(op_tear_off_arguments) {
    4504         /* tear_off_arguments arguments(r) activation(r)
    4505 
    4506            Copy named parameters from the register file to the heap. Point the
    4507            bindings in 'arguments' to this new backing store. (If 'activation'
    4508            was also copied to the heap, 'arguments' will point to its storage.)
    4509 
    4510            This opcode appears before op_ret in functions that don't require full
    4511            scope chains, but do use 'arguments'.
    4512         */
    4513 
    4514         int arguments = vPC[1].u.operand;
    4515         int activation = vPC[2].u.operand;
    4516         ASSERT(codeBlock->usesArguments());
    4517         if (JSValue argumentsValue = callFrame->r(unmodifiedArgumentsRegister(arguments)).jsValue()) {
    4518             if (JSValue activationValue = callFrame->r(activation).jsValue())
    4519                 asArguments(argumentsValue)->didTearOffActivation(callFrame, asActivation(activationValue));
    4520             else
    4521                 asArguments(argumentsValue)->tearOff(callFrame);
    4522         }
    4523 
    4524         vPC += OPCODE_LENGTH(op_tear_off_arguments);
    4525         NEXT_INSTRUCTION();
    4526     }
    4527     DEFINE_OPCODE(op_ret) {
    4528         /* ret result(r)
    4529            
    4530            Return register result as the return value of the current
    4531            function call, writing it into functionReturnValue.
    4532            In addition, unwind one call frame and restore the scope
    4533            chain, code block instruction pointer and register base
    4534            to those of the calling function.
    4535         */
    4536 
    4537         int result = vPC[1].u.operand;
    4538 
    4539         JSValue returnValue = callFrame->r(result).jsValue();
    4540 
    4541         vPC = callFrame->returnVPC();
    4542         callFrame = callFrame->callerFrame();
    4543 
    4544         if (callFrame->hasHostCallFrameFlag())
    4545             return returnValue;
    4546 
    4547         *topCallFrameSlot = callFrame;
    4548         functionReturnValue = returnValue;
    4549         codeBlock = callFrame->codeBlock();
    4550         ASSERT(codeBlock == callFrame->codeBlock());
    4551 
    4552         NEXT_INSTRUCTION();
    4553     }
    4554     DEFINE_OPCODE(op_call_put_result) {
    4555         /* op_call_put_result result(r)
    4556            
    4557            Move call result from functionReturnValue to caller's
    4558            expected return value register.
    4559         */
    4560 
    4561         callFrame->uncheckedR(vPC[1].u.operand) = functionReturnValue;
    4562 
    4563         vPC += OPCODE_LENGTH(op_call_put_result);
    4564         NEXT_INSTRUCTION();
    4565     }
    4566     DEFINE_OPCODE(op_ret_object_or_this) {
    4567         /* ret result(r)
    4568            
    4569            Return register result as the return value of the current
    4570            function call, writing it into the caller's expected return
    4571            value register. In addition, unwind one call frame and
    4572            restore the scope chain, code block instruction pointer and
    4573            register base to those of the calling function.
    4574         */
    4575 
    4576         int result = vPC[1].u.operand;
    4577 
    4578         JSValue returnValue = callFrame->r(result).jsValue();
    4579 
    4580         if (UNLIKELY(!returnValue.isObject()))
    4581             returnValue = callFrame->r(vPC[2].u.operand).jsValue();
    4582 
    4583         vPC = callFrame->returnVPC();
    4584         callFrame = callFrame->callerFrame();
    4585 
    4586         if (callFrame->hasHostCallFrameFlag())
    4587             return returnValue;
    4588 
    4589         *topCallFrameSlot = callFrame;
    4590         functionReturnValue = returnValue;
    4591         codeBlock = callFrame->codeBlock();
    4592         ASSERT(codeBlock == callFrame->codeBlock());
    4593 
    4594         NEXT_INSTRUCTION();
    4595     }
    4596     DEFINE_OPCODE(op_enter) {
    4597         /* enter
    4598 
    4599            Initializes local variables to undefined. If the code block requires
    4600            an activation, enter_with_activation is used instead.
    4601 
    4602            This opcode appears only at the beginning of a code block.
    4603         */
    4604 
    4605         size_t i = 0;
    4606         for (size_t count = codeBlock->m_numVars; i < count; ++i)
    4607             callFrame->uncheckedR(i) = jsUndefined();
    4608 
    4609         vPC += OPCODE_LENGTH(op_enter);
    4610         NEXT_INSTRUCTION();
    4611     }
    4612     DEFINE_OPCODE(op_create_activation) {
    4613         /* create_activation dst(r)
    4614 
    4615            If the activation object for this callframe has not yet been created,
    4616            this creates it and writes it back to dst.
    4617         */
    4618 
    4619         int activationReg = vPC[1].u.operand;
    4620         if (!callFrame->r(activationReg).jsValue()) {
    4621             JSActivation* activation = JSActivation::create(*globalData, callFrame, static_cast<FunctionExecutable*>(codeBlock->ownerExecutable()));
    4622             callFrame->r(activationReg) = JSValue(activation);
    4623             callFrame->setScope(activation);
    4624         }
    4625         vPC += OPCODE_LENGTH(op_create_activation);
    4626         NEXT_INSTRUCTION();
    4627     }
    4628     DEFINE_OPCODE(op_create_this) {
    4629         /* op_create_this this(r) proto(r)
    4630 
    4631            Allocate an object as 'this', fr use in construction.
    4632 
    4633            This opcode should only be used at the beginning of a code
    4634            block.
    4635         */
    4636 
    4637         int thisRegister = vPC[1].u.operand;
    4638 
    4639         JSFunction* constructor = jsCast<JSFunction*>(callFrame->callee());
    4640 #if !ASSERT_DISABLED
    4641         ConstructData constructData;
    4642         ASSERT(constructor->methodTable()->getConstructData(constructor, constructData) == ConstructTypeJS);
    4643 #endif
    4644 
    4645         Structure* structure = constructor->cachedInheritorID(callFrame);
    4646         callFrame->uncheckedR(thisRegister) = constructEmptyObject(callFrame, structure);
    4647 
    4648         vPC += OPCODE_LENGTH(op_create_this);
    4649         NEXT_INSTRUCTION();
    4650     }
    4651     DEFINE_OPCODE(op_convert_this) {
    4652         /* convert_this this(r)
    4653 
    4654            Takes the value in the 'this' register, converts it to a
    4655            value that is suitable for use as the 'this' value, and
    4656            stores it in the 'this' register. This opcode is emitted
    4657            to avoid doing the conversion in the caller unnecessarily.
    4658 
    4659            This opcode should only be used at the beginning of a code
    4660            block.
    4661         */
    4662 
    4663         int thisRegister = vPC[1].u.operand;
    4664         JSValue thisVal = callFrame->r(thisRegister).jsValue();
    4665         if (thisVal.isPrimitive())
    4666             callFrame->uncheckedR(thisRegister) = JSValue(thisVal.toThisObject(callFrame));
    4667 
    4668         vPC += OPCODE_LENGTH(op_convert_this);
    4669         NEXT_INSTRUCTION();
    4670     }
    4671     DEFINE_OPCODE(op_init_lazy_reg) {
    4672         /* init_lazy_reg dst(r)
    4673 
    4674            Initialises dst(r) to JSValue().
    4675 
    4676            This opcode appears only at the beginning of a code block.
    4677          */
    4678         int dst = vPC[1].u.operand;
    4679 
    4680         callFrame->uncheckedR(dst) = JSValue();
    4681         vPC += OPCODE_LENGTH(op_init_lazy_reg);
    4682         NEXT_INSTRUCTION();
    4683     }
    4684     DEFINE_OPCODE(op_create_arguments) {
    4685         /* create_arguments dst(r)
    4686 
    4687            Creates the 'arguments' object and places it in both the
    4688            'arguments' call frame slot and the local 'arguments'
    4689            register, if it has not already been initialised.
    4690          */
    4691        
    4692         int dst = vPC[1].u.operand;
    4693 
    4694         if (!callFrame->r(dst).jsValue()) {
    4695             Arguments* arguments = Arguments::create(*globalData, callFrame);
    4696             callFrame->uncheckedR(dst) = JSValue(arguments);
    4697             callFrame->uncheckedR(unmodifiedArgumentsRegister(dst)) = JSValue(arguments);
    4698         }
    4699         vPC += OPCODE_LENGTH(op_create_arguments);
    4700         NEXT_INSTRUCTION();
    4701     }
    4702     DEFINE_OPCODE(op_construct) {
    4703         /* construct func(r) argCount(n) registerOffset(n) proto(r) thisRegister(r)
    4704 
    4705            Invoke register "func" as a constructor. For JS
    4706            functions, the calling convention is exactly as for the
    4707            "call" opcode, except that the "this" value is a newly
    4708            created Object. For native constructors, no "this"
    4709            value is passed. In either case, the argCount and registerOffset
    4710            registers are interpreted as for the "call" opcode.
    4711 
    4712            Register proto must contain the prototype property of
    4713            register func. This is to enable polymorphic inline
    4714            caching of this lookup.
    4715         */
    4716 
    4717         int func = vPC[1].u.operand;
    4718         int argCount = vPC[2].u.operand;
    4719         int registerOffset = vPC[3].u.operand;
    4720 
    4721         JSValue v = callFrame->r(func).jsValue();
    4722 
    4723         ConstructData constructData;
    4724         ConstructType constructType = getConstructData(v, constructData);
    4725 
    4726         if (constructType == ConstructTypeJS) {
    4727             JSScope* callDataScope = constructData.js.scope;
    4728 
    4729             JSObject* error = constructData.js.functionExecutable->compileForConstruct(callFrame, callDataScope);
    4730             if (UNLIKELY(!!error)) {
    4731                 exceptionValue = error;
    4732                 goto vm_throw;
    4733             }
    4734 
    4735             CallFrame* previousCallFrame = callFrame;
    4736             CodeBlock* newCodeBlock = &constructData.js.functionExecutable->generatedBytecodeForConstruct();
    4737             callFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, callFrame, registerOffset, argCount);
    4738             if (UNLIKELY(!callFrame)) {
    4739                 callFrame = previousCallFrame;
    4740                 exceptionValue = createStackOverflowError(callFrame);
    4741                 goto vm_throw;
    4742             }
    4743 
    4744             callFrame->init(newCodeBlock, vPC + OPCODE_LENGTH(op_construct), callDataScope, previousCallFrame, argCount, jsCast<JSFunction*>(v));
    4745             codeBlock = newCodeBlock;
    4746             *topCallFrameSlot = callFrame;
    4747             vPC = newCodeBlock->instructions().begin();
    4748 #if ENABLE(OPCODE_STATS)
    4749             OpcodeStats::resetLastInstruction();
    4750 #endif
    4751 
    4752             NEXT_INSTRUCTION();
    4753         }
    4754 
    4755         if (constructType == ConstructTypeHost) {
    4756             JSScope* scope = callFrame->scope();
    4757             CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset);
    4758             newCallFrame->init(0, vPC + OPCODE_LENGTH(op_construct), scope, callFrame, argCount, asObject(v));
    4759 
    4760             JSValue returnValue;
    4761             {
    4762                 *topCallFrameSlot = newCallFrame;
    4763                 SamplingTool::HostCallRecord callRecord(m_sampler.get());
    4764                 returnValue = JSValue::decode(constructData.native.function(newCallFrame));
    4765                 *topCallFrameSlot = callFrame;
    4766             }
    4767             CHECK_FOR_EXCEPTION();
    4768             functionReturnValue = returnValue;
    4769 
    4770             vPC += OPCODE_LENGTH(op_construct);
    4771             NEXT_INSTRUCTION();
    4772         }
    4773 
    4774         ASSERT(constructType == ConstructTypeNone);
    4775 
    4776         exceptionValue = createNotAConstructorError(callFrame, v);
    4777         goto vm_throw;
    4778     }
    4779     DEFINE_OPCODE(op_strcat) {
    4780         /* strcat dst(r) src(r) count(n)
    4781 
    4782            Construct a new String instance using the original
    4783            constructor, and puts the result in register dst.
    4784            The string will be the result of concatenating count
    4785            strings with values taken from registers starting at
    4786            register src.
    4787         */
    4788         int dst = vPC[1].u.operand;
    4789         int src = vPC[2].u.operand;
    4790         int count = vPC[3].u.operand;
    4791 
    4792         callFrame->uncheckedR(dst) = concatenateStrings(callFrame, &callFrame->registers()[src], count);
    4793         CHECK_FOR_EXCEPTION();
    4794         vPC += OPCODE_LENGTH(op_strcat);
    4795 
    4796         NEXT_INSTRUCTION();
    4797     }
    4798     DEFINE_OPCODE(op_to_primitive) {
    4799         int dst = vPC[1].u.operand;
    4800         int src = vPC[2].u.operand;
    4801 
    4802         callFrame->uncheckedR(dst) = callFrame->r(src).jsValue().toPrimitive(callFrame);
    4803         vPC += OPCODE_LENGTH(op_to_primitive);
    4804 
    4805         NEXT_INSTRUCTION();
    4806     }
    4807     DEFINE_OPCODE(op_push_with_scope) {
    4808         /* push_with_scope scope(r)
    4809 
    4810            Converts register scope to object, and pushes it onto the top
    4811            of the scope chain.
    4812         */
    4813         int scope = vPC[1].u.operand;
    4814         JSValue v = callFrame->r(scope).jsValue();
    4815         JSObject* o = v.toObject(callFrame);
    4816         CHECK_FOR_EXCEPTION();
    4817 
    4818         callFrame->setScope(JSWithScope::create(callFrame, o));
    4819 
    4820         vPC += OPCODE_LENGTH(op_push_with_scope);
    4821         NEXT_INSTRUCTION();
    4822     }
    4823     DEFINE_OPCODE(op_pop_scope) {
    4824         /* pop_scope
    4825 
    4826            Removes the top item from the current scope chain.
    4827         */
    4828         callFrame->setScope(callFrame->scope()->next());
    4829 
    4830         vPC += OPCODE_LENGTH(op_pop_scope);
    4831         NEXT_INSTRUCTION();
    4832     }
    4833     DEFINE_OPCODE(op_get_pnames) {
    4834         /* get_pnames dst(r) base(r) i(n) size(n) breakTarget(offset)
    4835 
    4836            Creates a property name list for register base and puts it
    4837            in register dst, initializing i and size for iteration. If
    4838            base is undefined or null, jumps to breakTarget.
    4839         */
    4840         int dst = vPC[1].u.operand;
    4841         int base = vPC[2].u.operand;
    4842         int i = vPC[3].u.operand;
    4843         int size = vPC[4].u.operand;
    4844         int breakTarget = vPC[5].u.operand;
    4845 
    4846         JSValue v = callFrame->r(base).jsValue();
    4847         if (v.isUndefinedOrNull()) {
    4848             vPC += breakTarget;
    4849             NEXT_INSTRUCTION();
    4850         }
    4851 
    4852         JSObject* o = v.toObject(callFrame);
    4853         Structure* structure = o->structure();
    4854         JSPropertyNameIterator* jsPropertyNameIterator = structure->enumerationCache();
    4855         if (!jsPropertyNameIterator || jsPropertyNameIterator->cachedPrototypeChain() != structure->prototypeChain(callFrame))
    4856             jsPropertyNameIterator = JSPropertyNameIterator::create(callFrame, o);
    4857 
    4858         callFrame->uncheckedR(dst) = jsPropertyNameIterator;
    4859         callFrame->uncheckedR(base) = JSValue(o);
    4860         callFrame->uncheckedR(i) = Register::withInt(0);
    4861         callFrame->uncheckedR(size) = Register::withInt(jsPropertyNameIterator->size());
    4862         vPC += OPCODE_LENGTH(op_get_pnames);
    4863         NEXT_INSTRUCTION();
    4864     }
    4865     DEFINE_OPCODE(op_next_pname) {
    4866         /* next_pname dst(r) base(r) i(n) size(n) iter(r) target(offset)
    4867 
    4868            Copies the next name from the property name list in
    4869            register iter to dst, then jumps to offset target. If there are no
    4870            names left, invalidates the iterator and continues to the next
    4871            instruction.
    4872         */
    4873         int dst = vPC[1].u.operand;
    4874         int base = vPC[2].u.operand;
    4875         int i = vPC[3].u.operand;
    4876         int size = vPC[4].u.operand;
    4877         int iter = vPC[5].u.operand;
    4878         int target = vPC[6].u.operand;
    4879 
    4880         JSPropertyNameIterator* it = callFrame->r(iter).propertyNameIterator();
    4881         while (callFrame->r(i).i() != callFrame->r(size).i()) {
    4882             JSValue key = it->get(callFrame, asObject(callFrame->r(base).jsValue()), callFrame->r(i).i());
    4883             CHECK_FOR_EXCEPTION();
    4884             callFrame->uncheckedR(i) = Register::withInt(callFrame->r(i).i() + 1);
    4885             if (key) {
    4886                 CHECK_FOR_TIMEOUT();
    4887                 callFrame->uncheckedR(dst) = key;
    4888                 vPC += target;
    4889                 NEXT_INSTRUCTION();
    4890             }
    4891         }
    4892 
    4893         vPC += OPCODE_LENGTH(op_next_pname);
    4894         NEXT_INSTRUCTION();
    4895     }
    4896     DEFINE_OPCODE(op_jmp_scopes) {
    4897         /* jmp_scopes count(n) target(offset)
    4898 
    4899            Removes the a number of items from the current scope chain
    4900            specified by immediate number count, then jumps to offset
    4901            target.
    4902         */
    4903         int count = vPC[1].u.operand;
    4904         int target = vPC[2].u.operand;
    4905 
    4906         JSScope* tmp = callFrame->scope();
    4907         while (count--)
    4908             tmp = tmp->next();
    4909         callFrame->setScope(tmp);
    4910 
    4911         vPC += target;
    4912         NEXT_INSTRUCTION();
    4913     }
    4914 #if ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
    4915     // Appease GCC
    4916     goto *(&&skip_new_scope);
    4917 #endif
    4918     DEFINE_OPCODE(op_push_name_scope) {
    4919         /* new_scope property(id) value(r) attributes(unsigned)
    4920          
    4921            Constructs a name scope of the form { property<attributes>: value },
    4922            and pushes it onto the scope chain.
    4923          */
    4924         callFrame->setScope(createNameScope(callFrame, vPC));
    4925 
    4926         vPC += OPCODE_LENGTH(op_push_name_scope);
    4927         NEXT_INSTRUCTION();
    4928     }
    4929 #if ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
    4930     skip_new_scope:
    4931 #endif
    4932     DEFINE_OPCODE(op_catch) {
    4933         /* catch ex(r)
    4934 
    4935            Retrieves the VM's current exception and puts it in register
    4936            ex. This is only valid after an exception has been raised,
    4937            and usually forms the beginning of an exception handler.
    4938         */
    4939         ASSERT(exceptionValue);
    4940         ASSERT(!globalData->exception);
    4941         int ex = vPC[1].u.operand;
    4942         callFrame->uncheckedR(ex) = exceptionValue;
    4943         exceptionValue = JSValue();
    4944 
    4945         vPC += OPCODE_LENGTH(op_catch);
    4946         NEXT_INSTRUCTION();
    4947     }
    4948     DEFINE_OPCODE(op_throw) {
    4949         /* throw ex(r)
    4950 
    4951            Throws register ex as an exception. This involves three
    4952            steps: first, it is set as the current exception in the
    4953            VM's internal state, then the stack is unwound until an
    4954            exception handler or a native code boundary is found, and
    4955            then control resumes at the exception handler if any or
    4956            else the script returns control to the nearest native caller.
    4957         */
    4958 
    4959         int ex = vPC[1].u.operand;
    4960         exceptionValue = callFrame->r(ex).jsValue();
    4961 
    4962         handler = throwException(callFrame, exceptionValue, vPC - codeBlock->instructions().begin());
    4963         if (!handler)
    4964             return throwError(callFrame, exceptionValue);
    4965 
    4966         codeBlock = callFrame->codeBlock();
    4967         vPC = codeBlock->instructions().begin() + handler->target;
    4968         NEXT_INSTRUCTION();
    4969     }
    4970     DEFINE_OPCODE(op_throw_reference_error) {
    4971         /* op_throw_reference_error message(k)
    4972 
    4973            Constructs a new reference Error instance using the
    4974            original constructor, using constant message as the
    4975            message string. The result is thrown.
    4976         */
    4977         String message = callFrame->r(vPC[1].u.operand).jsValue().toString(callFrame)->value(callFrame);
    4978         exceptionValue = JSValue(createReferenceError(callFrame, message));
    4979         goto vm_throw;
    4980     }
    4981     DEFINE_OPCODE(op_end) {
    4982         /* end result(r)
    4983            
    4984            Return register result as the value of a global or eval
    4985            program. Return control to the calling native code.
    4986         */
    4987 
    4988         int result = vPC[1].u.operand;
    4989         return callFrame->r(result).jsValue();
    4990     }
    4991     DEFINE_OPCODE(op_put_getter_setter) {
    4992         /* put_getter_setter base(r) property(id) getter(r) setter(r)
    4993 
    4994            Puts accessor descriptor to register base as the named
    4995            identifier property. Base and function may be objects
    4996            or undefined, this op should only be used for accessors
    4997            defined in object literal form.
    4998 
    4999            Unlike many opcodes, this one does not write any output to
    5000            the register file.
    5001         */
    5002         int base = vPC[1].u.operand;
    5003         int property = vPC[2].u.operand;
    5004         int getterReg = vPC[3].u.operand;
    5005         int setterReg = vPC[4].u.operand;
    5006 
    5007         ASSERT(callFrame->r(base).jsValue().isObject());
    5008         JSObject* baseObj = asObject(callFrame->r(base).jsValue());
    5009         Identifier& ident = codeBlock->identifier(property);
    5010 
    5011         GetterSetter* accessor = GetterSetter::create(callFrame);
    5012 
    5013         JSValue getter = callFrame->r(getterReg).jsValue();
    5014         JSValue setter = callFrame->r(setterReg).jsValue();
    5015         ASSERT(getter.isObject() || getter.isUndefined());
    5016         ASSERT(setter.isObject() || setter.isUndefined());
    5017         ASSERT(getter.isObject() || setter.isObject());
    5018 
    5019         if (!getter.isUndefined())
    5020             accessor->setGetter(callFrame->globalData(), asObject(getter));
    5021         if (!setter.isUndefined())
    5022             accessor->setSetter(callFrame->globalData(), asObject(setter));
    5023         baseObj->putDirectAccessor(callFrame, ident, accessor, Accessor);
    5024 
    5025         vPC += OPCODE_LENGTH(op_put_getter_setter);
    5026         NEXT_INSTRUCTION();
    5027     }
    5028     DEFINE_OPCODE(op_method_check) {
    5029         vPC++;
    5030         NEXT_INSTRUCTION();
    5031     }
    5032     DEFINE_OPCODE(op_debug) {
    5033         /* debug debugHookID(n) firstLine(n) lastLine(n) column(n)
    5034 
    5035          Notifies the debugger of the current state of execution. This opcode
    5036          is only generated while the debugger is attached.
    5037         */
    5038         int debugHookID = vPC[1].u.operand;
    5039         int firstLine = vPC[2].u.operand;
    5040         int lastLine = vPC[3].u.operand;
    5041         int column = vPC[4].u.operand;
    5042 
    5043 
    5044         debug(callFrame, static_cast<DebugHookID>(debugHookID), firstLine, lastLine, column);
    5045 
    5046         vPC += OPCODE_LENGTH(op_debug);
    5047         NEXT_INSTRUCTION();
    5048     }
    5049     DEFINE_OPCODE(op_profile_will_call) {
    5050         /* op_profile_will_call function(r)
    5051 
    5052          Notifies the profiler of the beginning of a function call. This opcode
    5053          is only generated if developer tools are enabled.
    5054         */
    5055         int function = vPC[1].u.operand;
    5056 
    5057         if (Profiler* profiler = globalData->enabledProfiler())
    5058             profiler->willExecute(callFrame, callFrame->r(function).jsValue());
    5059 
    5060         vPC += OPCODE_LENGTH(op_profile_will_call);
    5061         NEXT_INSTRUCTION();
    5062     }
    5063     DEFINE_OPCODE(op_profile_did_call) {
    5064         /* op_profile_did_call function(r)
    5065 
    5066          Notifies the profiler of the end of a function call. This opcode
    5067          is only generated if developer tools are enabled.
    5068         */
    5069         int function = vPC[1].u.operand;
    5070 
    5071         if (Profiler* profiler = globalData->enabledProfiler())
    5072             profiler->didExecute(callFrame, callFrame->r(function).jsValue());
    5073 
    5074         vPC += OPCODE_LENGTH(op_profile_did_call);
    5075         NEXT_INSTRUCTION();
    5076     }
    5077     vm_throw: {
    5078         globalData->exception = JSValue();
    5079         if (!tickCount) {
    5080             // The exceptionValue is a lie! (GCC produces bad code for reasons I
    5081             // cannot fathom if we don't assign to the exceptionValue before branching)
    5082             exceptionValue = createInterruptedExecutionException(globalData);
    5083         }
    5084         JSGlobalObject* globalObject = callFrame->lexicalGlobalObject();
    5085         handler = throwException(callFrame, exceptionValue, vPC - codeBlock->instructions().begin());
    5086         if (!handler) {
    5087             // Can't use the callframe at this point as the scopechain, etc have
    5088             // been released.
    5089             return throwError(globalObject->globalExec(), exceptionValue);
    5090         }
    5091 
    5092         codeBlock = callFrame->codeBlock();
    5093         vPC = codeBlock->instructions().begin() + handler->target;
    5094         NEXT_INSTRUCTION();
    5095     }
    5096     }
    5097 #if !ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
    5098     } // iterator loop ends
    5099 #endif
    5100     #undef NEXT_INSTRUCTION
    5101     #undef DEFINE_OPCODE
    5102     #undef CHECK_FOR_EXCEPTION
    5103     #undef CHECK_FOR_TIMEOUT
    5104 #endif // ENABLE(CLASSIC_INTERPRETER)
    5105 }
    5106 
    5107 #endif // !ENABLE(LLINT_C_LOOP)
    5108 
    5109 
    51101290JSValue Interpreter::retrieveArgumentsFromVMCode(CallFrame* callFrame, JSFunction* function) const
    51111291{
     
    51631343        return;
    51641344    unsigned bytecodeOffset = 0;
    5165 #if ENABLE(CLASSIC_INTERPRETER)
    5166     if (!callerFrame->globalData().canUseJIT())
    5167         bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnVPC());
    5168 #if ENABLE(JIT)
    5169     else
    5170         bytecodeOffset = callerCodeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
    5171 #endif
    5172 #else
    51731345    bytecodeOffset = callerCodeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
    5174 #endif
    51751346    lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset - 1);
    51761347    sourceID = callerCodeBlock->ownerExecutable()->sourceID();
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.h

    r128014 r129453  
    205205        {
    206206            ASSERT(m_initialized);
    207 #if ENABLE(COMPUTED_GOTO_OPCODES)
    208 #if ENABLE(LLINT)
     207#if ENABLE(COMPUTED_GOTO_OPCODES) && ENABLE(LLINT)
    209208            ASSERT(isOpcode(opcode));
    210209            return m_opcodeIDTable.get(opcode);
    211 #elif ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
    212             ASSERT(isOpcode(opcode));
    213             if (!m_classicEnabled)
    214                 return static_cast<OpcodeID>(bitwise_cast<uintptr_t>(opcode));
    215 
    216             return m_opcodeIDTable.get(opcode);
    217 #endif // ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
    218 #else // !ENABLE(COMPUTED_GOTO_OPCODES)
     210#else
    219211            return opcode;
    220 #endif // !ENABLE(COMPUTED_GOTO_OPCODES)
    221         }
    222        
    223         bool classicEnabled()
    224         {
    225             return m_classicEnabled;
    226         }
    227 
     212#endif
     213        }
     214       
    228215        bool isOpcode(Opcode);
    229216
     
    261248        JSValue execute(CallFrameClosure&);
    262249
    263 #if ENABLE(CLASSIC_INTERPRETER)
    264         NEVER_INLINE JSScope* createNameScope(CallFrame*, const Instruction* vPC);
    265 
    266         void tryCacheGetByID(CallFrame*, CodeBlock*, Instruction*, JSValue baseValue, const Identifier& propertyName, const PropertySlot&);
    267         void uncacheGetByID(CodeBlock*, Instruction* vPC);
    268         void tryCachePutByID(CallFrame*, CodeBlock*, Instruction*, JSValue baseValue, const PutPropertySlot&);
    269         void uncachePutByID(CodeBlock*, Instruction* vPC);       
    270 #endif // ENABLE(CLASSIC_INTERPRETER)
    271 
    272250        NEVER_INLINE bool unwindCallFrame(CallFrame*&, JSValue, unsigned& bytecodeOffset, CodeBlock*&);
    273251
     
    292270        RegisterFile m_registerFile;
    293271       
    294 #if ENABLE(COMPUTED_GOTO_OPCODES)
    295 #if ENABLE(LLINT)
     272#if ENABLE(COMPUTED_GOTO_OPCODES) && ENABLE(LLINT)
    296273        Opcode* m_opcodeTable; // Maps OpcodeID => Opcode for compiling
    297274        HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling
    298 #elif ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
    299         Opcode m_opcodeTable[numOpcodeIDs]; // Maps OpcodeID => Opcode for compiling
    300         HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling
    301 #endif
    302 #endif // ENABLE(COMPUTED_GOTO_OPCODES)
     275#endif
    303276
    304277#if !ASSERT_DISABLED
    305278        bool m_initialized;
    306279#endif
    307         bool m_classicEnabled;
    308280    };
    309281
Note: See TracChangeset for help on using the changeset viewer.