/*
 * Copyright (C) 2008, 2009, 2010 Apple Inc. All rights reserved.
 * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "Interpreter.h"

#include "Arguments.h"
#include "BatchedTransitionOptimizer.h"
#include "CallFrame.h"
#include "CallFrameClosure.h"
#include "CodeBlock.h"
#include "Heap.h"
#include "Debugger.h"
#include "DebuggerCallFrame.h"
#include "ErrorInstance.h"
#include "EvalCodeCache.h"
#include "ExceptionHelpers.h"
#include "GetterSetter.h"
#include "JSActivation.h"
#include "JSArray.h"
#include "JSByteArray.h"
#include "JSNotAnObject.h"
#include "JSPropertyNameIterator.h"
#include "LiteralParser.h"
#include "JSStaticScopeObject.h"
#include "JSString.h"
#include "ObjectPrototype.h"
#include "Operations.h"
#include "Parser.h"
#include "Profiler.h"
#include "RegExpObject.h"
#include "RegExpPrototype.h"
#include "Register.h"
#include "SamplingTool.h"
#include "StrictEvalActivation.h"
#include "StrongInlines.h"
#include "UStringConcatenate.h"
#include <limits.h>
#include <stdio.h>
#include <wtf/Threading.h>

#if ENABLE(JIT)
#include "JIT.h"
#endif

#define WTF_USE_GCC_COMPUTED_GOTO_WORKAROUND ((ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER) || ENABLE(LLINT)) && !defined(__llvm__))

using namespace std;

namespace JSC {

// Returns the depth of the scope chain within a given call frame.
static int depth(CodeBlock* codeBlock, ScopeChainNode* sc)
{
    if (!codeBlock->needsFullScopeChain())
        return 0;
    return sc->localDepth();
}

#if ENABLE(CLASSIC_INTERPRETER) 
static NEVER_INLINE JSValue concatenateStrings(ExecState* exec, Register* strings, unsigned count)
{
    return jsString(exec, strings, count);
}

NEVER_INLINE bool Interpreter::resolve(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue)
{
    int dst = vPC[1].u.operand;
    int property = vPC[2].u.operand;

    ScopeChainNode* scopeChain = callFrame->scopeChain();
    ScopeChainIterator iter = scopeChain->begin();
    ScopeChainIterator end = scopeChain->end();
    ASSERT(iter != end);

    CodeBlock* codeBlock = callFrame->codeBlock();
    Identifier& ident = codeBlock->identifier(property);
    do {
        JSObject* o = iter->get();
        PropertySlot slot(o);
        if (o->getPropertySlot(callFrame, ident, slot)) {
            JSValue result = slot.getValue(callFrame, ident);
            exceptionValue = callFrame->globalData().exception;
            if (exceptionValue)
                return false;
            callFrame->uncheckedR(dst) = JSValue(result);
            return true;
        }
    } while (++iter != end);
    exceptionValue = createUndefinedVariableError(callFrame, ident);
    return false;
}

NEVER_INLINE bool Interpreter::resolveSkip(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue)
{
    CodeBlock* codeBlock = callFrame->codeBlock();

    int dst = vPC[1].u.operand;
    int property = vPC[2].u.operand;
    int skip = vPC[3].u.operand;

    ScopeChainNode* scopeChain = callFrame->scopeChain();
    ScopeChainIterator iter = scopeChain->begin();
    ScopeChainIterator end = scopeChain->end();
    ASSERT(iter != end);
    bool checkTopLevel = codeBlock->codeType() == FunctionCode && codeBlock->needsFullScopeChain();
    ASSERT(skip || !checkTopLevel);
    if (checkTopLevel && skip--) {
        if (callFrame->uncheckedR(codeBlock->activationRegister()).jsValue())
            ++iter;
    }
    while (skip--) {
        ++iter;
        ASSERT(iter != end);
    }
    Identifier& ident = codeBlock->identifier(property);
    do {
        JSObject* o = iter->get();
        PropertySlot slot(o);
        if (o->getPropertySlot(callFrame, ident, slot)) {
            JSValue result = slot.getValue(callFrame, ident);
            exceptionValue = callFrame->globalData().exception;
            if (exceptionValue)
                return false;
            ASSERT(result);
            callFrame->uncheckedR(dst) = JSValue(result);
            return true;
        }
    } while (++iter != end);
    exceptionValue = createUndefinedVariableError(callFrame, ident);
    return false;
}

NEVER_INLINE bool Interpreter::resolveGlobal(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue)
{
    int dst = vPC[1].u.operand;
    CodeBlock* codeBlock = callFrame->codeBlock();
    JSGlobalObject* globalObject = codeBlock->globalObject();
    ASSERT(globalObject->isGlobalObject());
    int property = vPC[2].u.operand;
    Structure* structure = vPC[3].u.structure.get();
    int offset = vPC[4].u.operand;

    if (structure == globalObject->structure()) {
        callFrame->uncheckedR(dst) = JSValue(globalObject->getDirectOffset(offset));
        return true;
    }

    Identifier& ident = codeBlock->identifier(property);
    PropertySlot slot(globalObject);
    if (globalObject->getPropertySlot(callFrame, ident, slot)) {
        JSValue result = slot.getValue(callFrame, ident);
        if (slot.isCacheableValue() && !globalObject->structure()->isUncacheableDictionary() && slot.slotBase() == globalObject) {
            vPC[3].u.structure.set(callFrame->globalData(), codeBlock->ownerExecutable(), globalObject->structure());
            vPC[4] = slot.cachedOffset();
            callFrame->uncheckedR(dst) = JSValue(result);
            return true;
        }

        exceptionValue = callFrame->globalData().exception;
        if (exceptionValue)
            return false;
        callFrame->uncheckedR(dst) = JSValue(result);
        return true;
    }

    exceptionValue = createUndefinedVariableError(callFrame, ident);
    return false;
}

NEVER_INLINE bool Interpreter::resolveGlobalDynamic(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue)
{
    int dst = vPC[1].u.operand;
    CodeBlock* codeBlock = callFrame->codeBlock();
    JSGlobalObject* globalObject = codeBlock->globalObject();
    ASSERT(globalObject->isGlobalObject());
    int property = vPC[2].u.operand;
    Structure* structure = vPC[3].u.structure.get();
    int offset = vPC[4].u.operand;
    int skip = vPC[5].u.operand;
    
    ScopeChainNode* scopeChain = callFrame->scopeChain();
    ScopeChainIterator iter = scopeChain->begin();
    ScopeChainIterator end = scopeChain->end();
    ASSERT(iter != end);
    bool checkTopLevel = codeBlock->codeType() == FunctionCode && codeBlock->needsFullScopeChain();
    ASSERT(skip || !checkTopLevel);
    if (checkTopLevel && skip--) {
        if (callFrame->uncheckedR(codeBlock->activationRegister()).jsValue())
            ++iter;
    }
    while (skip--) {
        JSObject* o = iter->get();
        if (o->hasCustomProperties()) {
            Identifier& ident = codeBlock->identifier(property);
            do {
                PropertySlot slot(o);
                if (o->getPropertySlot(callFrame, ident, slot)) {
                    JSValue result = slot.getValue(callFrame, ident);
                    exceptionValue = callFrame->globalData().exception;
                    if (exceptionValue)
                        return false;
                    ASSERT(result);
                    callFrame->uncheckedR(dst) = JSValue(result);
                    return true;
                }
                if (iter == end)
                    break;
                o = iter->get();
                ++iter;
            } while (true);
            exceptionValue = createUndefinedVariableError(callFrame, ident);
            return false;
        }
        ++iter;
    }
    
    if (structure == globalObject->structure()) {
        callFrame->uncheckedR(dst) = JSValue(globalObject->getDirectOffset(offset));
        ASSERT(callFrame->uncheckedR(dst).jsValue());
        return true;
    }

    Identifier& ident = codeBlock->identifier(property);
    PropertySlot slot(globalObject);
    if (globalObject->getPropertySlot(callFrame, ident, slot)) {
        JSValue result = slot.getValue(callFrame, ident);
        if (slot.isCacheableValue() && !globalObject->structure()->isUncacheableDictionary() && slot.slotBase() == globalObject) {
            vPC[3].u.structure.set(callFrame->globalData(), codeBlock->ownerExecutable(), globalObject->structure());
            vPC[4] = slot.cachedOffset();
            ASSERT(result);
            callFrame->uncheckedR(dst) = JSValue(result);
            return true;
        }
        
        exceptionValue = callFrame->globalData().exception;
        if (exceptionValue)
            return false;
        ASSERT(result);
        callFrame->uncheckedR(dst) = JSValue(result);
        return true;
    }
    
    exceptionValue = createUndefinedVariableError(callFrame, ident);
    return false;
}

NEVER_INLINE void Interpreter::resolveBase(CallFrame* callFrame, Instruction* vPC)
{
    int dst = vPC[1].u.operand;
    int property = vPC[2].u.operand;
    bool isStrictPut = vPC[3].u.operand;
    Identifier ident = callFrame->codeBlock()->identifier(property);
    JSValue result = JSC::resolveBase(callFrame, ident, callFrame->scopeChain(), isStrictPut);
    if (result) {
        callFrame->uncheckedR(dst) = result;
        ASSERT(callFrame->uncheckedR(dst).jsValue());
    } else
        callFrame->globalData().exception = createErrorForInvalidGlobalAssignment(callFrame, ident.ustring());
}

NEVER_INLINE bool Interpreter::resolveBaseAndProperty(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue)
{
    int baseDst = vPC[1].u.operand;
    int propDst = vPC[2].u.operand;
    int property = vPC[3].u.operand;

    ScopeChainNode* scopeChain = callFrame->scopeChain();
    ScopeChainIterator iter = scopeChain->begin();
    ScopeChainIterator end = scopeChain->end();

    // FIXME: add scopeDepthIsZero optimization

    ASSERT(iter != end);

    CodeBlock* codeBlock = callFrame->codeBlock();
    Identifier& ident = codeBlock->identifier(property);
    JSObject* base;
    do {
        base = iter->get();
        PropertySlot slot(base);
        if (base->getPropertySlot(callFrame, ident, slot)) {
            JSValue result = slot.getValue(callFrame, ident);
            exceptionValue = callFrame->globalData().exception;
            if (exceptionValue)
                return false;
            callFrame->uncheckedR(propDst) = JSValue(result);
            callFrame->uncheckedR(baseDst) = JSValue(base);
            return true;
        }
        ++iter;
    } while (iter != end);

    exceptionValue = createUndefinedVariableError(callFrame, ident);
    return false;
}

NEVER_INLINE bool Interpreter::resolveThisAndProperty(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue)
{
    int thisDst = vPC[1].u.operand;
    int propDst = vPC[2].u.operand;
    int property = vPC[3].u.operand;

    ScopeChainNode* scopeChain = callFrame->scopeChain();
    ScopeChainIterator iter = scopeChain->begin();
    ScopeChainIterator end = scopeChain->end();

    // FIXME: add scopeDepthIsZero optimization

    ASSERT(iter != end);

    CodeBlock* codeBlock = callFrame->codeBlock();
    Identifier& ident = codeBlock->identifier(property);
    JSObject* base;
    do {
        base = iter->get();
        ++iter;
        PropertySlot slot(base);
        if (base->getPropertySlot(callFrame, ident, slot)) {
            JSValue result = slot.getValue(callFrame, ident);
            exceptionValue = callFrame->globalData().exception;
            if (exceptionValue)
                return false;
            callFrame->uncheckedR(propDst) = JSValue(result);
            // All entries on the scope chain should be EnvironmentRecords (activations etc),
            // other then 'with' object, which are directly referenced from the scope chain,
            // and the global object. If we hit either an EnvironmentRecord or a global
            // object at the end of the scope chain, this is undefined. If we hit a non-
            // EnvironmentRecord within the scope chain, pass the base as the this value.
            if (iter == end || base->structure()->typeInfo().isEnvironmentRecord())
                callFrame->uncheckedR(thisDst) = jsUndefined();
            else
                callFrame->uncheckedR(thisDst) = JSValue(base);
            return true;
        }
    } while (iter != end);

    exceptionValue = createUndefinedVariableError(callFrame, ident);
    return false;
}

#endif // ENABLE(CLASSIC_INTERPRETER)

ALWAYS_INLINE CallFrame* Interpreter::slideRegisterWindowForCall(CodeBlock* newCodeBlock, RegisterFile* registerFile, CallFrame* callFrame, size_t registerOffset, int argumentCountIncludingThis)
{
    // This ensures enough space for the worst case scenario of zero arguments passed by the caller.
    if (!registerFile->grow(callFrame->registers() + registerOffset + newCodeBlock->numParameters() + newCodeBlock->m_numCalleeRegisters))
        return 0;

    if (argumentCountIncludingThis >= newCodeBlock->numParameters()) {
        Register* newCallFrame = callFrame->registers() + registerOffset;
        return CallFrame::create(newCallFrame);
    }

    // Too few arguments -- copy arguments, then fill in missing arguments with undefined.
    size_t delta = newCodeBlock->numParameters() - argumentCountIncludingThis;
    CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset + delta);

    Register* dst = &newCallFrame->uncheckedR(CallFrame::thisArgumentOffset());
    Register* end = dst - argumentCountIncludingThis;
    for ( ; dst != end; --dst)
        *dst = *(dst - delta);

    end -= delta;
    for ( ; dst != end; --dst)
        *dst = jsUndefined();

    return newCallFrame;
}

#if ENABLE(CLASSIC_INTERPRETER)
static NEVER_INLINE bool isInvalidParamForIn(CallFrame* callFrame, JSValue value, JSValue& exceptionData)
{
    if (value.isObject())
        return false;
    exceptionData = createInvalidParamError(callFrame, "in" , value);
    return true;
}

static NEVER_INLINE bool isInvalidParamForInstanceOf(CallFrame* callFrame, JSValue value, JSValue& exceptionData)
{
    if (value.isObject() && asObject(value)->structure()->typeInfo().implementsHasInstance())
        return false;
    exceptionData = createInvalidParamError(callFrame, "instanceof" , value);
    return true;
}
#endif

JSValue eval(CallFrame* callFrame)
{
    if (!callFrame->argumentCount())
        return jsUndefined();

    JSValue program = callFrame->argument(0);
    if (!program.isString())
        return program;

    UString programSource = asString(program)->value(callFrame);
    if (callFrame->hadException())
        return JSValue();
    
    CallFrame* callerFrame = callFrame->callerFrame();
    CodeBlock* callerCodeBlock = callerFrame->codeBlock();
    ScopeChainNode* callerScopeChain = callerFrame->scopeChain();
    EvalExecutable* eval = callerCodeBlock->evalCodeCache().tryGet(callerCodeBlock->isStrictMode(), programSource, callerScopeChain);

    if (!eval) {
        if (!callerCodeBlock->isStrictMode()) {
            // FIXME: We can use the preparser in strict mode, we just need additional logic
            // to prevent duplicates.
            if (programSource.is8Bit()) {
                LiteralParser<LChar> preparser(callFrame, programSource.characters8(), programSource.length(), NonStrictJSON);
                if (JSValue parsedObject = preparser.tryLiteralParse())
                    return parsedObject;
            } else {
                LiteralParser<UChar> preparser(callFrame, programSource.characters16(), programSource.length(), NonStrictJSON);
                if (JSValue parsedObject = preparser.tryLiteralParse())
                    return parsedObject;                
            }
        }

        JSValue exceptionValue;
        eval = callerCodeBlock->evalCodeCache().getSlow(callFrame, callerCodeBlock->ownerExecutable(), callerCodeBlock->isStrictMode(), programSource, callerScopeChain, exceptionValue);
        
        ASSERT(!eval == exceptionValue);
        if (UNLIKELY(!eval))
            return throwError(callFrame, exceptionValue);
    }

    JSValue thisValue = callerFrame->thisValue();
    ASSERT(isValidThisObject(thisValue, callFrame));
    Interpreter* interpreter = callFrame->globalData().interpreter;
    return interpreter->execute(eval, callFrame, thisValue, callerScopeChain, callFrame->registers() - interpreter->registerFile().begin() + 1 + RegisterFile::CallFrameHeaderSize);
}

CallFrame* loadVarargs(CallFrame* callFrame, RegisterFile* registerFile, JSValue thisValue, JSValue arguments, int firstFreeRegister)
{
    if (!arguments) { // f.apply(x, arguments), with arguments unmodified.
        unsigned argumentCountIncludingThis = callFrame->argumentCountIncludingThis();
        CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + argumentCountIncludingThis + RegisterFile::CallFrameHeaderSize);
        if (argumentCountIncludingThis > Arguments::MaxArguments + 1 || !registerFile->grow(newCallFrame->registers())) {
            callFrame->globalData().exception = createStackOverflowError(callFrame);
            return 0;
        }

        newCallFrame->setArgumentCountIncludingThis(argumentCountIncludingThis);
        newCallFrame->setThisValue(thisValue);
        for (size_t i = 0; i < callFrame->argumentCount(); ++i)
            newCallFrame->setArgument(i, callFrame->argument(i));
        return newCallFrame;
    }

    if (arguments.isUndefinedOrNull()) {
        CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + 1 + RegisterFile::CallFrameHeaderSize);
        if (!registerFile->grow(newCallFrame->registers())) {
            callFrame->globalData().exception = createStackOverflowError(callFrame);
            return 0;
        }
        newCallFrame->setArgumentCountIncludingThis(1);
        newCallFrame->setThisValue(thisValue);
        return newCallFrame;
    }

    if (!arguments.isObject()) {
        callFrame->globalData().exception = createInvalidParamError(callFrame, "Function.prototype.apply", arguments);
        return 0;
    }

    if (asObject(arguments)->classInfo() == &Arguments::s_info) {
        Arguments* argsObject = asArguments(arguments);
        unsigned argCount = argsObject->length(callFrame);
        CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + CallFrame::offsetFor(argCount + 1));
        if (argCount > Arguments::MaxArguments || !registerFile->grow(newCallFrame->registers())) {
            callFrame->globalData().exception = createStackOverflowError(callFrame);
            return 0;
        }
        newCallFrame->setArgumentCountIncludingThis(argCount + 1);
        newCallFrame->setThisValue(thisValue);
        argsObject->copyToArguments(callFrame, newCallFrame, argCount);
        return newCallFrame;
    }

    if (isJSArray(arguments)) {
        JSArray* array = asArray(arguments);
        unsigned argCount = array->length();
        CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + CallFrame::offsetFor(argCount + 1));
        if (argCount > Arguments::MaxArguments || !registerFile->grow(newCallFrame->registers())) {
            callFrame->globalData().exception = createStackOverflowError(callFrame);
            return 0;
        }
        newCallFrame->setArgumentCountIncludingThis(argCount + 1);
        newCallFrame->setThisValue(thisValue);
        array->copyToArguments(callFrame, newCallFrame, argCount);
        return newCallFrame;
    }

    JSObject* argObject = asObject(arguments);
    unsigned argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
    CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + CallFrame::offsetFor(argCount + 1));
    if (argCount > Arguments::MaxArguments || !registerFile->grow(newCallFrame->registers())) {
        callFrame->globalData().exception = createStackOverflowError(callFrame);
        return 0;
    }
    newCallFrame->setArgumentCountIncludingThis(argCount + 1);
    newCallFrame->setThisValue(thisValue);
    for (size_t i = 0; i < argCount; ++i) {
        newCallFrame->setArgument(i, asObject(arguments)->get(callFrame, i));
        if (UNLIKELY(callFrame->globalData().exception))
            return 0;
    }
    return newCallFrame;
}

Interpreter::Interpreter()
    : m_sampleEntryDepth(0)
    , m_reentryDepth(0)
#if !ASSERT_DISABLED
    , m_initialized(false)
#endif
    , m_classicEnabled(false)
{
}

Interpreter::~Interpreter()
{
#if ENABLE(LLINT)
    if (m_classicEnabled)
        delete[] m_opcodeTable;
#endif
}

void Interpreter::initialize(LLInt::Data* llintData, bool canUseJIT)
{
    UNUSED_PARAM(llintData);
    UNUSED_PARAM(canUseJIT);
#if ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER) || ENABLE(LLINT)
#if !ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
    // Having LLInt enabled, but not being able to use the JIT, and not having
    // a computed goto interpreter, is not supported. Not because we cannot
    // support it, but because I decided to draw the line at the number of
    // permutations of execution engines that I wanted this code to grok.
    ASSERT(canUseJIT);
#endif
    if (canUseJIT) {
#if ENABLE(LLINT)
        m_opcodeTable = llintData->opcodeMap();
        for (int i = 0; i < numOpcodeIDs; ++i)
            m_opcodeIDTable.add(m_opcodeTable[i], static_cast<OpcodeID>(i));
#else
        // If the JIT is present, don't use jump destinations for opcodes.
        
        for (int i = 0; i < numOpcodeIDs; ++i) {
            Opcode opcode = bitwise_cast<void*>(static_cast<uintptr_t>(i));
            m_opcodeTable[i] = opcode;
        }
#endif
    } else {
#if ENABLE(LLINT)
        m_opcodeTable = new Opcode[numOpcodeIDs];
#endif
        privateExecute(InitializeAndReturn, 0, 0);
        
        for (int i = 0; i < numOpcodeIDs; ++i)
            m_opcodeIDTable.add(m_opcodeTable[i], static_cast<OpcodeID>(i));
        
        m_classicEnabled = true;
    }
#else
#if ENABLE(CLASSIC_INTERPRETER)
    m_classicEnabled = true;
#else
    m_classicEnabled = false;
#endif
#endif // ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
#if !ASSERT_DISABLED
    m_initialized = true;
#endif

#if ENABLE(OPCODE_SAMPLING)
    enableSampler();
#endif
}

#ifndef NDEBUG

void Interpreter::dumpCallFrame(CallFrame* callFrame)
{
    callFrame->codeBlock()->dump(callFrame);
    dumpRegisters(callFrame);
}

void Interpreter::dumpRegisters(CallFrame* callFrame)
{
    dataLog("Register frame: \n\n");
    dataLog("-----------------------------------------------------------------------------\n");
    dataLog("            use            |   address  |                value               \n");
    dataLog("-----------------------------------------------------------------------------\n");

    CodeBlock* codeBlock = callFrame->codeBlock();
    const Register* it;
    const Register* end;
    JSValue v;

    it = callFrame->registers() - RegisterFile::CallFrameHeaderSize - codeBlock->numParameters();
    v = (*it).jsValue();
#if USE(JSVALUE32_64)
    dataLog("[this]                     | %10p | %-16s 0x%llx \n", it, v.description(), JSValue::encode(v)); ++it;
#else
    dataLog("[this]                     | %10p | %-16s %p \n", it, v.description(), JSValue::encode(v)); ++it;
#endif
    end = it + max(codeBlock->numParameters() - 1, 0); // - 1 to skip "this"
    if (it != end) {
        do {
            v = (*it).jsValue();
#if USE(JSVALUE32_64)
            dataLog("[param]                    | %10p | %-16s 0x%llx \n", it, v.description(), JSValue::encode(v));
#else
            dataLog("[param]                    | %10p | %-16s %p \n", it, v.description(), JSValue::encode(v));
#endif
            ++it;
        } while (it != end);
    }
    dataLog("-----------------------------------------------------------------------------\n");
    dataLog("[CodeBlock]                | %10p | %p \n", it, (*it).codeBlock()); ++it;
    dataLog("[ScopeChain]               | %10p | %p \n", it, (*it).scopeChain()); ++it;
    dataLog("[CallerRegisters]          | %10p | %d \n", it, (*it).i()); ++it;
    dataLog("[ReturnPC]                 | %10p | %p \n", it, (*it).vPC()); ++it;
    dataLog("[ArgumentCount]            | %10p | %d \n", it, (*it).i()); ++it;
    dataLog("[Callee]                   | %10p | %p \n", it, (*it).function()); ++it;
    dataLog("-----------------------------------------------------------------------------\n");

    int registerCount = 0;

    end = it + codeBlock->m_numVars;
    if (it != end) {
        do {
            v = (*it).jsValue();
#if USE(JSVALUE32_64)
            dataLog("[r%2d]                      | %10p | %-16s 0x%llx \n", registerCount, it, v.description(), JSValue::encode(v));
#else
            dataLog("[r%2d]                      | %10p | %-16s %p \n", registerCount, it, v.description(), JSValue::encode(v));
#endif
            ++it;
            ++registerCount;
        } while (it != end);
    }
    dataLog("-----------------------------------------------------------------------------\n");

    end = it + codeBlock->m_numCalleeRegisters - codeBlock->m_numVars;
    if (it != end) {
        do {
            v = (*it).jsValue();
#if USE(JSVALUE32_64)
            dataLog("[r%2d]                      | %10p | %-16s 0x%llx \n", registerCount, it, v.description(), JSValue::encode(v));
#else
            dataLog("[r%2d]                      | %10p | %-16s %p \n", registerCount, it, v.description(), JSValue::encode(v));
#endif
            ++it;
            ++registerCount;
        } while (it != end);
    }
    dataLog("-----------------------------------------------------------------------------\n");
}

#endif

bool Interpreter::isOpcode(Opcode opcode)
{
#if ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER) || ENABLE(LLINT)
#if !ENABLE(LLINT)
    if (!m_classicEnabled)
        return opcode >= 0 && static_cast<OpcodeID>(bitwise_cast<uintptr_t>(opcode)) <= op_end;
#endif
    return opcode != HashTraits<Opcode>::emptyValue()
        && !HashTraits<Opcode>::isDeletedValue(opcode)
        && m_opcodeIDTable.contains(opcode);
#else
    return opcode >= 0 && opcode <= op_end;
#endif
}

NEVER_INLINE bool Interpreter::unwindCallFrame(CallFrame*& callFrame, JSValue exceptionValue, unsigned& bytecodeOffset, CodeBlock*& codeBlock)
{
    CodeBlock* oldCodeBlock = codeBlock;
    ScopeChainNode* scopeChain = callFrame->scopeChain();

    if (Debugger* debugger = callFrame->dynamicGlobalObject()->debugger()) {
        DebuggerCallFrame debuggerCallFrame(callFrame, exceptionValue);
        if (callFrame->callee())
            debugger->returnEvent(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->lastLine());
        else
            debugger->didExecuteProgram(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->lastLine());
    }

    // If this call frame created an activation or an 'arguments' object, tear it off.
    if (oldCodeBlock->codeType() == FunctionCode && oldCodeBlock->needsFullScopeChain()) {
        if (!callFrame->uncheckedR(oldCodeBlock->activationRegister()).jsValue()) {
            oldCodeBlock->createActivation(callFrame);
            scopeChain = callFrame->scopeChain();
        }
        while (!scopeChain->object->inherits(&JSActivation::s_info))
            scopeChain = scopeChain->pop();

        callFrame->setScopeChain(scopeChain);
        JSActivation* activation = asActivation(scopeChain->object.get());
        activation->tearOff(*scopeChain->globalData);
        if (JSValue arguments = callFrame->uncheckedR(unmodifiedArgumentsRegister(oldCodeBlock->argumentsRegister())).jsValue())
            asArguments(arguments)->didTearOffActivation(callFrame->globalData(), activation);
    } else if (oldCodeBlock->usesArguments() && !oldCodeBlock->isStrictMode()) {
        if (JSValue arguments = callFrame->uncheckedR(unmodifiedArgumentsRegister(oldCodeBlock->argumentsRegister())).jsValue())
            asArguments(arguments)->tearOff(callFrame);
    }

    CallFrame* callerFrame = callFrame->callerFrame();
    callFrame->globalData().topCallFrame = callerFrame;
    if (callerFrame->hasHostCallFrameFlag())
        return false;

    codeBlock = callerFrame->codeBlock();
    
    // Because of how the JIT records call site->bytecode offset
    // information the JIT reports the bytecodeOffset for the returnPC
    // to be at the beginning of the opcode that has caused the call.
    // In the interpreter we have an actual return address, which is
    // the beginning of next instruction to execute. To get an offset
    // inside the call instruction that triggered the exception we
    // have to subtract 1.
#if ENABLE(JIT) && ENABLE(CLASSIC_INTERPRETER)
    if (callerFrame->globalData().canUseJIT())
        bytecodeOffset = codeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
    else
        bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnVPC()) - 1;
#elif ENABLE(JIT)
    bytecodeOffset = codeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
#else
    bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnVPC()) - 1;
#endif

    callFrame = callerFrame;
    return true;
}

static void appendSourceToError(CallFrame* callFrame, ErrorInstance* exception, unsigned bytecodeOffset)
{
    exception->clearAppendSourceToMessage();

    if (!callFrame->codeBlock()->hasExpressionInfo())
        return;

    int startOffset = 0;
    int endOffset = 0;
    int divotPoint = 0;

    CodeBlock* codeBlock = callFrame->codeBlock();
    codeBlock->expressionRangeForBytecodeOffset(bytecodeOffset, divotPoint, startOffset, endOffset);

    int expressionStart = divotPoint - startOffset;
    int expressionStop = divotPoint + endOffset;

    if (!expressionStop || expressionStart > codeBlock->source()->length())
        return;

    JSGlobalData* globalData = &callFrame->globalData();
    JSValue jsMessage = exception->getDirect(*globalData, globalData->propertyNames->message);
    if (!jsMessage || !jsMessage.isString())
        return;

    UString message = asString(jsMessage)->value(callFrame);

    if (expressionStart < expressionStop)
        message =  makeUString(message, " (evaluating '", codeBlock->source()->getRange(expressionStart, expressionStop), "')");
    else {
        // No range information, so give a few characters of context
        const StringImpl* data = codeBlock->source()->data();
        int dataLength = codeBlock->source()->length();
        int start = expressionStart;
        int stop = expressionStart;
        // Get up to 20 characters of context to the left and right of the divot, clamping to the line.
        // then strip whitespace.
        while (start > 0 && (expressionStart - start < 20) && (*data)[start - 1] != '\n')
            start--;
        while (start < (expressionStart - 1) && isStrWhiteSpace((*data)[start]))
            start++;
        while (stop < dataLength && (stop - expressionStart < 20) && (*data)[stop] != '\n')
            stop++;
        while (stop > expressionStart && isStrWhiteSpace((*data)[stop - 1]))
            stop--;
        message = makeUString(message, " (near '...", codeBlock->source()->getRange(start, stop), "...')");
    }

    exception->putDirect(*globalData, globalData->propertyNames->message, jsString(globalData, message));
}

static int getLineNumberForCallFrame(JSGlobalData* globalData, CallFrame* callFrame)
{
    UNUSED_PARAM(globalData);
    callFrame = callFrame->removeHostCallFrameFlag();
    CodeBlock* codeBlock = callFrame->codeBlock();
    if (!codeBlock)
        return -1;
#if ENABLE(CLASSIC_INTERPRETER)
    if (!globalData->canUseJIT())
        return codeBlock->lineNumberForBytecodeOffset(callFrame->bytecodeOffsetForNonDFGCode() - 1);
#endif
#if ENABLE(JIT)
#if ENABLE(DFG_JIT)
    if (codeBlock->getJITType() == JITCode::DFGJIT)
        return codeBlock->lineNumberForBytecodeOffset(codeBlock->codeOrigin(callFrame->codeOriginIndexForDFG()).bytecodeIndex);
#endif
    return codeBlock->lineNumberForBytecodeOffset(callFrame->bytecodeOffsetForNonDFGCode());
#else
    return -1;
#endif
}

static CallFrame* getCallerInfo(JSGlobalData* globalData, CallFrame* callFrame, int& lineNumber)
{
    UNUSED_PARAM(globalData);
    unsigned bytecodeOffset = 0;
    lineNumber = -1;
    ASSERT(!callFrame->hasHostCallFrameFlag());
    CallFrame* callerFrame = callFrame->codeBlock() ? callFrame->trueCallerFrame() : 0;
    bool callframeIsHost = callerFrame->addHostCallFrameFlag() == callFrame->callerFrame();
    ASSERT(!callerFrame->hasHostCallFrameFlag());

    if (callerFrame == CallFrame::noCaller() || !callerFrame || !callerFrame->codeBlock())
        return callerFrame;

    CodeBlock* callerCodeBlock = callerFrame->codeBlock();

    if (callframeIsHost) {
        // Don't need to deal with inline callframes here as by definition we haven't
        // inlined a call with an intervening native call frame.
#if ENABLE(CLASSIC_INTERPRETER)
        if (!globalData->canUseJIT()) {
            bytecodeOffset = callerFrame->bytecodeOffsetForNonDFGCode();
            lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset - 1);
            return callerFrame;
        }
#endif
#if ENABLE(JIT)
#if ENABLE(DFG_JIT)
        if (callerCodeBlock && callerCodeBlock->getJITType() == JITCode::DFGJIT)
            bytecodeOffset = callerCodeBlock->codeOrigin(callerFrame->codeOriginIndexForDFG()).bytecodeIndex;
        else
#endif
            bytecodeOffset = callerFrame->bytecodeOffsetForNonDFGCode();
#endif
    } else {
#if ENABLE(CLASSIC_INTERPRETER)
        if (!globalData->canUseJIT()) {
            bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnVPC());
            lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset - 1);
            return callerFrame;
        }
#endif
#if ENABLE(JIT)
    #if ENABLE(DFG_JIT)
        if (callFrame->isInlineCallFrame()) {
            InlineCallFrame* icf = callFrame->inlineCallFrame();
            bytecodeOffset = icf->caller.bytecodeIndex;
            if (InlineCallFrame* parentCallFrame = icf->caller.inlineCallFrame) {
                FunctionExecutable* executable = static_cast<FunctionExecutable*>(parentCallFrame->executable.get());
                CodeBlock* newCodeBlock = executable->baselineCodeBlockFor(parentCallFrame->isCall ? CodeForCall : CodeForConstruct);
                ASSERT(newCodeBlock);
                ASSERT(newCodeBlock->instructionCount() > bytecodeOffset);
                callerCodeBlock = newCodeBlock;
            }
        } else if (callerCodeBlock && callerCodeBlock->getJITType() == JITCode::DFGJIT) {
            CodeOrigin origin;
            if (!callerCodeBlock->codeOriginForReturn(callFrame->returnPC(), origin))
                ASSERT_NOT_REACHED();
            bytecodeOffset = origin.bytecodeIndex;
            if (InlineCallFrame* icf = origin.inlineCallFrame) {
                FunctionExecutable* executable = static_cast<FunctionExecutable*>(icf->executable.get());
                CodeBlock* newCodeBlock = executable->baselineCodeBlockFor(icf->isCall ? CodeForCall : CodeForConstruct);
                ASSERT(newCodeBlock);
                ASSERT(newCodeBlock->instructionCount() > bytecodeOffset);
                callerCodeBlock = newCodeBlock;
            }
        } else
    #endif
            bytecodeOffset = callerCodeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
#endif
    }

    lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset);
    return callerFrame;
}

static ALWAYS_INLINE const UString getSourceURLFromCallFrame(CallFrame* callFrame) 
{
    ASSERT(!callFrame->hasHostCallFrameFlag());
#if ENABLE(CLASSIC_INTERPRETER)
#if ENABLE(JIT)
    if (callFrame->globalData().canUseJIT())
        return callFrame->codeBlock()->ownerExecutable()->sourceURL();
#endif
    return callFrame->codeBlock()->source()->url();

#else
    return callFrame->codeBlock()->ownerExecutable()->sourceURL();
#endif
}

static StackFrameCodeType getStackFrameCodeType(CallFrame* callFrame)
{
    ASSERT(!callFrame->hasHostCallFrameFlag());

    switch (callFrame->codeBlock()->codeType()) {
    case EvalCode:
        return StackFrameEvalCode;
    case FunctionCode:
        return StackFrameFunctionCode;
    case GlobalCode:
        return StackFrameGlobalCode;
    }
    ASSERT_NOT_REACHED();
    return StackFrameGlobalCode;
}

void Interpreter::getStackTrace(JSGlobalData* globalData, int line, Vector<StackFrame>& results)
{
    CallFrame* callFrame = globalData->topCallFrame->removeHostCallFrameFlag()->trueCallFrameFromVMCode();
    if (!callFrame || callFrame == CallFrame::noCaller()) 
        return;

    if (line == -1)
        line = getLineNumberForCallFrame(globalData, callFrame);

    while (callFrame && callFrame != CallFrame::noCaller()) {
        UString sourceURL;
        if (callFrame->codeBlock()) {
            sourceURL = getSourceURLFromCallFrame(callFrame);
            StackFrame s = { Strong<JSObject>(*globalData, callFrame->callee()), getStackFrameCodeType(callFrame), Strong<ExecutableBase>(*globalData, callFrame->codeBlock()->ownerExecutable()), line, sourceURL};
            results.append(s);
        } else {
            StackFrame s = { Strong<JSObject>(*globalData, callFrame->callee()), StackFrameNativeCode, Strong<ExecutableBase>(), -1, UString()};
            results.append(s);
        }
        callFrame = getCallerInfo(globalData, callFrame, line);
    }
}

NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSValue& exceptionValue, unsigned bytecodeOffset)
{
    CodeBlock* codeBlock = callFrame->codeBlock();
    bool isInterrupt = false;

    // Set up the exception object
    if (exceptionValue.isObject()) {
        JSObject* exception = asObject(exceptionValue);

        if (exception->isErrorInstance() && static_cast<ErrorInstance*>(exception)->appendSourceToMessage())
            appendSourceToError(callFrame, static_cast<ErrorInstance*>(exception), bytecodeOffset);

        // Using hasExpressionInfo to imply we are interested in rich exception info.
        if (codeBlock->hasExpressionInfo() && !hasErrorInfo(callFrame, exception)) {
            ASSERT(codeBlock->hasLineInfo());

            // FIXME: should only really be adding these properties to VM generated exceptions,
            // but the inspector currently requires these for all thrown objects.
            Vector<StackFrame> stackTrace;
            getStackTrace(&callFrame->globalData(), codeBlock->lineNumberForBytecodeOffset(bytecodeOffset), stackTrace);
            addErrorInfo(callFrame, exception, codeBlock->lineNumberForBytecodeOffset(bytecodeOffset), codeBlock->ownerExecutable()->source(), stackTrace);
        }

        isInterrupt = isInterruptedExecutionException(exception) || isTerminatedExecutionException(exception);
    }

    if (Debugger* debugger = callFrame->dynamicGlobalObject()->debugger()) {
        DebuggerCallFrame debuggerCallFrame(callFrame, exceptionValue);
        bool hasHandler = codeBlock->handlerForBytecodeOffset(bytecodeOffset);
        debugger->exception(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->lineNumberForBytecodeOffset(bytecodeOffset), hasHandler);
    }

    // Calculate an exception handler vPC, unwinding call frames as necessary.
    HandlerInfo* handler = 0;
    while (isInterrupt || !(handler = codeBlock->handlerForBytecodeOffset(bytecodeOffset))) {
        if (!unwindCallFrame(callFrame, exceptionValue, bytecodeOffset, codeBlock)) {
            if (Profiler* profiler = *Profiler::enabledProfilerReference())
                profiler->exceptionUnwind(callFrame);
            return 0;
        }
    }

    if (Profiler* profiler = *Profiler::enabledProfilerReference())
        profiler->exceptionUnwind(callFrame);

    // Shrink the JS stack, in case stack overflow made it huge.
    Register* highWaterMark = 0;
    for (CallFrame* callerFrame = callFrame; callerFrame; callerFrame = callerFrame->callerFrame()->removeHostCallFrameFlag()) {
        CodeBlock* codeBlock = callerFrame->codeBlock();
        if (!codeBlock)
            continue;
        Register* callerHighWaterMark = callerFrame->registers() + codeBlock->m_numCalleeRegisters;
        highWaterMark = max(highWaterMark, callerHighWaterMark);
    }
    m_registerFile.shrink(highWaterMark);

    // Unwind the scope chain within the exception handler's call frame.
    ScopeChainNode* scopeChain = callFrame->scopeChain();
    int scopeDelta = 0;
    if (!codeBlock->needsFullScopeChain() || codeBlock->codeType() != FunctionCode 
        || callFrame->uncheckedR(codeBlock->activationRegister()).jsValue())
        scopeDelta = depth(codeBlock, scopeChain) - handler->scopeDepth;
    ASSERT(scopeDelta >= 0);
    while (scopeDelta--)
        scopeChain = scopeChain->pop();
    callFrame->setScopeChain(scopeChain);

    return handler;
}

static inline JSValue checkedReturn(JSValue returnValue)
{
    ASSERT(returnValue);
    return returnValue;
}

static inline JSObject* checkedReturn(JSObject* returnValue)
{
    ASSERT(returnValue);
    return returnValue;
}

JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, ScopeChainNode* scopeChain, JSObject* thisObj)
{
    ASSERT(isValidThisObject(thisObj, callFrame));
    ASSERT(!scopeChain->globalData->exception);
    ASSERT(!callFrame->globalData().isCollectorBusy());
    if (callFrame->globalData().isCollectorBusy())
        return jsNull();

    if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth)
        return checkedReturn(throwStackOverflowError(callFrame));

    DynamicGlobalObjectScope globalObjectScope(*scopeChain->globalData, scopeChain->globalObject.get());
    Vector<JSONPData> JSONPData;
    bool parseResult;
    const UString programSource = program->source().toString();
    if (programSource.isNull())
        return jsUndefined();
    if (programSource.is8Bit()) {
        LiteralParser<LChar> literalParser(callFrame, programSource.characters8(), programSource.length(), JSONP);
        parseResult = literalParser.tryJSONPParse(JSONPData, scopeChain->globalObject->globalObjectMethodTable()->supportsRichSourceInfo(scopeChain->globalObject.get()));
    } else {
        LiteralParser<UChar> literalParser(callFrame, programSource.characters16(), programSource.length(), JSONP);
        parseResult = literalParser.tryJSONPParse(JSONPData, scopeChain->globalObject->globalObjectMethodTable()->supportsRichSourceInfo(scopeChain->globalObject.get()));
    }

    if (parseResult) {
        JSGlobalObject* globalObject = scopeChain->globalObject.get();
        JSValue result;
        for (unsigned entry = 0; entry < JSONPData.size(); entry++) {
            Vector<JSONPPathEntry> JSONPPath;
            JSONPPath.swap(JSONPData[entry].m_path);
            JSValue JSONPValue = JSONPData[entry].m_value.get();
            if (JSONPPath.size() == 1 && JSONPPath[0].m_type == JSONPPathEntryTypeDeclare) {
                if (globalObject->hasProperty(callFrame, JSONPPath[0].m_pathEntryName)) {
                    PutPropertySlot slot;
                    globalObject->methodTable()->put(globalObject, callFrame, JSONPPath[0].m_pathEntryName, JSONPValue, slot);
                } else
                    globalObject->methodTable()->putDirectVirtual(globalObject, callFrame, JSONPPath[0].m_pathEntryName, JSONPValue, DontEnum | DontDelete);
                // var declarations return undefined
                result = jsUndefined();
                continue;
            }
            JSValue baseObject(globalObject);
            for (unsigned i = 0; i < JSONPPath.size() - 1; i++) {
                ASSERT(JSONPPath[i].m_type != JSONPPathEntryTypeDeclare);
                switch (JSONPPath[i].m_type) {
                case JSONPPathEntryTypeDot: {
                    if (i == 0) {
                        PropertySlot slot(globalObject);
                        if (!globalObject->getPropertySlot(callFrame, JSONPPath[i].m_pathEntryName, slot)) {
                            if (entry)
                                return throwError(callFrame, createUndefinedVariableError(globalObject->globalExec(), JSONPPath[i].m_pathEntryName));
                            goto failedJSONP;
                        }
                        baseObject = slot.getValue(callFrame, JSONPPath[i].m_pathEntryName);
                    } else
                        baseObject = baseObject.get(callFrame, JSONPPath[i].m_pathEntryName);
                    if (callFrame->hadException())
                        return jsUndefined();
                    continue;
                }
                case JSONPPathEntryTypeLookup: {
                    baseObject = baseObject.get(callFrame, JSONPPath[i].m_pathIndex);
                    if (callFrame->hadException())
                        return jsUndefined();
                    continue;
                }
                default:
                    ASSERT_NOT_REACHED();
                    return jsUndefined();
                }
            }
            PutPropertySlot slot;
            switch (JSONPPath.last().m_type) {
            case JSONPPathEntryTypeCall: {
                JSValue function = baseObject.get(callFrame, JSONPPath.last().m_pathEntryName);
                if (callFrame->hadException())
                    return jsUndefined();
                CallData callData;
                CallType callType = getCallData(function, callData);
                if (callType == CallTypeNone)
                    return throwError(callFrame, createNotAFunctionError(callFrame, function));
                MarkedArgumentBuffer jsonArg;
                jsonArg.append(JSONPValue);
                JSValue thisValue = JSONPPath.size() == 1 ? jsUndefined(): baseObject;
                JSONPValue = JSC::call(callFrame, function, callType, callData, thisValue, jsonArg);
                if (callFrame->hadException())
                    return jsUndefined();
                break;
            }
            case JSONPPathEntryTypeDot: {
                baseObject.put(callFrame, JSONPPath.last().m_pathEntryName, JSONPValue, slot);
                if (callFrame->hadException())
                    return jsUndefined();
                break;
            }
            case JSONPPathEntryTypeLookup: {
                baseObject.put(callFrame, JSONPPath.last().m_pathIndex, JSONPValue);
                if (callFrame->hadException())
                    return jsUndefined();
                break;
            }
            default:
                ASSERT_NOT_REACHED();
                    return jsUndefined();
            }
            result = JSONPValue;
        }
        return result;
    }
failedJSONP:
    JSObject* error = program->compile(callFrame, scopeChain);
    if (error)
        return checkedReturn(throwError(callFrame, error));
    CodeBlock* codeBlock = &program->generatedBytecode();

    Register* oldEnd = m_registerFile.end();
    Register* newEnd = oldEnd + codeBlock->numParameters() + RegisterFile::CallFrameHeaderSize + codeBlock->m_numCalleeRegisters;
    if (!m_registerFile.grow(newEnd))
        return checkedReturn(throwStackOverflowError(callFrame));

    CallFrame* newCallFrame = CallFrame::create(oldEnd + codeBlock->numParameters() + RegisterFile::CallFrameHeaderSize);
    ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'.
    newCallFrame->init(codeBlock, 0, scopeChain, CallFrame::noCaller(), codeBlock->numParameters(), 0);
    newCallFrame->setThisValue(thisObj);
    TopCallFrameSetter topCallFrame(callFrame->globalData(), newCallFrame);

    Profiler** profiler = Profiler::enabledProfilerReference();
    if (*profiler)
        (*profiler)->willExecute(callFrame, program->sourceURL(), program->lineNo());

    JSValue result;
    {
        SamplingTool::CallRecord callRecord(m_sampler.get());

        m_reentryDepth++;  
#if ENABLE(JIT)
        if (callFrame->globalData().canUseJIT())
            result = program->generatedJITCode().execute(&m_registerFile, newCallFrame, scopeChain->globalData);
        else
#endif
            result = privateExecute(Normal, &m_registerFile, newCallFrame);

        m_reentryDepth--;
    }

    if (*profiler)
        (*profiler)->didExecute(callFrame, program->sourceURL(), program->lineNo());

    m_registerFile.shrink(oldEnd);

    return checkedReturn(result);
}

JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallType callType, const CallData& callData, JSValue thisValue, const ArgList& args)
{
    ASSERT(isValidThisObject(thisValue, callFrame));
    ASSERT(!callFrame->hadException());
    ASSERT(!callFrame->globalData().isCollectorBusy());
    if (callFrame->globalData().isCollectorBusy())
        return jsNull();

    if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth)
        return checkedReturn(throwStackOverflowError(callFrame));

    Register* oldEnd = m_registerFile.end();
    int argCount = 1 + args.size(); // implicit "this" parameter
    size_t registerOffset = argCount + RegisterFile::CallFrameHeaderSize;

    CallFrame* newCallFrame = CallFrame::create(oldEnd + registerOffset);
    if (!m_registerFile.grow(newCallFrame->registers()))
        return checkedReturn(throwStackOverflowError(callFrame));

    newCallFrame->setThisValue(thisValue);
    for (size_t i = 0; i < args.size(); ++i)
        newCallFrame->setArgument(i, args.at(i));

    if (callType == CallTypeJS) {
        ScopeChainNode* callDataScopeChain = callData.js.scopeChain;

        DynamicGlobalObjectScope globalObjectScope(*callDataScopeChain->globalData, callDataScopeChain->globalObject.get());

        JSObject* compileError = callData.js.functionExecutable->compileForCall(callFrame, callDataScopeChain);
        if (UNLIKELY(!!compileError)) {
            m_registerFile.shrink(oldEnd);
            return checkedReturn(throwError(callFrame, compileError));
        }

        CodeBlock* newCodeBlock = &callData.js.functionExecutable->generatedBytecodeForCall();
        newCallFrame = slideRegisterWindowForCall(newCodeBlock, &m_registerFile, newCallFrame, 0, argCount);
        if (UNLIKELY(!newCallFrame)) {
            m_registerFile.shrink(oldEnd);
            return checkedReturn(throwStackOverflowError(callFrame));
        }

        newCallFrame->init(newCodeBlock, 0, callDataScopeChain, callFrame->addHostCallFrameFlag(), argCount, function);

        TopCallFrameSetter topCallFrame(callFrame->globalData(), newCallFrame);

        Profiler** profiler = Profiler::enabledProfilerReference();
        if (*profiler)
            (*profiler)->willExecute(callFrame, function);

        JSValue result;
        {
            SamplingTool::CallRecord callRecord(m_sampler.get());

            m_reentryDepth++;  
#if ENABLE(JIT)
            if (callFrame->globalData().canUseJIT())
                result = callData.js.functionExecutable->generatedJITCodeForCall().execute(&m_registerFile, newCallFrame, callDataScopeChain->globalData);
            else
#endif
                result = privateExecute(Normal, &m_registerFile, newCallFrame);
            m_reentryDepth--;
        }

        if (*profiler)
            (*profiler)->didExecute(callFrame, function);

        m_registerFile.shrink(oldEnd);
        return checkedReturn(result);
    }

    ASSERT(callType == CallTypeHost);
    ScopeChainNode* scopeChain = callFrame->scopeChain();
    newCallFrame->init(0, 0, scopeChain, callFrame->addHostCallFrameFlag(), argCount, function);

    TopCallFrameSetter topCallFrame(callFrame->globalData(), newCallFrame);

    DynamicGlobalObjectScope globalObjectScope(*scopeChain->globalData, scopeChain->globalObject.get());

    Profiler** profiler = Profiler::enabledProfilerReference();
    if (*profiler)
        (*profiler)->willExecute(callFrame, function);

    JSValue result;
    {
        SamplingTool::HostCallRecord callRecord(m_sampler.get());
        result = JSValue::decode(callData.native.function(newCallFrame));
    }

    if (*profiler)
        (*profiler)->didExecute(callFrame, function);

    m_registerFile.shrink(oldEnd);
    return checkedReturn(result);
}

JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* constructor, ConstructType constructType, const ConstructData& constructData, const ArgList& args)
{
    ASSERT(!callFrame->hadException());
    ASSERT(!callFrame->globalData().isCollectorBusy());
    // We throw in this case because we have to return something "valid" but we're
    // already in an invalid state.
    if (callFrame->globalData().isCollectorBusy())
        return checkedReturn(throwStackOverflowError(callFrame));

    if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth)
        return checkedReturn(throwStackOverflowError(callFrame));

    Register* oldEnd = m_registerFile.end();
    int argCount = 1 + args.size(); // implicit "this" parameter
    size_t registerOffset = argCount + RegisterFile::CallFrameHeaderSize;

    if (!m_registerFile.grow(oldEnd + registerOffset))
        return checkedReturn(throwStackOverflowError(callFrame));

    CallFrame* newCallFrame = CallFrame::create(oldEnd + registerOffset);
    newCallFrame->setThisValue(jsUndefined());
    for (size_t i = 0; i < args.size(); ++i)
        newCallFrame->setArgument(i, args.at(i));

    if (constructType == ConstructTypeJS) {
        ScopeChainNode* constructDataScopeChain = constructData.js.scopeChain;

        DynamicGlobalObjectScope globalObjectScope(*constructDataScopeChain->globalData, constructDataScopeChain->globalObject.get());

        JSObject* compileError = constructData.js.functionExecutable->compileForConstruct(callFrame, constructDataScopeChain);
        if (UNLIKELY(!!compileError)) {
            m_registerFile.shrink(oldEnd);
            return checkedReturn(throwError(callFrame, compileError));
        }

        CodeBlock* newCodeBlock = &constructData.js.functionExecutable->generatedBytecodeForConstruct();
        newCallFrame = slideRegisterWindowForCall(newCodeBlock, &m_registerFile, newCallFrame, 0, argCount);
        if (UNLIKELY(!newCallFrame)) {
            m_registerFile.shrink(oldEnd);
            return checkedReturn(throwStackOverflowError(callFrame));
        }

        newCallFrame->init(newCodeBlock, 0, constructDataScopeChain, callFrame->addHostCallFrameFlag(), argCount, constructor);

        TopCallFrameSetter topCallFrame(callFrame->globalData(), newCallFrame);

        Profiler** profiler = Profiler::enabledProfilerReference();
        if (*profiler)
            (*profiler)->willExecute(callFrame, constructor);

        JSValue result;
        {
            SamplingTool::CallRecord callRecord(m_sampler.get());

            m_reentryDepth++;  
#if ENABLE(JIT)
            if (callFrame->globalData().canUseJIT())
                result = constructData.js.functionExecutable->generatedJITCodeForConstruct().execute(&m_registerFile, newCallFrame, constructDataScopeChain->globalData);
            else
#endif
                result = privateExecute(Normal, &m_registerFile, newCallFrame);
            m_reentryDepth--;
        }

        if (*profiler)
            (*profiler)->didExecute(callFrame, constructor);

        m_registerFile.shrink(oldEnd);
        if (callFrame->hadException())
            return 0;
        ASSERT(result.isObject());
        return checkedReturn(asObject(result));
    }

    ASSERT(constructType == ConstructTypeHost);
    ScopeChainNode* scopeChain = callFrame->scopeChain();
    newCallFrame->init(0, 0, scopeChain, callFrame->addHostCallFrameFlag(), argCount, constructor);

    TopCallFrameSetter topCallFrame(callFrame->globalData(), newCallFrame);

    DynamicGlobalObjectScope globalObjectScope(*scopeChain->globalData, scopeChain->globalObject.get());

    Profiler** profiler = Profiler::enabledProfilerReference();
    if (*profiler)
        (*profiler)->willExecute(callFrame, constructor);

    JSValue result;
    {
        SamplingTool::HostCallRecord callRecord(m_sampler.get());
        result = JSValue::decode(constructData.native.function(newCallFrame));
    }

    if (*profiler)
        (*profiler)->didExecute(callFrame, constructor);

    m_registerFile.shrink(oldEnd);
    if (callFrame->hadException())
        return 0;
    ASSERT(result.isObject());
    return checkedReturn(asObject(result));
}

CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* functionExecutable, CallFrame* callFrame, JSFunction* function, int argumentCountIncludingThis, ScopeChainNode* scopeChain)
{
    ASSERT(!scopeChain->globalData->exception);
    
    if (callFrame->globalData().isCollectorBusy())
        return CallFrameClosure();

    if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth) {
        throwStackOverflowError(callFrame);
        return CallFrameClosure();
    }

    Register* oldEnd = m_registerFile.end();
    size_t registerOffset = argumentCountIncludingThis + RegisterFile::CallFrameHeaderSize;

    CallFrame* newCallFrame = CallFrame::create(oldEnd + registerOffset);
    if (!m_registerFile.grow(newCallFrame->registers())) {
        throwStackOverflowError(callFrame);
        return CallFrameClosure();
    }

    JSObject* error = functionExecutable->compileForCall(callFrame, scopeChain);
    if (error) {
        throwError(callFrame, error);
        m_registerFile.shrink(oldEnd);
        return CallFrameClosure();
    }
    CodeBlock* codeBlock = &functionExecutable->generatedBytecodeForCall();

    newCallFrame = slideRegisterWindowForCall(codeBlock, &m_registerFile, newCallFrame, 0, argumentCountIncludingThis);
    if (UNLIKELY(!newCallFrame)) {
        throwStackOverflowError(callFrame);
        m_registerFile.shrink(oldEnd);
        return CallFrameClosure();
    }
    newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag(), argumentCountIncludingThis, function);  
    scopeChain->globalData->topCallFrame = newCallFrame;
    CallFrameClosure result = { callFrame, newCallFrame, function, functionExecutable, scopeChain->globalData, oldEnd, scopeChain, codeBlock->numParameters(), argumentCountIncludingThis };
    return result;
}

JSValue Interpreter::execute(CallFrameClosure& closure) 
{
    ASSERT(!closure.oldCallFrame->globalData().isCollectorBusy());
    if (closure.oldCallFrame->globalData().isCollectorBusy())
        return jsNull();
    closure.resetCallFrame();
    Profiler** profiler = Profiler::enabledProfilerReference();
    if (*profiler)
        (*profiler)->willExecute(closure.oldCallFrame, closure.function);

    TopCallFrameSetter topCallFrame(*closure.globalData, closure.newCallFrame);

    JSValue result;
    {
        SamplingTool::CallRecord callRecord(m_sampler.get());
        
        m_reentryDepth++;  
#if ENABLE(JIT)
#if ENABLE(CLASSIC_INTERPRETER)
        if (closure.newCallFrame->globalData().canUseJIT())
#endif
            result = closure.functionExecutable->generatedJITCodeForCall().execute(&m_registerFile, closure.newCallFrame, closure.globalData);
#if ENABLE(CLASSIC_INTERPRETER)
        else
#endif
#endif
#if ENABLE(CLASSIC_INTERPRETER)
            result = privateExecute(Normal, &m_registerFile, closure.newCallFrame);
#endif
        m_reentryDepth--;
    }

    if (*profiler)
        (*profiler)->didExecute(closure.oldCallFrame, closure.function);
    return checkedReturn(result);
}

void Interpreter::endRepeatCall(CallFrameClosure& closure)
{
    closure.globalData->topCallFrame = closure.oldCallFrame;
    m_registerFile.shrink(closure.oldEnd);
}

JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue thisValue, ScopeChainNode* scopeChain, int globalRegisterOffset)
{
    ASSERT(isValidThisObject(thisValue, callFrame));
    ASSERT(!scopeChain->globalData->exception);
    ASSERT(!callFrame->globalData().isCollectorBusy());
    if (callFrame->globalData().isCollectorBusy())
        return jsNull();

    DynamicGlobalObjectScope globalObjectScope(*scopeChain->globalData, scopeChain->globalObject.get());

    if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth)
        return checkedReturn(throwStackOverflowError(callFrame));

    JSObject* compileError = eval->compile(callFrame, scopeChain);
    if (UNLIKELY(!!compileError))
        return checkedReturn(throwError(callFrame, compileError));
    EvalCodeBlock* codeBlock = &eval->generatedBytecode();

    JSObject* variableObject;
    for (ScopeChainNode* node = scopeChain; ; node = node->next.get()) {
        ASSERT(node);
        if (node->object->isVariableObject() && !node->object->isStaticScopeObject()) {
            variableObject = static_cast<JSVariableObject*>(node->object.get());
            break;
        }
    }

    unsigned numVariables = codeBlock->numVariables();
    int numFunctions = codeBlock->numberOfFunctionDecls();
    bool pushedScope = false;
    if (numVariables || numFunctions) {
        if (codeBlock->isStrictMode()) {
            variableObject = StrictEvalActivation::create(callFrame);
            scopeChain = scopeChain->push(variableObject);
            pushedScope = true;
        }
        // Scope for BatchedTransitionOptimizer
        BatchedTransitionOptimizer optimizer(callFrame->globalData(), variableObject);

        for (unsigned i = 0; i < numVariables; ++i) {
            const Identifier& ident = codeBlock->variable(i);
            if (!variableObject->hasProperty(callFrame, ident)) {
                PutPropertySlot slot;
                variableObject->methodTable()->put(variableObject, callFrame, ident, jsUndefined(), slot);
            }
        }

        for (int i = 0; i < numFunctions; ++i) {
            FunctionExecutable* function = codeBlock->functionDecl(i);
            PutPropertySlot slot;
            variableObject->methodTable()->put(variableObject, callFrame, function->name(), function->make(callFrame, scopeChain), slot);
        }
    }

    Register* oldEnd = m_registerFile.end();
    Register* newEnd = m_registerFile.begin() + globalRegisterOffset + codeBlock->m_numCalleeRegisters;
    if (!m_registerFile.grow(newEnd)) {
        if (pushedScope)
            scopeChain->pop();
        return checkedReturn(throwStackOverflowError(callFrame));
    }

    CallFrame* newCallFrame = CallFrame::create(m_registerFile.begin() + globalRegisterOffset);

    ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'.
    newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag(), codeBlock->numParameters(), 0);
    newCallFrame->setThisValue(thisValue);

    TopCallFrameSetter topCallFrame(callFrame->globalData(), newCallFrame);

    Profiler** profiler = Profiler::enabledProfilerReference();
    if (*profiler)
        (*profiler)->willExecute(callFrame, eval->sourceURL(), eval->lineNo());

    JSValue result;
    {
        SamplingTool::CallRecord callRecord(m_sampler.get());

        m_reentryDepth++;
        
#if ENABLE(JIT)
#if ENABLE(CLASSIC_INTERPRETER)
        if (callFrame->globalData().canUseJIT())
#endif
            result = eval->generatedJITCode().execute(&m_registerFile, newCallFrame, scopeChain->globalData);
#if ENABLE(CLASSIC_INTERPRETER)
        else
#endif
#endif
#if ENABLE(CLASSIC_INTERPRETER)
            result = privateExecute(Normal, &m_registerFile, newCallFrame);
#endif
        m_reentryDepth--;
    }

    if (*profiler)
        (*profiler)->didExecute(callFrame, eval->sourceURL(), eval->lineNo());

    m_registerFile.shrink(oldEnd);
    if (pushedScope)
        scopeChain->pop();
    return checkedReturn(result);
}

NEVER_INLINE void Interpreter::debug(CallFrame* callFrame, DebugHookID debugHookID, int firstLine, int lastLine)
{
    Debugger* debugger = callFrame->dynamicGlobalObject()->debugger();
    if (!debugger)
        return;

    switch (debugHookID) {
        case DidEnterCallFrame:
            debugger->callEvent(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), firstLine);
            return;
        case WillLeaveCallFrame:
            debugger->returnEvent(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine);
            return;
        case WillExecuteStatement:
            debugger->atStatement(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), firstLine);
            return;
        case WillExecuteProgram:
            debugger->willExecuteProgram(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), firstLine);
            return;
        case DidExecuteProgram:
            debugger->didExecuteProgram(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine);
            return;
        case DidReachBreakpoint:
            debugger->didReachBreakpoint(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine);
            return;
    }
}
    
#if ENABLE(CLASSIC_INTERPRETER)
NEVER_INLINE ScopeChainNode* Interpreter::createExceptionScope(CallFrame* callFrame, const Instruction* vPC)
{
    int dst = vPC[1].u.operand;
    CodeBlock* codeBlock = callFrame->codeBlock();
    Identifier& property = codeBlock->identifier(vPC[2].u.operand);
    JSValue value = callFrame->r(vPC[3].u.operand).jsValue();
    JSObject* scope = JSStaticScopeObject::create(callFrame, property, value, DontDelete);
    callFrame->uncheckedR(dst) = JSValue(scope);

    return callFrame->scopeChain()->push(scope);
}

NEVER_INLINE void Interpreter::tryCachePutByID(CallFrame* callFrame, CodeBlock* codeBlock, Instruction* vPC, JSValue baseValue, const PutPropertySlot& slot)
{
    // Recursive invocation may already have specialized this instruction.
    if (vPC[0].u.opcode != getOpcode(op_put_by_id))
        return;

    if (!baseValue.isCell())
        return;

    // Uncacheable: give up.
    if (!slot.isCacheable()) {
        vPC[0] = getOpcode(op_put_by_id_generic);
        return;
    }
    
    JSCell* baseCell = baseValue.asCell();
    Structure* structure = baseCell->structure();

    if (structure->isUncacheableDictionary() || structure->typeInfo().prohibitsPropertyCaching()) {
        vPC[0] = getOpcode(op_put_by_id_generic);
        return;
    }

    // Cache miss: record Structure to compare against next time.
    Structure* lastStructure = vPC[4].u.structure.get();
    if (structure != lastStructure) {
        // First miss: record Structure to compare against next time.
        if (!lastStructure) {
            vPC[4].u.structure.set(callFrame->globalData(), codeBlock->ownerExecutable(), structure);
            return;
        }

        // Second miss: give up.
        vPC[0] = getOpcode(op_put_by_id_generic);
        return;
    }

    // Cache hit: Specialize instruction and ref Structures.

    // If baseCell != slot.base(), then baseCell must be a proxy for another object.
    if (baseCell != slot.base()) {
        vPC[0] = getOpcode(op_put_by_id_generic);
        return;
    }

    // Structure transition, cache transition info
    if (slot.type() == PutPropertySlot::NewProperty) {
        if (structure->isDictionary()) {
            vPC[0] = getOpcode(op_put_by_id_generic);
            return;
        }

        // put_by_id_transition checks the prototype chain for setters.
        normalizePrototypeChain(callFrame, baseCell);
        JSCell* owner = codeBlock->ownerExecutable();
        JSGlobalData& globalData = callFrame->globalData();
        // Get the prototype here because the call to prototypeChain could cause a 
        // GC allocation, which we don't want to happen while we're in the middle of 
        // initializing the union.
        StructureChain* prototypeChain = structure->prototypeChain(callFrame);
        vPC[0] = getOpcode(op_put_by_id_transition);
        vPC[4].u.structure.set(globalData, owner, structure->previousID());
        vPC[5].u.structure.set(globalData, owner, structure);
        vPC[6].u.structureChain.set(callFrame->globalData(), codeBlock->ownerExecutable(), prototypeChain);
        ASSERT(vPC[6].u.structureChain);
        vPC[7] = slot.cachedOffset();
        return;
    }

    vPC[0] = getOpcode(op_put_by_id_replace);
    vPC[5] = slot.cachedOffset();
}

NEVER_INLINE void Interpreter::uncachePutByID(CodeBlock*, Instruction* vPC)
{
    vPC[0] = getOpcode(op_put_by_id);
    vPC[4] = 0;
}

NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock* codeBlock, Instruction* vPC, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot)
{
    // Recursive invocation may already have specialized this instruction.
    if (vPC[0].u.opcode != getOpcode(op_get_by_id))
        return;

    // FIXME: Cache property access for immediates.
    if (!baseValue.isCell()) {
        vPC[0] = getOpcode(op_get_by_id_generic);
        return;
    }

    if (isJSArray(baseValue) && propertyName == callFrame->propertyNames().length) {
        vPC[0] = getOpcode(op_get_array_length);
        return;
    }

    if (isJSString(baseValue) && propertyName == callFrame->propertyNames().length) {
        vPC[0] = getOpcode(op_get_string_length);
        return;
    }

    // Uncacheable: give up.
    if (!slot.isCacheable()) {
        vPC[0] = getOpcode(op_get_by_id_generic);
        return;
    }

    Structure* structure = baseValue.asCell()->structure();

    if (structure->isUncacheableDictionary() || structure->typeInfo().prohibitsPropertyCaching()) {
        vPC[0] = getOpcode(op_get_by_id_generic);
        return;
    }

    // Cache miss
    Structure* lastStructure = vPC[4].u.structure.get();
    if (structure != lastStructure) {
        // First miss: record Structure to compare against next time.
        if (!lastStructure) {
            vPC[4].u.structure.set(callFrame->globalData(), codeBlock->ownerExecutable(), structure);
            return;
        }

        // Second miss: give up.
        vPC[0] = getOpcode(op_get_by_id_generic);
        return;
    }

    // Cache hit: Specialize instruction and ref Structures.

    if (slot.slotBase() == baseValue) {
        switch (slot.cachedPropertyType()) {
        case PropertySlot::Getter:
            vPC[0] = getOpcode(op_get_by_id_getter_self);
            vPC[5] = slot.cachedOffset();
            break;
        case PropertySlot::Custom:
            vPC[0] = getOpcode(op_get_by_id_custom_self);
            vPC[5] = slot.customGetter();
            break;
        default:
            vPC[0] = getOpcode(op_get_by_id_self);
            vPC[5] = slot.cachedOffset();
            break;
        }
        return;
    }

    if (structure->isDictionary()) {
        vPC[0] = getOpcode(op_get_by_id_generic);
        return;
    }

    if (slot.slotBase() == structure->prototypeForLookup(callFrame)) {
        ASSERT(slot.slotBase().isObject());

        JSObject* baseObject = asObject(slot.slotBase());
        size_t offset = slot.cachedOffset();

        // Since we're accessing a prototype in a loop, it's a good bet that it
        // should not be treated as a dictionary.
        if (baseObject->structure()->isDictionary()) {
            baseObject->flattenDictionaryObject(callFrame->globalData());
            offset = baseObject->structure()->get(callFrame->globalData(), propertyName);
        }

        ASSERT(!baseObject->structure()->isUncacheableDictionary());
        
        switch (slot.cachedPropertyType()) {
        case PropertySlot::Getter:
            vPC[0] = getOpcode(op_get_by_id_getter_proto);
            vPC[6] = offset;
            break;
        case PropertySlot::Custom:
            vPC[0] = getOpcode(op_get_by_id_custom_proto);
            vPC[6] = slot.customGetter();
            break;
        default:
            vPC[0] = getOpcode(op_get_by_id_proto);
            vPC[6] = offset;
            break;
        }
        vPC[5].u.structure.set(callFrame->globalData(), codeBlock->ownerExecutable(), baseObject->structure());
        return;
    }

    size_t offset = slot.cachedOffset();
    size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset);
    if (!count) {
        vPC[0] = getOpcode(op_get_by_id_generic);
        return;
    }

    
    switch (slot.cachedPropertyType()) {
    case PropertySlot::Getter:
        vPC[0] = getOpcode(op_get_by_id_getter_chain);
        vPC[7] = offset;
        break;
    case PropertySlot::Custom:
        vPC[0] = getOpcode(op_get_by_id_custom_chain);
        vPC[7] = slot.customGetter();
        break;
    default:
        vPC[0] = getOpcode(op_get_by_id_chain);
        vPC[7] = offset;
        break;
    }
    vPC[4].u.structure.set(callFrame->globalData(), codeBlock->ownerExecutable(), structure);
    vPC[5].u.structureChain.set(callFrame->globalData(), codeBlock->ownerExecutable(), structure->prototypeChain(callFrame));
    vPC[6] = count;
}

NEVER_INLINE void Interpreter::uncacheGetByID(CodeBlock*, Instruction* vPC)
{
    vPC[0] = getOpcode(op_get_by_id);
    vPC[4] = 0;
}

#endif // ENABLE(CLASSIC_INTERPRETER)

JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFile, CallFrame* callFrame)
{
    // One-time initialization of our address tables. We have to put this code
    // here because our labels are only in scope inside this function.
    if (UNLIKELY(flag == InitializeAndReturn)) {
        #if ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
            #define LIST_OPCODE_LABEL(id, length) &&id,
                static Opcode labels[] = { FOR_EACH_OPCODE_ID(LIST_OPCODE_LABEL) };
                for (size_t i = 0; i < WTF_ARRAY_LENGTH(labels); ++i)
                    m_opcodeTable[i] = labels[i];
            #undef LIST_OPCODE_LABEL
        #endif // ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
        return JSValue();
    }
    
    ASSERT(m_initialized);
    ASSERT(m_classicEnabled);
    
#if ENABLE(JIT)
#if ENABLE(CLASSIC_INTERPRETER)
    // Mixing Interpreter + JIT is not supported.
    if (callFrame->globalData().canUseJIT())
#endif
        ASSERT_NOT_REACHED();
#endif

#if !ENABLE(CLASSIC_INTERPRETER)
    UNUSED_PARAM(registerFile);
    UNUSED_PARAM(callFrame);
    return JSValue();
#else

    ASSERT(callFrame->globalData().topCallFrame == callFrame);

    JSGlobalData* globalData = &callFrame->globalData();
    JSValue exceptionValue;
    HandlerInfo* handler = 0;
    CallFrame** topCallFrameSlot = &globalData->topCallFrame;

    CodeBlock* codeBlock = callFrame->codeBlock();
    Instruction* vPC = codeBlock->instructions().begin();
    Profiler** enabledProfilerReference = Profiler::enabledProfilerReference();
    unsigned tickCount = globalData->timeoutChecker.ticksUntilNextCheck();
    JSValue functionReturnValue;

#define CHECK_FOR_EXCEPTION() \
    do { \
        if (UNLIKELY(globalData->exception != JSValue())) { \
            exceptionValue = globalData->exception; \
            goto vm_throw; \
        } \
    } while (0)

#if ENABLE(OPCODE_STATS)
    OpcodeStats::resetLastInstruction();
#endif

#define CHECK_FOR_TIMEOUT() \
    if (!--tickCount) { \
        if (globalData->terminator.shouldTerminate() || globalData->timeoutChecker.didTimeOut(callFrame)) { \
            exceptionValue = jsNull(); \
            goto vm_throw; \
        } \
        tickCount = globalData->timeoutChecker.ticksUntilNextCheck(); \
    }
    
#if ENABLE(OPCODE_SAMPLING)
    #define SAMPLE(codeBlock, vPC) m_sampler->sample(codeBlock, vPC)
#else
    #define SAMPLE(codeBlock, vPC)
#endif

#define UPDATE_BYTECODE_OFFSET() \
    do {\
        callFrame->setBytecodeOffsetForNonDFGCode(vPC - codeBlock->instructions().data() + 1);\
    } while (0)

#if ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
    #define NEXT_INSTRUCTION() SAMPLE(codeBlock, vPC); goto *vPC->u.opcode
#if ENABLE(OPCODE_STATS)
    #define DEFINE_OPCODE(opcode) \
        opcode:\
            OpcodeStats::recordInstruction(opcode);\
            UPDATE_BYTECODE_OFFSET();
#else
    #define DEFINE_OPCODE(opcode) opcode: UPDATE_BYTECODE_OFFSET();
#endif
    NEXT_INSTRUCTION();
#else
    #define NEXT_INSTRUCTION() SAMPLE(codeBlock, vPC); goto interpreterLoopStart
#if ENABLE(OPCODE_STATS)
    #define DEFINE_OPCODE(opcode) \
        case opcode:\
            OpcodeStats::recordInstruction(opcode);\
            UPDATE_BYTECODE_OFFSET();
#else
    #define DEFINE_OPCODE(opcode) case opcode: UPDATE_BYTECODE_OFFSET();
#endif
    while (1) { // iterator loop begins
    interpreterLoopStart:;
    switch (vPC->u.opcode)
#endif
    {
    DEFINE_OPCODE(op_new_object) {
        /* new_object dst(r)

           Constructs a new empty Object instance using the original
           constructor, and puts the result in register dst.
        */
        int dst = vPC[1].u.operand;
        callFrame->uncheckedR(dst) = JSValue(constructEmptyObject(callFrame));

        vPC += OPCODE_LENGTH(op_new_object);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_new_array) {
        /* new_array dst(r) firstArg(r) argCount(n)

           Constructs a new Array instance using the original
           constructor, and puts the result in register dst.
           The array will contain argCount elements with values
           taken from registers starting at register firstArg.
        */
        int dst = vPC[1].u.operand;
        int firstArg = vPC[2].u.operand;
        int argCount = vPC[3].u.operand;
        callFrame->uncheckedR(dst) = JSValue(constructArray(callFrame, reinterpret_cast<JSValue*>(&callFrame->registers()[firstArg]), argCount));

        vPC += OPCODE_LENGTH(op_new_array);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_new_array_buffer) {
        /* new_array_buffer dst(r) index(n) argCount(n)
         
         Constructs a new Array instance using the original
         constructor, and puts the result in register dst.
         The array be initialized with the values from constantBuffer[index]
         */
        int dst = vPC[1].u.operand;
        int firstArg = vPC[2].u.operand;
        int argCount = vPC[3].u.operand;
        callFrame->uncheckedR(dst) = JSValue(constructArray(callFrame, codeBlock->constantBuffer(firstArg), argCount));
        
        vPC += OPCODE_LENGTH(op_new_array);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_new_regexp) {
        /* new_regexp dst(r) regExp(re)

           Constructs a new RegExp instance using the original
           constructor from regexp regExp, and puts the result in
           register dst.
        */
        int dst = vPC[1].u.operand;
        RegExp* regExp = codeBlock->regexp(vPC[2].u.operand);
        if (!regExp->isValid()) {
            exceptionValue = createSyntaxError(callFrame, "Invalid flags supplied to RegExp constructor.");
            goto vm_throw;
        }
        callFrame->uncheckedR(dst) = JSValue(RegExpObject::create(*globalData, callFrame->lexicalGlobalObject(), callFrame->scopeChain()->globalObject->regExpStructure(), regExp));

        vPC += OPCODE_LENGTH(op_new_regexp);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_mov) {
        /* mov dst(r) src(r)

           Copies register src to register dst.
        */
        int dst = vPC[1].u.operand;
        int src = vPC[2].u.operand;
        
        callFrame->uncheckedR(dst) = callFrame->r(src);

        vPC += OPCODE_LENGTH(op_mov);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_eq) {
        /* eq dst(r) src1(r) src2(r)

           Checks whether register src1 and register src2 are equal,
           as with the ECMAScript '==' operator, and puts the result
           as a boolean in register dst.
        */
        int dst = vPC[1].u.operand;
        JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
        JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
        if (src1.isInt32() && src2.isInt32())
            callFrame->uncheckedR(dst) = jsBoolean(src1.asInt32() == src2.asInt32());
        else {
            JSValue result = jsBoolean(JSValue::equalSlowCase(callFrame, src1, src2));
            CHECK_FOR_EXCEPTION();
            callFrame->uncheckedR(dst) = result;
        }

        vPC += OPCODE_LENGTH(op_eq);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_eq_null) {
        /* eq_null dst(r) src(r)

           Checks whether register src is null, as with the ECMAScript '!='
           operator, and puts the result as a boolean in register dst.
        */
        int dst = vPC[1].u.operand;
        JSValue src = callFrame->r(vPC[2].u.operand).jsValue();

        if (src.isUndefinedOrNull()) {
            callFrame->uncheckedR(dst) = jsBoolean(true);
            vPC += OPCODE_LENGTH(op_eq_null);
            NEXT_INSTRUCTION();
        }
        
        callFrame->uncheckedR(dst) = jsBoolean(src.isCell() && src.asCell()->structure()->typeInfo().masqueradesAsUndefined());
        vPC += OPCODE_LENGTH(op_eq_null);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_neq) {
        /* neq dst(r) src1(r) src2(r)

           Checks whether register src1 and register src2 are not
           equal, as with the ECMAScript '!=' operator, and puts the
           result as a boolean in register dst.
        */
        int dst = vPC[1].u.operand;
        JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
        JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
        if (src1.isInt32() && src2.isInt32())
            callFrame->uncheckedR(dst) = jsBoolean(src1.asInt32() != src2.asInt32());
        else {
            JSValue result = jsBoolean(!JSValue::equalSlowCase(callFrame, src1, src2));
            CHECK_FOR_EXCEPTION();
            callFrame->uncheckedR(dst) = result;
        }

        vPC += OPCODE_LENGTH(op_neq);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_neq_null) {
        /* neq_null dst(r) src(r)

           Checks whether register src is not null, as with the ECMAScript '!='
           operator, and puts the result as a boolean in register dst.
        */
        int dst = vPC[1].u.operand;
        JSValue src = callFrame->r(vPC[2].u.operand).jsValue();

        if (src.isUndefinedOrNull()) {
            callFrame->uncheckedR(dst) = jsBoolean(false);
            vPC += OPCODE_LENGTH(op_neq_null);
            NEXT_INSTRUCTION();
        }
        
        callFrame->uncheckedR(dst) = jsBoolean(!src.isCell() || !src.asCell()->structure()->typeInfo().masqueradesAsUndefined());
        vPC += OPCODE_LENGTH(op_neq_null);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_stricteq) {
        /* stricteq dst(r) src1(r) src2(r)

           Checks whether register src1 and register src2 are strictly
           equal, as with the ECMAScript '===' operator, and puts the
           result as a boolean in register dst.
        */
        int dst = vPC[1].u.operand;
        JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
        JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
        bool result = JSValue::strictEqual(callFrame, src1, src2);
        CHECK_FOR_EXCEPTION();
        callFrame->uncheckedR(dst) = jsBoolean(result);

        vPC += OPCODE_LENGTH(op_stricteq);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_nstricteq) {
        /* nstricteq dst(r) src1(r) src2(r)

           Checks whether register src1 and register src2 are not
           strictly equal, as with the ECMAScript '!==' operator, and
           puts the result as a boolean in register dst.
        */
        int dst = vPC[1].u.operand;
        JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
        JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
        bool result = !JSValue::strictEqual(callFrame, src1, src2);
        CHECK_FOR_EXCEPTION();
        callFrame->uncheckedR(dst) = jsBoolean(result);

        vPC += OPCODE_LENGTH(op_nstricteq);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_less) {
        /* less dst(r) src1(r) src2(r)

           Checks whether register src1 is less than register src2, as
           with the ECMAScript '<' operator, and puts the result as
           a boolean in register dst.
        */
        int dst = vPC[1].u.operand;
        JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
        JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
        JSValue result = jsBoolean(jsLess<true>(callFrame, src1, src2));
        CHECK_FOR_EXCEPTION();
        callFrame->uncheckedR(dst) = result;

        vPC += OPCODE_LENGTH(op_less);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_lesseq) {
        /* lesseq dst(r) src1(r) src2(r)

           Checks whether register src1 is less than or equal to
           register src2, as with the ECMAScript '<=' operator, and
           puts the result as a boolean in register dst.
        */
        int dst = vPC[1].u.operand;
        JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
        JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
        JSValue result = jsBoolean(jsLessEq<true>(callFrame, src1, src2));
        CHECK_FOR_EXCEPTION();
        callFrame->uncheckedR(dst) = result;

        vPC += OPCODE_LENGTH(op_lesseq);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_greater) {
        /* greater dst(r) src1(r) src2(r)

           Checks whether register src1 is greater than register src2, as
           with the ECMAScript '>' operator, and puts the result as
           a boolean in register dst.
        */
        int dst = vPC[1].u.operand;
        JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
        JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
        JSValue result = jsBoolean(jsLess<false>(callFrame, src2, src1));
        CHECK_FOR_EXCEPTION();
        callFrame->uncheckedR(dst) = result;

        vPC += OPCODE_LENGTH(op_greater);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_greatereq) {
        /* greatereq dst(r) src1(r) src2(r)

           Checks whether register src1 is greater than or equal to
           register src2, as with the ECMAScript '>=' operator, and
           puts the result as a boolean in register dst.
        */
        int dst = vPC[1].u.operand;
        JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
        JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
        JSValue result = jsBoolean(jsLessEq<false>(callFrame, src2, src1));
        CHECK_FOR_EXCEPTION();
        callFrame->uncheckedR(dst) = result;

        vPC += OPCODE_LENGTH(op_greatereq);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_pre_inc) {
        /* pre_inc srcDst(r)

           Converts register srcDst to number, adds one, and puts the result
           back in register srcDst.
        */
        int srcDst = vPC[1].u.operand;
        JSValue v = callFrame->r(srcDst).jsValue();
        if (v.isInt32() && v.asInt32() < INT_MAX)
            callFrame->uncheckedR(srcDst) = jsNumber(v.asInt32() + 1);
        else {
            JSValue result = jsNumber(v.toNumber(callFrame) + 1);
            CHECK_FOR_EXCEPTION();
            callFrame->uncheckedR(srcDst) = result;
        }

        vPC += OPCODE_LENGTH(op_pre_inc);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_pre_dec) {
        /* pre_dec srcDst(r)

           Converts register srcDst to number, subtracts one, and puts the result
           back in register srcDst.
        */
        int srcDst = vPC[1].u.operand;
        JSValue v = callFrame->r(srcDst).jsValue();
        if (v.isInt32() && v.asInt32() > INT_MIN)
            callFrame->uncheckedR(srcDst) = jsNumber(v.asInt32() - 1);
        else {
            JSValue result = jsNumber(v.toNumber(callFrame) - 1);
            CHECK_FOR_EXCEPTION();
            callFrame->uncheckedR(srcDst) = result;
        }

        vPC += OPCODE_LENGTH(op_pre_dec);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_post_inc) {
        /* post_inc dst(r) srcDst(r)

           Converts register srcDst to number. The number itself is
           written to register dst, and the number plus one is written
           back to register srcDst.
        */
        int dst = vPC[1].u.operand;
        int srcDst = vPC[2].u.operand;
        JSValue v = callFrame->r(srcDst).jsValue();
        if (v.isInt32() && v.asInt32() < INT_MAX) {
            callFrame->uncheckedR(srcDst) = jsNumber(v.asInt32() + 1);
            callFrame->uncheckedR(dst) = v;
        } else {
            double number = callFrame->r(srcDst).jsValue().toNumber(callFrame);
            CHECK_FOR_EXCEPTION();
            callFrame->uncheckedR(srcDst) = jsNumber(number + 1);
            callFrame->uncheckedR(dst) = jsNumber(number);
        }

        vPC += OPCODE_LENGTH(op_post_inc);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_post_dec) {
        /* post_dec dst(r) srcDst(r)

           Converts register srcDst to number. The number itself is
           written to register dst, and the number minus one is written
           back to register srcDst.
        */
        int dst = vPC[1].u.operand;
        int srcDst = vPC[2].u.operand;
        JSValue v = callFrame->r(srcDst).jsValue();
        if (v.isInt32() && v.asInt32() > INT_MIN) {
            callFrame->uncheckedR(srcDst) = jsNumber(v.asInt32() - 1);
            callFrame->uncheckedR(dst) = v;
        } else {
            double number = callFrame->r(srcDst).jsValue().toNumber(callFrame);
            CHECK_FOR_EXCEPTION();
            callFrame->uncheckedR(srcDst) = jsNumber(number - 1);
            callFrame->uncheckedR(dst) = jsNumber(number);
        }

        vPC += OPCODE_LENGTH(op_post_dec);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_to_jsnumber) {
        /* to_jsnumber dst(r) src(r)

           Converts register src to number, and puts the result
           in register dst.
        */
        int dst = vPC[1].u.operand;
        int src = vPC[2].u.operand;

        JSValue srcVal = callFrame->r(src).jsValue();

        if (LIKELY(srcVal.isNumber()))
            callFrame->uncheckedR(dst) = callFrame->r(src);
        else {
            double number = srcVal.toNumber(callFrame);
            CHECK_FOR_EXCEPTION();
            callFrame->uncheckedR(dst) = jsNumber(number);
        }

        vPC += OPCODE_LENGTH(op_to_jsnumber);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_negate) {
        /* negate dst(r) src(r)

           Converts register src to number, negates it, and puts the
           result in register dst.
        */
        int dst = vPC[1].u.operand;
        JSValue src = callFrame->r(vPC[2].u.operand).jsValue();
        if (src.isInt32() && (src.asInt32() & 0x7fffffff)) // non-zero and no overflow
            callFrame->uncheckedR(dst) = jsNumber(-src.asInt32());
        else {
            JSValue result = jsNumber(-src.toNumber(callFrame));
            CHECK_FOR_EXCEPTION();
            callFrame->uncheckedR(dst) = result;
        }

        vPC += OPCODE_LENGTH(op_negate);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_add) {
        /* add dst(r) src1(r) src2(r)

           Adds register src1 and register src2, and puts the result
           in register dst. (JS add may be string concatenation or
           numeric add, depending on the types of the operands.)
        */
        int dst = vPC[1].u.operand;
        JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
        JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
        if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | (src2.asInt32() & 0xc0000000))) // no overflow
            callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() + src2.asInt32());
        else {
            JSValue result = jsAdd(callFrame, src1, src2);
            CHECK_FOR_EXCEPTION();
            callFrame->uncheckedR(dst) = result;
        }
        vPC += OPCODE_LENGTH(op_add);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_mul) {
        /* mul dst(r) src1(r) src2(r)

           Multiplies register src1 and register src2 (converted to
           numbers), and puts the product in register dst.
        */
        int dst = vPC[1].u.operand;
        JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
        JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
        if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | src2.asInt32() >> 15)) // no overflow
                callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() * src2.asInt32());
        else {
            JSValue result = jsNumber(src1.toNumber(callFrame) * src2.toNumber(callFrame));
            CHECK_FOR_EXCEPTION();
            callFrame->uncheckedR(dst) = result;
        }

        vPC += OPCODE_LENGTH(op_mul);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_div) {
        /* div dst(r) dividend(r) divisor(r)

           Divides register dividend (converted to number) by the
           register divisor (converted to number), and puts the
           quotient in register dst.
        */
        int dst = vPC[1].u.operand;
        JSValue dividend = callFrame->r(vPC[2].u.operand).jsValue();
        JSValue divisor = callFrame->r(vPC[3].u.operand).jsValue();

        JSValue result = jsNumber(dividend.toNumber(callFrame) / divisor.toNumber(callFrame));
        CHECK_FOR_EXCEPTION();
        callFrame->uncheckedR(dst) = result;

        vPC += OPCODE_LENGTH(op_div);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_mod) {
        /* mod dst(r) dividend(r) divisor(r)

           Divides register dividend (converted to number) by
           register divisor (converted to number), and puts the
           remainder in register dst.
        */
        int dst = vPC[1].u.operand;
        JSValue dividend = callFrame->r(vPC[2].u.operand).jsValue();
        JSValue divisor = callFrame->r(vPC[3].u.operand).jsValue();

        if (dividend.isInt32() && divisor.isInt32() && divisor.asInt32() != 0) {
            JSValue result = jsNumber(dividend.asInt32() % divisor.asInt32());
            ASSERT(result);
            callFrame->uncheckedR(dst) = result;
            vPC += OPCODE_LENGTH(op_mod);
            NEXT_INSTRUCTION();
        }

        // Conversion to double must happen outside the call to fmod since the
        // order of argument evaluation is not guaranteed.
        double d1 = dividend.toNumber(callFrame);
        double d2 = divisor.toNumber(callFrame);
        JSValue result = jsNumber(fmod(d1, d2));
        CHECK_FOR_EXCEPTION();
        callFrame->uncheckedR(dst) = result;
        vPC += OPCODE_LENGTH(op_mod);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_sub) {
        /* sub dst(r) src1(r) src2(r)

           Subtracts register src2 (converted to number) from register
           src1 (converted to number), and puts the difference in
           register dst.
        */
        int dst = vPC[1].u.operand;
        JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
        JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
        if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | (src2.asInt32() & 0xc0000000))) // no overflow
            callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() - src2.asInt32());
        else {
            JSValue result = jsNumber(src1.toNumber(callFrame) - src2.toNumber(callFrame));
            CHECK_FOR_EXCEPTION();
            callFrame->uncheckedR(dst) = result;
        }
        vPC += OPCODE_LENGTH(op_sub);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_lshift) {
        /* lshift dst(r) val(r) shift(r)

           Performs left shift of register val (converted to int32) by
           register shift (converted to uint32), and puts the result
           in register dst.
        */
        int dst = vPC[1].u.operand;
        JSValue val = callFrame->r(vPC[2].u.operand).jsValue();
        JSValue shift = callFrame->r(vPC[3].u.operand).jsValue();

        if (val.isInt32() && shift.isInt32())
            callFrame->uncheckedR(dst) = jsNumber(val.asInt32() << (shift.asInt32() & 0x1f));
        else {
            JSValue result = jsNumber((val.toInt32(callFrame)) << (shift.toUInt32(callFrame) & 0x1f));
            CHECK_FOR_EXCEPTION();
            callFrame->uncheckedR(dst) = result;
        }

        vPC += OPCODE_LENGTH(op_lshift);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_rshift) {
        /* rshift dst(r) val(r) shift(r)

           Performs arithmetic right shift of register val (converted
           to int32) by register shift (converted to
           uint32), and puts the result in register dst.
        */
        int dst = vPC[1].u.operand;
        JSValue val = callFrame->r(vPC[2].u.operand).jsValue();
        JSValue shift = callFrame->r(vPC[3].u.operand).jsValue();

        if (val.isInt32() && shift.isInt32())
            callFrame->uncheckedR(dst) = jsNumber(val.asInt32() >> (shift.asInt32() & 0x1f));
        else {
            JSValue result = jsNumber((val.toInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
            CHECK_FOR_EXCEPTION();
            callFrame->uncheckedR(dst) = result;
        }

        vPC += OPCODE_LENGTH(op_rshift);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_urshift) {
        /* rshift dst(r) val(r) shift(r)

           Performs logical right shift of register val (converted
           to uint32) by register shift (converted to
           uint32), and puts the result in register dst.
        */
        int dst = vPC[1].u.operand;
        JSValue val = callFrame->r(vPC[2].u.operand).jsValue();
        JSValue shift = callFrame->r(vPC[3].u.operand).jsValue();
        if (val.isUInt32() && shift.isInt32())
            callFrame->uncheckedR(dst) = jsNumber(val.asInt32() >> (shift.asInt32() & 0x1f));
        else {
            JSValue result = jsNumber((val.toUInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
            CHECK_FOR_EXCEPTION();
            callFrame->uncheckedR(dst) = result;
        }

        vPC += OPCODE_LENGTH(op_urshift);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_bitand) {
        /* bitand dst(r) src1(r) src2(r)

           Computes bitwise AND of register src1 (converted to int32)
           and register src2 (converted to int32), and puts the result
           in register dst.
        */
        int dst = vPC[1].u.operand;
        JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
        JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
        if (src1.isInt32() && src2.isInt32())
            callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() & src2.asInt32());
        else {
            JSValue result = jsNumber(src1.toInt32(callFrame) & src2.toInt32(callFrame));
            CHECK_FOR_EXCEPTION();
            callFrame->uncheckedR(dst) = result;
        }

        vPC += OPCODE_LENGTH(op_bitand);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_bitxor) {
        /* bitxor dst(r) src1(r) src2(r)

           Computes bitwise XOR of register src1 (converted to int32)
           and register src2 (converted to int32), and puts the result
           in register dst.
        */
        int dst = vPC[1].u.operand;
        JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
        JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
        if (src1.isInt32() && src2.isInt32())
            callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() ^ src2.asInt32());
        else {
            JSValue result = jsNumber(src1.toInt32(callFrame) ^ src2.toInt32(callFrame));
            CHECK_FOR_EXCEPTION();
            callFrame->uncheckedR(dst) = result;
        }

        vPC += OPCODE_LENGTH(op_bitxor);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_bitor) {
        /* bitor dst(r) src1(r) src2(r)

           Computes bitwise OR of register src1 (converted to int32)
           and register src2 (converted to int32), and puts the
           result in register dst.
        */
        int dst = vPC[1].u.operand;
        JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
        JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
        if (src1.isInt32() && src2.isInt32())
            callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() | src2.asInt32());
        else {
            JSValue result = jsNumber(src1.toInt32(callFrame) | src2.toInt32(callFrame));
            CHECK_FOR_EXCEPTION();
            callFrame->uncheckedR(dst) = result;
        }

        vPC += OPCODE_LENGTH(op_bitor);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_not) {
        /* not dst(r) src(r)

           Computes logical NOT of register src (converted to
           boolean), and puts the result in register dst.
        */
        int dst = vPC[1].u.operand;
        int src = vPC[2].u.operand;
        JSValue result = jsBoolean(!callFrame->r(src).jsValue().toBoolean(callFrame));
        CHECK_FOR_EXCEPTION();
        callFrame->uncheckedR(dst) = result;

        vPC += OPCODE_LENGTH(op_not);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_check_has_instance) {
        /* check_has_instance constructor(r)

           Check 'constructor' is an object with the internal property
           [HasInstance] (i.e. is a function ... *shakes head sadly at
           JSC API*). Raises an exception if register constructor is not
           an valid parameter for instanceof.
        */
        int base = vPC[1].u.operand;
        JSValue baseVal = callFrame->r(base).jsValue();

        if (isInvalidParamForInstanceOf(callFrame, baseVal, exceptionValue))
            goto vm_throw;

        vPC += OPCODE_LENGTH(op_check_has_instance);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_instanceof) {
        /* instanceof dst(r) value(r) constructor(r) constructorProto(r)

           Tests whether register value is an instance of register
           constructor, and puts the boolean result in register
           dst. Register constructorProto must contain the "prototype"
           property (not the actual prototype) of the object in
           register constructor. This lookup is separated so that
           polymorphic inline caching can apply.

           Raises an exception if register constructor is not an
           object.
        */
        int dst = vPC[1].u.operand;
        int value = vPC[2].u.operand;
        int base = vPC[3].u.operand;
        int baseProto = vPC[4].u.operand;

        JSValue baseVal = callFrame->r(base).jsValue();

        ASSERT(!isInvalidParamForInstanceOf(callFrame, baseVal, exceptionValue));

        bool result = asObject(baseVal)->methodTable()->hasInstance(asObject(baseVal), callFrame, callFrame->r(value).jsValue(), callFrame->r(baseProto).jsValue());
        CHECK_FOR_EXCEPTION();
        callFrame->uncheckedR(dst) = jsBoolean(result);

        vPC += OPCODE_LENGTH(op_instanceof);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_typeof) {
        /* typeof dst(r) src(r)

           Determines the type string for src according to ECMAScript
           rules, and puts the result in register dst.
        */
        int dst = vPC[1].u.operand;
        int src = vPC[2].u.operand;
        callFrame->uncheckedR(dst) = JSValue(jsTypeStringForValue(callFrame, callFrame->r(src).jsValue()));

        vPC += OPCODE_LENGTH(op_typeof);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_is_undefined) {
        /* is_undefined dst(r) src(r)

           Determines whether the type string for src according to
           the ECMAScript rules is "undefined", and puts the result
           in register dst.
        */
        int dst = vPC[1].u.operand;
        int src = vPC[2].u.operand;
        JSValue v = callFrame->r(src).jsValue();
        callFrame->uncheckedR(dst) = jsBoolean(v.isCell() ? v.asCell()->structure()->typeInfo().masqueradesAsUndefined() : v.isUndefined());

        vPC += OPCODE_LENGTH(op_is_undefined);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_is_boolean) {
        /* is_boolean dst(r) src(r)

           Determines whether the type string for src according to
           the ECMAScript rules is "boolean", and puts the result
           in register dst.
        */
        int dst = vPC[1].u.operand;
        int src = vPC[2].u.operand;
        callFrame->uncheckedR(dst) = jsBoolean(callFrame->r(src).jsValue().isBoolean());

        vPC += OPCODE_LENGTH(op_is_boolean);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_is_number) {
        /* is_number dst(r) src(r)

           Determines whether the type string for src according to
           the ECMAScript rules is "number", and puts the result
           in register dst.
        */
        int dst = vPC[1].u.operand;
        int src = vPC[2].u.operand;
        callFrame->uncheckedR(dst) = jsBoolean(callFrame->r(src).jsValue().isNumber());

        vPC += OPCODE_LENGTH(op_is_number);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_is_string) {
        /* is_string dst(r) src(r)

           Determines whether the type string for src according to
           the ECMAScript rules is "string", and puts the result
           in register dst.
        */
        int dst = vPC[1].u.operand;
        int src = vPC[2].u.operand;
        callFrame->uncheckedR(dst) = jsBoolean(callFrame->r(src).jsValue().isString());

        vPC += OPCODE_LENGTH(op_is_string);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_is_object) {
        /* is_object dst(r) src(r)

           Determines whether the type string for src according to
           the ECMAScript rules is "object", and puts the result
           in register dst.
        */
        int dst = vPC[1].u.operand;
        int src = vPC[2].u.operand;
        callFrame->uncheckedR(dst) = jsBoolean(jsIsObjectType(callFrame->r(src).jsValue()));

        vPC += OPCODE_LENGTH(op_is_object);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_is_function) {
        /* is_function dst(r) src(r)

           Determines whether the type string for src according to
           the ECMAScript rules is "function", and puts the result
           in register dst.
        */
        int dst = vPC[1].u.operand;
        int src = vPC[2].u.operand;
        callFrame->uncheckedR(dst) = jsBoolean(jsIsFunctionType(callFrame->r(src).jsValue()));

        vPC += OPCODE_LENGTH(op_is_function);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_in) {
        /* in dst(r) property(r) base(r)

           Tests whether register base has a property named register
           property, and puts the boolean result in register dst.

           Raises an exception if register constructor is not an
           object.
        */
        int dst = vPC[1].u.operand;
        int property = vPC[2].u.operand;
        int base = vPC[3].u.operand;

        JSValue baseVal = callFrame->r(base).jsValue();
        if (isInvalidParamForIn(callFrame, baseVal, exceptionValue))
            goto vm_throw;

        JSObject* baseObj = asObject(baseVal);

        JSValue propName = callFrame->r(property).jsValue();

        uint32_t i;
        if (propName.getUInt32(i))
            callFrame->uncheckedR(dst) = jsBoolean(baseObj->hasProperty(callFrame, i));
        else {
            Identifier property(callFrame, propName.toString(callFrame)->value(callFrame));
            CHECK_FOR_EXCEPTION();
            callFrame->uncheckedR(dst) = jsBoolean(baseObj->hasProperty(callFrame, property));
        }

        vPC += OPCODE_LENGTH(op_in);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_resolve) {
        /* resolve dst(r) property(id)

           Looks up the property named by identifier property in the
           scope chain, and writes the resulting value to register
           dst. If the property is not found, raises an exception.
        */
        if (UNLIKELY(!resolve(callFrame, vPC, exceptionValue)))
            goto vm_throw;

        vPC += OPCODE_LENGTH(op_resolve);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_resolve_skip) {
        /* resolve_skip dst(r) property(id) skip(n)

         Looks up the property named by identifier property in the
         scope chain skipping the top 'skip' levels, and writes the resulting
         value to register dst. If the property is not found, raises an exception.
         */
        if (UNLIKELY(!resolveSkip(callFrame, vPC, exceptionValue)))
            goto vm_throw;

        vPC += OPCODE_LENGTH(op_resolve_skip);

        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_resolve_global) {
        /* resolve_skip dst(r) globalObject(c) property(id) structure(sID) offset(n)
         
           Performs a dynamic property lookup for the given property, on the provided
           global object.  If structure matches the Structure of the global then perform
           a fast lookup using the case offset, otherwise fall back to a full resolve and
           cache the new structure and offset
         */
        if (UNLIKELY(!resolveGlobal(callFrame, vPC, exceptionValue)))
            goto vm_throw;
        
        vPC += OPCODE_LENGTH(op_resolve_global);
        
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_resolve_global_dynamic) {
        /* resolve_skip dst(r) globalObject(c) property(id) structure(sID) offset(n), depth(n)
         
         Performs a dynamic property lookup for the given property, on the provided
         global object.  If structure matches the Structure of the global then perform
         a fast lookup using the case offset, otherwise fall back to a full resolve and
         cache the new structure and offset.
         
         This walks through n levels of the scope chain to verify that none of those levels
         in the scope chain include dynamically added properties.
         */
        if (UNLIKELY(!resolveGlobalDynamic(callFrame, vPC, exceptionValue)))
            goto vm_throw;
        
        vPC += OPCODE_LENGTH(op_resolve_global_dynamic);
        
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_get_global_var) {
        /* get_global_var dst(r) globalObject(c) index(n)

           Gets the global var at global slot index and places it in register dst.
         */
        int dst = vPC[1].u.operand;
        JSGlobalObject* scope = codeBlock->globalObject();
        ASSERT(scope->isGlobalObject());
        int index = vPC[2].u.operand;

        callFrame->uncheckedR(dst) = scope->registerAt(index).get();
        vPC += OPCODE_LENGTH(op_get_global_var);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_put_global_var) {
        /* put_global_var globalObject(c) index(n) value(r)
         
           Puts value into global slot index.
         */
        JSGlobalObject* scope = codeBlock->globalObject();
        ASSERT(scope->isGlobalObject());
        int index = vPC[1].u.operand;
        int value = vPC[2].u.operand;
        
        scope->registerAt(index).set(*globalData, scope, callFrame->r(value).jsValue());
        vPC += OPCODE_LENGTH(op_put_global_var);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_get_scoped_var) {
        /* get_scoped_var dst(r) index(n) skip(n)

         Loads the contents of the index-th local from the scope skip nodes from
         the top of the scope chain, and places it in register dst.
         */
        int dst = vPC[1].u.operand;
        int index = vPC[2].u.operand;
        int skip = vPC[3].u.operand;

        ScopeChainNode* scopeChain = callFrame->scopeChain();
        ScopeChainIterator iter = scopeChain->begin();
        ScopeChainIterator end = scopeChain->end();
        ASSERT_UNUSED(end, iter != end);
        ASSERT(codeBlock == callFrame->codeBlock());
        bool checkTopLevel = codeBlock->codeType() == FunctionCode && codeBlock->needsFullScopeChain();
        ASSERT(skip || !checkTopLevel);
        if (checkTopLevel && skip--) {
            if (callFrame->r(codeBlock->activationRegister()).jsValue())
                ++iter;
        }
        while (skip--) {
            ++iter;
            ASSERT_UNUSED(end, iter != end);
        }
        ASSERT((*iter)->isVariableObject());
        JSVariableObject* scope = static_cast<JSVariableObject*>(iter->get());
        callFrame->uncheckedR(dst) = scope->registerAt(index).get();
        ASSERT(callFrame->r(dst).jsValue());
        vPC += OPCODE_LENGTH(op_get_scoped_var);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_put_scoped_var) {
        /* put_scoped_var index(n) skip(n) value(r)

         */
        int index = vPC[1].u.operand;
        int skip = vPC[2].u.operand;
        int value = vPC[3].u.operand;

        ScopeChainNode* scopeChain = callFrame->scopeChain();
        ScopeChainIterator iter = scopeChain->begin();
        ScopeChainIterator end = scopeChain->end();
        ASSERT(codeBlock == callFrame->codeBlock());
        ASSERT_UNUSED(end, iter != end);
        bool checkTopLevel = codeBlock->codeType() == FunctionCode && codeBlock->needsFullScopeChain();
        ASSERT(skip || !checkTopLevel);
        if (checkTopLevel && skip--) {
            if (callFrame->r(codeBlock->activationRegister()).jsValue())
                ++iter;
        }
        while (skip--) {
            ++iter;
            ASSERT_UNUSED(end, iter != end);
        }

        ASSERT((*iter)->isVariableObject());
        JSVariableObject* scope = static_cast<JSVariableObject*>(iter->get());
        ASSERT(callFrame->r(value).jsValue());
        scope->registerAt(index).set(*globalData, scope, callFrame->r(value).jsValue());
        vPC += OPCODE_LENGTH(op_put_scoped_var);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_resolve_base) {
        /* resolve_base dst(r) property(id) isStrict(bool)

           Searches the scope chain for an object containing
           identifier property, and if one is found, writes it to
           register dst. If none is found and isStrict is false, the
           outermost scope (which will be the global object) is
           stored in register dst.
        */
        resolveBase(callFrame, vPC);
        CHECK_FOR_EXCEPTION();

        vPC += OPCODE_LENGTH(op_resolve_base);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_ensure_property_exists) {
        /* ensure_property_exists base(r) property(id)

           Throws an exception if property does not exist on base
         */
        int base = vPC[1].u.operand;
        int property = vPC[2].u.operand;
        Identifier& ident = codeBlock->identifier(property);
        
        JSValue baseVal = callFrame->r(base).jsValue();
        JSObject* baseObject = asObject(baseVal);
        PropertySlot slot(baseVal);
        if (!baseObject->getPropertySlot(callFrame, ident, slot)) {
            exceptionValue = createErrorForInvalidGlobalAssignment(callFrame, ident.ustring());
            goto vm_throw;
        }

        vPC += OPCODE_LENGTH(op_ensure_property_exists);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_resolve_with_base) {
        /* resolve_with_base baseDst(r) propDst(r) property(id)

           Searches the scope chain for an object containing
           identifier property, and if one is found, writes it to
           register srcDst, and the retrieved property value to register
           propDst. If the property is not found, raises an exception.

           This is more efficient than doing resolve_base followed by
           resolve, or resolve_base followed by get_by_id, as it
           avoids duplicate hash lookups.
        */
        if (UNLIKELY(!resolveBaseAndProperty(callFrame, vPC, exceptionValue)))
            goto vm_throw;

        vPC += OPCODE_LENGTH(op_resolve_with_base);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_resolve_with_this) {
        /* resolve_with_this thisDst(r) propDst(r) property(id)

           Searches the scope chain for an object containing
           identifier property, and if one is found, writes the
           retrieved property value to register propDst, and the
           this object to pass in a call to thisDst.

           If the property is not found, raises an exception.
        */
        if (UNLIKELY(!resolveThisAndProperty(callFrame, vPC, exceptionValue)))
            goto vm_throw;

        vPC += OPCODE_LENGTH(op_resolve_with_this);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_get_by_id) {
        /* get_by_id dst(r) base(r) property(id) structure(sID) nop(n) nop(n) nop(n)

           Generic property access: Gets the property named by identifier
           property from the value base, and puts the result in register dst.
        */
        int dst = vPC[1].u.operand;
        int base = vPC[2].u.operand;
        int property = vPC[3].u.operand;

        Identifier& ident = codeBlock->identifier(property);
        JSValue baseValue = callFrame->r(base).jsValue();
        PropertySlot slot(baseValue);
        JSValue result = baseValue.get(callFrame, ident, slot);
        CHECK_FOR_EXCEPTION();

        tryCacheGetByID(callFrame, codeBlock, vPC, baseValue, ident, slot);

        callFrame->uncheckedR(dst) = result;
        vPC += OPCODE_LENGTH(op_get_by_id);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_get_by_id_self) {
        /* op_get_by_id_self dst(r) base(r) property(id) structure(sID) offset(n) nop(n) nop(n)

           Cached property access: Attempts to get a cached property from the
           value base. If the cache misses, op_get_by_id_self reverts to
           op_get_by_id.
        */
        int base = vPC[2].u.operand;
        JSValue baseValue = callFrame->r(base).jsValue();

        if (LIKELY(baseValue.isCell())) {
            JSCell* baseCell = baseValue.asCell();
            Structure* structure = vPC[4].u.structure.get();

            if (LIKELY(baseCell->structure() == structure)) {
                ASSERT(baseCell->isObject());
                JSObject* baseObject = asObject(baseCell);
                int dst = vPC[1].u.operand;
                int offset = vPC[5].u.operand;

                ASSERT(baseObject->get(callFrame, codeBlock->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset));
                callFrame->uncheckedR(dst) = JSValue(baseObject->getDirectOffset(offset));

                vPC += OPCODE_LENGTH(op_get_by_id_self);
                NEXT_INSTRUCTION();
            }
        }

        uncacheGetByID(codeBlock, vPC);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_get_by_id_proto) {
        /* op_get_by_id_proto dst(r) base(r) property(id) structure(sID) prototypeStructure(sID) offset(n) nop(n)

           Cached property access: Attempts to get a cached property from the
           value base's prototype. If the cache misses, op_get_by_id_proto
           reverts to op_get_by_id.
        */
        int base = vPC[2].u.operand;
        JSValue baseValue = callFrame->r(base).jsValue();

        if (LIKELY(baseValue.isCell())) {
            JSCell* baseCell = baseValue.asCell();
            Structure* structure = vPC[4].u.structure.get();

            if (LIKELY(baseCell->structure() == structure)) {
                ASSERT(structure->prototypeForLookup(callFrame).isObject());
                JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame));
                Structure* prototypeStructure = vPC[5].u.structure.get();

                if (LIKELY(protoObject->structure() == prototypeStructure)) {
                    int dst = vPC[1].u.operand;
                    int offset = vPC[6].u.operand;

                    ASSERT(protoObject->get(callFrame, codeBlock->identifier(vPC[3].u.operand)) == protoObject->getDirectOffset(offset));
                    ASSERT(baseValue.get(callFrame, codeBlock->identifier(vPC[3].u.operand)) == protoObject->getDirectOffset(offset));
                    callFrame->uncheckedR(dst) = JSValue(protoObject->getDirectOffset(offset));

                    vPC += OPCODE_LENGTH(op_get_by_id_proto);
                    NEXT_INSTRUCTION();
                }
            }
        }

        uncacheGetByID(codeBlock, vPC);
        NEXT_INSTRUCTION();
    }
#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
    goto *(&&skip_id_getter_proto);
#endif
    DEFINE_OPCODE(op_get_by_id_getter_proto) {
        /* op_get_by_id_getter_proto dst(r) base(r) property(id) structure(sID) prototypeStructure(sID) offset(n) nop(n)
         
         Cached property access: Attempts to get a cached getter property from the
         value base's prototype. If the cache misses, op_get_by_id_getter_proto
         reverts to op_get_by_id.
         */
        int base = vPC[2].u.operand;
        JSValue baseValue = callFrame->r(base).jsValue();
        
        if (LIKELY(baseValue.isCell())) {
            JSCell* baseCell = baseValue.asCell();
            Structure* structure = vPC[4].u.structure.get();
            
            if (LIKELY(baseCell->structure() == structure)) {
                ASSERT(structure->prototypeForLookup(callFrame).isObject());
                JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame));
                Structure* prototypeStructure = vPC[5].u.structure.get();
                
                if (LIKELY(protoObject->structure() == prototypeStructure)) {
                    int dst = vPC[1].u.operand;
                    int offset = vPC[6].u.operand;
                    if (GetterSetter* getterSetter = asGetterSetter(protoObject->getDirectOffset(offset).asCell())) {
                        JSObject* getter = getterSetter->getter();
                        CallData callData;
                        CallType callType = getter->methodTable()->getCallData(getter, callData);
                        JSValue result = call(callFrame, getter, callType, callData, asObject(baseCell), ArgList());
                        CHECK_FOR_EXCEPTION();
                        callFrame->uncheckedR(dst) = result;
                    } else
                        callFrame->uncheckedR(dst) = jsUndefined();
                    vPC += OPCODE_LENGTH(op_get_by_id_getter_proto);
                    NEXT_INSTRUCTION();
                }
            }
        }
        uncacheGetByID(codeBlock, vPC);
        NEXT_INSTRUCTION();
    }
#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
    skip_id_getter_proto:
#endif
#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
    goto *(&&skip_id_custom_proto);
#endif
    DEFINE_OPCODE(op_get_by_id_custom_proto) {
        /* op_get_by_id_custom_proto dst(r) base(r) property(id) structure(sID) prototypeStructure(sID) offset(n) nop(n)
         
         Cached property access: Attempts to use a cached named property getter
         from the value base's prototype. If the cache misses, op_get_by_id_custom_proto
         reverts to op_get_by_id.
         */
        int base = vPC[2].u.operand;
        JSValue baseValue = callFrame->r(base).jsValue();
        
        if (LIKELY(baseValue.isCell())) {
            JSCell* baseCell = baseValue.asCell();
            Structure* structure = vPC[4].u.structure.get();
            
            if (LIKELY(baseCell->structure() == structure)) {
                ASSERT(structure->prototypeForLookup(callFrame).isObject());
                JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame));
                Structure* prototypeStructure = vPC[5].u.structure.get();
                
                if (LIKELY(protoObject->structure() == prototypeStructure)) {
                    int dst = vPC[1].u.operand;
                    int property = vPC[3].u.operand;
                    Identifier& ident = codeBlock->identifier(property);
                    
                    PropertySlot::GetValueFunc getter = vPC[6].u.getterFunc;
                    JSValue result = getter(callFrame, protoObject, ident);
                    CHECK_FOR_EXCEPTION();
                    callFrame->uncheckedR(dst) = result;
                    vPC += OPCODE_LENGTH(op_get_by_id_custom_proto);
                    NEXT_INSTRUCTION();
                }
            }
        }
        uncacheGetByID(codeBlock, vPC);
        NEXT_INSTRUCTION();
    }
#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
    skip_id_custom_proto:
#endif
#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
    goto *(&&skip_get_by_id_chain);
#endif
    DEFINE_OPCODE(op_get_by_id_chain) {
        /* op_get_by_id_chain dst(r) base(r) property(id) structure(sID) structureChain(chain) count(n) offset(n)

           Cached property access: Attempts to get a cached property from the
           value base's prototype chain. If the cache misses, op_get_by_id_chain
           reverts to op_get_by_id.
        */
        int base = vPC[2].u.operand;
        JSValue baseValue = callFrame->r(base).jsValue();

        if (LIKELY(baseValue.isCell())) {
            JSCell* baseCell = baseValue.asCell();
            Structure* structure = vPC[4].u.structure.get();

            if (LIKELY(baseCell->structure() == structure)) {
                WriteBarrier<Structure>* it = vPC[5].u.structureChain->head();
                size_t count = vPC[6].u.operand;
                WriteBarrier<Structure>* end = it + count;

                while (true) {
                    JSObject* baseObject = asObject(baseCell->structure()->prototypeForLookup(callFrame));

                    if (UNLIKELY(baseObject->structure() != (*it).get()))
                        break;

                    if (++it == end) {
                        int dst = vPC[1].u.operand;
                        int offset = vPC[7].u.operand;

                        ASSERT(baseObject->get(callFrame, codeBlock->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset));
                        ASSERT(baseValue.get(callFrame, codeBlock->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset));
                        callFrame->uncheckedR(dst) = JSValue(baseObject->getDirectOffset(offset));

                        vPC += OPCODE_LENGTH(op_get_by_id_chain);
                        NEXT_INSTRUCTION();
                    }

                    // Update baseCell, so that next time around the loop we'll pick up the prototype's prototype.
                    baseCell = baseObject;
                }
            }
        }

        uncacheGetByID(codeBlock, vPC);
        NEXT_INSTRUCTION();
    }
#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
    skip_get_by_id_chain:
    goto *(&&skip_id_getter_self);
#endif
    DEFINE_OPCODE(op_get_by_id_getter_self) {
        /* op_get_by_id_self dst(r) base(r) property(id) structure(sID) offset(n) nop(n) nop(n)
         
         Cached property access: Attempts to get a cached property from the
         value base. If the cache misses, op_get_by_id_getter_self reverts to
         op_get_by_id.
         */
        int base = vPC[2].u.operand;
        JSValue baseValue = callFrame->r(base).jsValue();
        
        if (LIKELY(baseValue.isCell())) {
            JSCell* baseCell = baseValue.asCell();
            Structure* structure = vPC[4].u.structure.get();
            
            if (LIKELY(baseCell->structure() == structure)) {
                ASSERT(baseCell->isObject());
                JSObject* baseObject = asObject(baseCell);
                int dst = vPC[1].u.operand;
                int offset = vPC[5].u.operand;

                if (GetterSetter* getterSetter = asGetterSetter(baseObject->getDirectOffset(offset).asCell())) {
                    JSObject* getter = getterSetter->getter();
                    CallData callData;
                    CallType callType = getter->methodTable()->getCallData(getter, callData);
                    JSValue result = call(callFrame, getter, callType, callData, baseObject, ArgList());
                    CHECK_FOR_EXCEPTION();
                    callFrame->uncheckedR(dst) = result;
                } else
                    callFrame->uncheckedR(dst) = jsUndefined();

                vPC += OPCODE_LENGTH(op_get_by_id_getter_self);
                NEXT_INSTRUCTION();
            }
        }
        uncacheGetByID(codeBlock, vPC);
        NEXT_INSTRUCTION();
    }
#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
    skip_id_getter_self:
#endif
#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
    goto *(&&skip_id_custom_self);
#endif
    DEFINE_OPCODE(op_get_by_id_custom_self) {
        /* op_get_by_id_custom_self dst(r) base(r) property(id) structure(sID) offset(n) nop(n) nop(n)
         
         Cached property access: Attempts to use a cached named property getter
         from the value base. If the cache misses, op_get_by_id_custom_self reverts to
         op_get_by_id.
         */
        int base = vPC[2].u.operand;
        JSValue baseValue = callFrame->r(base).jsValue();
        
        if (LIKELY(baseValue.isCell())) {
            JSCell* baseCell = baseValue.asCell();
            Structure* structure = vPC[4].u.structure.get();
            
            if (LIKELY(baseCell->structure() == structure)) {
                ASSERT(baseCell->isObject());
                int dst = vPC[1].u.operand;
                int property = vPC[3].u.operand;
                Identifier& ident = codeBlock->identifier(property);

                PropertySlot::GetValueFunc getter = vPC[5].u.getterFunc;
                JSValue result = getter(callFrame, baseValue, ident);
                CHECK_FOR_EXCEPTION();
                callFrame->uncheckedR(dst) = result;
                vPC += OPCODE_LENGTH(op_get_by_id_custom_self);
                NEXT_INSTRUCTION();
            }
        }
        uncacheGetByID(codeBlock, vPC);
        NEXT_INSTRUCTION();
    }
#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
skip_id_custom_self:
#endif
    DEFINE_OPCODE(op_get_by_id_generic) {
        /* op_get_by_id_generic dst(r) base(r) property(id) nop(sID) nop(n) nop(n) nop(n)

           Generic property access: Gets the property named by identifier
           property from the value base, and puts the result in register dst.
        */
        int dst = vPC[1].u.operand;
        int base = vPC[2].u.operand;
        int property = vPC[3].u.operand;

        Identifier& ident = codeBlock->identifier(property);
        JSValue baseValue = callFrame->r(base).jsValue();
        PropertySlot slot(baseValue);
        JSValue result = baseValue.get(callFrame, ident, slot);
        CHECK_FOR_EXCEPTION();

        callFrame->uncheckedR(dst) = result;
        vPC += OPCODE_LENGTH(op_get_by_id_generic);
        NEXT_INSTRUCTION();
    }
#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
    goto *(&&skip_id_getter_chain);
#endif
    DEFINE_OPCODE(op_get_by_id_getter_chain) {
        /* op_get_by_id_getter_chain dst(r) base(r) property(id) structure(sID) structureChain(chain) count(n) offset(n)
         
         Cached property access: Attempts to get a cached property from the
         value base's prototype chain. If the cache misses, op_get_by_id_getter_chain
         reverts to op_get_by_id.
         */
        int base = vPC[2].u.operand;
        JSValue baseValue = callFrame->r(base).jsValue();
        
        if (LIKELY(baseValue.isCell())) {
            JSCell* baseCell = baseValue.asCell();
            Structure* structure = vPC[4].u.structure.get();
            
            if (LIKELY(baseCell->structure() == structure)) {
                WriteBarrier<Structure>* it = vPC[5].u.structureChain->head();
                size_t count = vPC[6].u.operand;
                WriteBarrier<Structure>* end = it + count;
                
                while (true) {
                    JSObject* baseObject = asObject(baseCell->structure()->prototypeForLookup(callFrame));
                    
                    if (UNLIKELY(baseObject->structure() != (*it).get()))
                        break;
                    
                    if (++it == end) {
                        int dst = vPC[1].u.operand;
                        int offset = vPC[7].u.operand;
                        if (GetterSetter* getterSetter = asGetterSetter(baseObject->getDirectOffset(offset).asCell())) {
                            JSObject* getter = getterSetter->getter();
                            CallData callData;
                            CallType callType = getter->methodTable()->getCallData(getter, callData);
                            JSValue result = call(callFrame, getter, callType, callData, baseValue, ArgList());
                            CHECK_FOR_EXCEPTION();
                            callFrame->uncheckedR(dst) = result;
                        } else
                            callFrame->uncheckedR(dst) = jsUndefined();
                        vPC += OPCODE_LENGTH(op_get_by_id_getter_chain);
                        NEXT_INSTRUCTION();
                    }
                    
                    // Update baseCell, so that next time around the loop we'll pick up the prototype's prototype.
                    baseCell = baseObject;
                }
            }
        }
        uncacheGetByID(codeBlock, vPC);
        NEXT_INSTRUCTION();
    }
#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
    skip_id_getter_chain:
#endif
#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
    goto *(&&skip_id_custom_chain);
#endif
    DEFINE_OPCODE(op_get_by_id_custom_chain) {
        /* op_get_by_id_custom_chain dst(r) base(r) property(id) structure(sID) structureChain(chain) count(n) offset(n)
         
         Cached property access: Attempts to use a cached named property getter on the
         value base's prototype chain. If the cache misses, op_get_by_id_custom_chain
         reverts to op_get_by_id.
         */
        int base = vPC[2].u.operand;
        JSValue baseValue = callFrame->r(base).jsValue();
        
        if (LIKELY(baseValue.isCell())) {
            JSCell* baseCell = baseValue.asCell();
            Structure* structure = vPC[4].u.structure.get();
            
            if (LIKELY(baseCell->structure() == structure)) {
                WriteBarrier<Structure>* it = vPC[5].u.structureChain->head();
                size_t count = vPC[6].u.operand;
                WriteBarrier<Structure>* end = it + count;
                
                while (true) {
                    JSObject* baseObject = asObject(baseCell->structure()->prototypeForLookup(callFrame));
                    
                    if (UNLIKELY(baseObject->structure() != (*it).get()))
                        break;
                    
                    if (++it == end) {
                        int dst = vPC[1].u.operand;
                        int property = vPC[3].u.operand;
                        Identifier& ident = codeBlock->identifier(property);
                        
                        PropertySlot::GetValueFunc getter = vPC[7].u.getterFunc;
                        JSValue result = getter(callFrame, baseObject, ident);
                        CHECK_FOR_EXCEPTION();
                        callFrame->uncheckedR(dst) = result;
                        vPC += OPCODE_LENGTH(op_get_by_id_custom_chain);
                        NEXT_INSTRUCTION();
                    }
                    
                    // Update baseCell, so that next time around the loop we'll pick up the prototype's prototype.
                    baseCell = baseObject;
                }
            }
        }
        uncacheGetByID(codeBlock, vPC);
        NEXT_INSTRUCTION();
    }
#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
    skip_id_custom_chain:
    goto *(&&skip_get_array_length);
#endif
    DEFINE_OPCODE(op_get_array_length) {
        /* op_get_array_length dst(r) base(r) property(id) nop(sID) nop(n) nop(n) nop(n)

           Cached property access: Gets the length of the array in register base,
           and puts the result in register dst. If register base does not hold
           an array, op_get_array_length reverts to op_get_by_id.
        */

        int base = vPC[2].u.operand;
        JSValue baseValue = callFrame->r(base).jsValue();
        if (LIKELY(isJSArray(baseValue))) {
            int dst = vPC[1].u.operand;
            callFrame->uncheckedR(dst) = jsNumber(asArray(baseValue)->length());
            vPC += OPCODE_LENGTH(op_get_array_length);
            NEXT_INSTRUCTION();
        }

        uncacheGetByID(codeBlock, vPC);
        NEXT_INSTRUCTION();
    }
#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
    skip_get_array_length:
    goto *(&&skip_get_string_length);
#endif
    DEFINE_OPCODE(op_get_string_length) {
        /* op_get_string_length dst(r) base(r) property(id) nop(sID) nop(n) nop(n) nop(n)

           Cached property access: Gets the length of the string in register base,
           and puts the result in register dst. If register base does not hold
           a string, op_get_string_length reverts to op_get_by_id.
        */

        int base = vPC[2].u.operand;
        JSValue baseValue = callFrame->r(base).jsValue();
        if (LIKELY(isJSString(baseValue))) {
            int dst = vPC[1].u.operand;
            callFrame->uncheckedR(dst) = jsNumber(asString(baseValue)->length());
            vPC += OPCODE_LENGTH(op_get_string_length);
            NEXT_INSTRUCTION();
        }

        uncacheGetByID(codeBlock, vPC);
        NEXT_INSTRUCTION();
    }
#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
    skip_get_string_length:
    goto *(&&skip_put_by_id);
#endif
    DEFINE_OPCODE(op_put_by_id) {
        /* put_by_id base(r) property(id) value(r) nop(n) nop(n) nop(n) nop(n) direct(b)

           Generic property access: Sets the property named by identifier
           property, belonging to register base, to register value.

           Unlike many opcodes, this one does not write any output to
           the register file.

           The "direct" flag should only be set this put_by_id is to initialize
           an object literal.
        */

        int base = vPC[1].u.operand;
        int property = vPC[2].u.operand;
        int value = vPC[3].u.operand;
        int direct = vPC[8].u.operand;

        JSValue baseValue = callFrame->r(base).jsValue();
        Identifier& ident = codeBlock->identifier(property);
        PutPropertySlot slot(codeBlock->isStrictMode());
        if (direct) {
            ASSERT(baseValue.isObject());
            asObject(baseValue)->putDirect(*globalData, ident, callFrame->r(value).jsValue(), slot);
        } else
            baseValue.put(callFrame, ident, callFrame->r(value).jsValue(), slot);
        CHECK_FOR_EXCEPTION();

        tryCachePutByID(callFrame, codeBlock, vPC, baseValue, slot);

        vPC += OPCODE_LENGTH(op_put_by_id);
        NEXT_INSTRUCTION();
    }
#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
      skip_put_by_id:
#endif
    DEFINE_OPCODE(op_put_by_id_transition_direct)
    DEFINE_OPCODE(op_put_by_id_transition_normal)
    DEFINE_OPCODE(op_put_by_id_transition) {
        /* op_put_by_id_transition base(r) property(id) value(r) oldStructure(sID) newStructure(sID) structureChain(chain) offset(n) direct(b)
         
           Cached property access: Attempts to set a new property with a cached transition
           property named by identifier property, belonging to register base,
           to register value. If the cache misses, op_put_by_id_transition
           reverts to op_put_by_id_generic.
         
           Unlike many opcodes, this one does not write any output to
           the register file.
         */
        int base = vPC[1].u.operand;
        JSValue baseValue = callFrame->r(base).jsValue();
        
        if (LIKELY(baseValue.isCell())) {
            JSCell* baseCell = baseValue.asCell();
            Structure* oldStructure = vPC[4].u.structure.get();
            Structure* newStructure = vPC[5].u.structure.get();
            
            if (LIKELY(baseCell->structure() == oldStructure)) {
                ASSERT(baseCell->isObject());
                JSObject* baseObject = asObject(baseCell);
                int direct = vPC[8].u.operand;
                
                if (!direct) {
                    WriteBarrier<Structure>* it = vPC[6].u.structureChain->head();

                    JSValue proto = baseObject->structure()->prototypeForLookup(callFrame);
                    while (!proto.isNull()) {
                        if (UNLIKELY(asObject(proto)->structure() != (*it).get())) {
                            uncachePutByID(codeBlock, vPC);
                            NEXT_INSTRUCTION();
                        }
                        ++it;
                        proto = asObject(proto)->structure()->prototypeForLookup(callFrame);
                    }
                }
                baseObject->transitionTo(*globalData, newStructure);

                int value = vPC[3].u.operand;
                unsigned offset = vPC[7].u.operand;
                ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(*globalData, codeBlock->identifier(vPC[2].u.operand))) == offset);
                baseObject->putDirectOffset(callFrame->globalData(), offset, callFrame->r(value).jsValue());

                vPC += OPCODE_LENGTH(op_put_by_id_transition);
                NEXT_INSTRUCTION();
            }
        }
        
        uncachePutByID(codeBlock, vPC);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_put_by_id_replace) {
        /* op_put_by_id_replace base(r) property(id) value(r) structure(sID) offset(n) nop(n) nop(n) direct(b)

           Cached property access: Attempts to set a pre-existing, cached
           property named by identifier property, belonging to register base,
           to register value. If the cache misses, op_put_by_id_replace
           reverts to op_put_by_id.

           Unlike many opcodes, this one does not write any output to
           the register file.
        */
        int base = vPC[1].u.operand;
        JSValue baseValue = callFrame->r(base).jsValue();

        if (LIKELY(baseValue.isCell())) {
            JSCell* baseCell = baseValue.asCell();
            Structure* structure = vPC[4].u.structure.get();

            if (LIKELY(baseCell->structure() == structure)) {
                ASSERT(baseCell->isObject());
                JSObject* baseObject = asObject(baseCell);
                int value = vPC[3].u.operand;
                unsigned offset = vPC[5].u.operand;
                
                ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(*globalData, codeBlock->identifier(vPC[2].u.operand))) == offset);
                baseObject->putDirectOffset(callFrame->globalData(), offset, callFrame->r(value).jsValue());

                vPC += OPCODE_LENGTH(op_put_by_id_replace);
                NEXT_INSTRUCTION();
            }
        }

        uncachePutByID(codeBlock, vPC);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_put_by_id_generic) {
        /* op_put_by_id_generic base(r) property(id) value(r) nop(n) nop(n) nop(n) nop(n) direct(b)

           Generic property access: Sets the property named by identifier
           property, belonging to register base, to register value.

           Unlike many opcodes, this one does not write any output to
           the register file.
        */
        int base = vPC[1].u.operand;
        int property = vPC[2].u.operand;
        int value = vPC[3].u.operand;
        int direct = vPC[8].u.operand;

        JSValue baseValue = callFrame->r(base).jsValue();
        Identifier& ident = codeBlock->identifier(property);
        PutPropertySlot slot(codeBlock->isStrictMode());
        if (direct) {
            ASSERT(baseValue.isObject());
            asObject(baseValue)->putDirect(*globalData, ident, callFrame->r(value).jsValue(), slot);
        } else
            baseValue.put(callFrame, ident, callFrame->r(value).jsValue(), slot);
        CHECK_FOR_EXCEPTION();

        vPC += OPCODE_LENGTH(op_put_by_id_generic);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_del_by_id) {
        /* del_by_id dst(r) base(r) property(id)

           Converts register base to Object, deletes the property
           named by identifier property from the object, and writes a
           boolean indicating success (if true) or failure (if false)
           to register dst.
        */
        int dst = vPC[1].u.operand;
        int base = vPC[2].u.operand;
        int property = vPC[3].u.operand;

        JSObject* baseObj = callFrame->r(base).jsValue().toObject(callFrame);
        Identifier& ident = codeBlock->identifier(property);
        bool result = baseObj->methodTable()->deleteProperty(baseObj, callFrame, ident);
        if (!result && codeBlock->isStrictMode()) {
            exceptionValue = createTypeError(callFrame, "Unable to delete property.");
            goto vm_throw;
        }
        CHECK_FOR_EXCEPTION();
        callFrame->uncheckedR(dst) = jsBoolean(result);
        vPC += OPCODE_LENGTH(op_del_by_id);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_get_by_pname) {
        int dst = vPC[1].u.operand;
        int base = vPC[2].u.operand;
        int property = vPC[3].u.operand;
        int expected = vPC[4].u.operand;
        int iter = vPC[5].u.operand;
        int i = vPC[6].u.operand;

        JSValue baseValue = callFrame->r(base).jsValue();
        JSPropertyNameIterator* it = callFrame->r(iter).propertyNameIterator();
        JSValue subscript = callFrame->r(property).jsValue();
        JSValue expectedSubscript = callFrame->r(expected).jsValue();
        int index = callFrame->r(i).i() - 1;
        JSValue result;
        int offset = 0;
        if (subscript == expectedSubscript && baseValue.isCell() && (baseValue.asCell()->structure() == it->cachedStructure()) && it->getOffset(index, offset)) {
            callFrame->uncheckedR(dst) = JSValue(asObject(baseValue)->getDirectOffset(offset));
            vPC += OPCODE_LENGTH(op_get_by_pname);
            NEXT_INSTRUCTION();
        }
        {
            Identifier propertyName(callFrame, subscript.toString(callFrame)->value(callFrame));
            result = baseValue.get(callFrame, propertyName);
        }
        CHECK_FOR_EXCEPTION();
        callFrame->uncheckedR(dst) = result;
        vPC += OPCODE_LENGTH(op_get_by_pname);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_get_arguments_length) {
        int dst = vPC[1].u.operand;
        int argumentsRegister = vPC[2].u.operand;
        int property = vPC[3].u.operand;
        JSValue arguments = callFrame->r(argumentsRegister).jsValue();
        if (arguments) {
            Identifier& ident = codeBlock->identifier(property);
            PropertySlot slot(arguments);
            JSValue result = arguments.get(callFrame, ident, slot);
            CHECK_FOR_EXCEPTION();
            callFrame->uncheckedR(dst) = result;
        } else
            callFrame->uncheckedR(dst) = jsNumber(callFrame->argumentCount());

        vPC += OPCODE_LENGTH(op_get_arguments_length);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_get_argument_by_val) {
        int dst = vPC[1].u.operand;
        int argumentsRegister = vPC[2].u.operand;
        int property = vPC[3].u.operand;
        JSValue arguments = callFrame->r(argumentsRegister).jsValue();
        JSValue subscript = callFrame->r(property).jsValue();
        if (!arguments && subscript.isUInt32() && subscript.asUInt32() < callFrame->argumentCount()) {
            callFrame->uncheckedR(dst) = callFrame->argument(subscript.asUInt32());
            vPC += OPCODE_LENGTH(op_get_argument_by_val);
            NEXT_INSTRUCTION();
        }
        if (!arguments) {
            Arguments* arguments = Arguments::create(*globalData, callFrame);
            callFrame->uncheckedR(argumentsRegister) = JSValue(arguments);
            callFrame->uncheckedR(unmodifiedArgumentsRegister(argumentsRegister)) = JSValue(arguments);
        }
        // fallthrough
    }
    DEFINE_OPCODE(op_get_by_val) {
        /* get_by_val dst(r) base(r) property(r)

           Converts register base to Object, gets the property named
           by register property from the object, and puts the result
           in register dst. property is nominally converted to string
           but numbers are treated more efficiently.
        */
        int dst = vPC[1].u.operand;
        int base = vPC[2].u.operand;
        int property = vPC[3].u.operand;
        
        JSValue baseValue = callFrame->r(base).jsValue();
        JSValue subscript = callFrame->r(property).jsValue();

        JSValue result;

        if (LIKELY(subscript.isUInt32())) {
            uint32_t i = subscript.asUInt32();
            if (isJSArray(baseValue)) {
                JSArray* jsArray = asArray(baseValue);
                if (jsArray->canGetIndex(i))
                    result = jsArray->getIndex(i);
                else
                    result = jsArray->JSArray::get(callFrame, i);
            } else if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
                result = asString(baseValue)->getIndex(callFrame, i);
            else if (isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i))
                result = asByteArray(baseValue)->getIndex(callFrame, i);
            else
                result = baseValue.get(callFrame, i);
        } else {
            Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
            result = baseValue.get(callFrame, property);
        }

        CHECK_FOR_EXCEPTION();
        callFrame->uncheckedR(dst) = result;
        vPC += OPCODE_LENGTH(op_get_by_val);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_put_by_val) {
        /* put_by_val base(r) property(r) value(r)

           Sets register value on register base as the property named
           by register property. Base is converted to object
           first. register property is nominally converted to string
           but numbers are treated more efficiently.

           Unlike many opcodes, this one does not write any output to
           the register file.
        */
        int base = vPC[1].u.operand;
        int property = vPC[2].u.operand;
        int value = vPC[3].u.operand;

        JSValue baseValue = callFrame->r(base).jsValue();
        JSValue subscript = callFrame->r(property).jsValue();

        if (LIKELY(subscript.isUInt32())) {
            uint32_t i = subscript.asUInt32();
            if (isJSArray(baseValue)) {
                JSArray* jsArray = asArray(baseValue);
                if (jsArray->canSetIndex(i))
                    jsArray->setIndex(*globalData, i, callFrame->r(value).jsValue());
                else
                    jsArray->JSArray::putByIndex(jsArray, callFrame, i, callFrame->r(value).jsValue());
            } else if (isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
                JSByteArray* jsByteArray = asByteArray(baseValue);
                JSValue jsValue = callFrame->r(value).jsValue();
                if (jsValue.isInt32())
                    jsByteArray->setIndex(i, jsValue.asInt32());
                else if (jsValue.isDouble())
                    jsByteArray->setIndex(i, jsValue.asDouble());
                else
                    baseValue.put(callFrame, i, jsValue);
            } else
                baseValue.put(callFrame, i, callFrame->r(value).jsValue());
        } else {
            Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
            if (!globalData->exception) { // Don't put to an object if toString threw an exception.
                PutPropertySlot slot(codeBlock->isStrictMode());
                baseValue.put(callFrame, property, callFrame->r(value).jsValue(), slot);
            }
        }

        CHECK_FOR_EXCEPTION();
        vPC += OPCODE_LENGTH(op_put_by_val);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_del_by_val) {
        /* del_by_val dst(r) base(r) property(r)

           Converts register base to Object, deletes the property
           named by register property from the object, and writes a
           boolean indicating success (if true) or failure (if false)
           to register dst.
        */
        int dst = vPC[1].u.operand;
        int base = vPC[2].u.operand;
        int property = vPC[3].u.operand;

        JSObject* baseObj = callFrame->r(base).jsValue().toObject(callFrame); // may throw

        JSValue subscript = callFrame->r(property).jsValue();
        bool result;
        uint32_t i;
        if (subscript.getUInt32(i))
            result = baseObj->methodTable()->deletePropertyByIndex(baseObj, callFrame, i);
        else {
            CHECK_FOR_EXCEPTION();
            Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
            CHECK_FOR_EXCEPTION();
            result = baseObj->methodTable()->deleteProperty(baseObj, callFrame, property);
        }
        if (!result && codeBlock->isStrictMode()) {
            exceptionValue = createTypeError(callFrame, "Unable to delete property.");
            goto vm_throw;
        }
        CHECK_FOR_EXCEPTION();
        callFrame->uncheckedR(dst) = jsBoolean(result);
        vPC += OPCODE_LENGTH(op_del_by_val);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_put_by_index) {
        /* put_by_index base(r) property(n) value(r)

           Sets register value on register base as the property named
           by the immediate number property. Base is converted to
           object first.

           Unlike many opcodes, this one does not write any output to
           the register file.

           This opcode is mainly used to initialize array literals.
        */
        int base = vPC[1].u.operand;
        unsigned property = vPC[2].u.operand;
        int value = vPC[3].u.operand;

        callFrame->r(base).jsValue().put(callFrame, property, callFrame->r(value).jsValue());

        vPC += OPCODE_LENGTH(op_put_by_index);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_loop) {
        /* loop target(offset)
         
           Jumps unconditionally to offset target from the current
           instruction.

           Additionally this loop instruction may terminate JS execution is
           the JS timeout is reached.
         */
#if ENABLE(OPCODE_STATS)
        OpcodeStats::resetLastInstruction();
#endif
        int target = vPC[1].u.operand;
        CHECK_FOR_TIMEOUT();
        vPC += target;
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_jmp) {
        /* jmp target(offset)

           Jumps unconditionally to offset target from the current
           instruction.
        */
#if ENABLE(OPCODE_STATS)
        OpcodeStats::resetLastInstruction();
#endif
        int target = vPC[1].u.operand;

        vPC += target;
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_loop_hint) {
        // This is a no-op unless we intend on doing OSR from the interpreter.
        vPC += OPCODE_LENGTH(op_loop_hint);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_loop_if_true) {
        /* loop_if_true cond(r) target(offset)
         
           Jumps to offset target from the current instruction, if and
           only if register cond converts to boolean as true.

           Additionally this loop instruction may terminate JS execution is
           the JS timeout is reached.
         */
        int cond = vPC[1].u.operand;
        int target = vPC[2].u.operand;
        if (callFrame->r(cond).jsValue().toBoolean(callFrame)) {
            vPC += target;
            CHECK_FOR_TIMEOUT();
            NEXT_INSTRUCTION();
        }
        
        vPC += OPCODE_LENGTH(op_loop_if_true);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_loop_if_false) {
        /* loop_if_true cond(r) target(offset)
         
           Jumps to offset target from the current instruction, if and
           only if register cond converts to boolean as false.

           Additionally this loop instruction may terminate JS execution is
           the JS timeout is reached.
         */
        int cond = vPC[1].u.operand;
        int target = vPC[2].u.operand;
        if (!callFrame->r(cond).jsValue().toBoolean(callFrame)) {
            vPC += target;
            CHECK_FOR_TIMEOUT();
            NEXT_INSTRUCTION();
        }
        
        vPC += OPCODE_LENGTH(op_loop_if_true);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_jtrue) {
        /* jtrue cond(r) target(offset)

           Jumps to offset target from the current instruction, if and
           only if register cond converts to boolean as true.
        */
        int cond = vPC[1].u.operand;
        int target = vPC[2].u.operand;
        if (callFrame->r(cond).jsValue().toBoolean(callFrame)) {
            vPC += target;
            NEXT_INSTRUCTION();
        }

        vPC += OPCODE_LENGTH(op_jtrue);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_jfalse) {
        /* jfalse cond(r) target(offset)

           Jumps to offset target from the current instruction, if and
           only if register cond converts to boolean as false.
        */
        int cond = vPC[1].u.operand;
        int target = vPC[2].u.operand;
        if (!callFrame->r(cond).jsValue().toBoolean(callFrame)) {
            vPC += target;
            NEXT_INSTRUCTION();
        }

        vPC += OPCODE_LENGTH(op_jfalse);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_jeq_null) {
        /* jeq_null src(r) target(offset)

           Jumps to offset target from the current instruction, if and
           only if register src is null.
        */
        int src = vPC[1].u.operand;
        int target = vPC[2].u.operand;
        JSValue srcValue = callFrame->r(src).jsValue();

        if (srcValue.isUndefinedOrNull() || (srcValue.isCell() && srcValue.asCell()->structure()->typeInfo().masqueradesAsUndefined())) {
            vPC += target;
            NEXT_INSTRUCTION();
        }

        vPC += OPCODE_LENGTH(op_jeq_null);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_jneq_null) {
        /* jneq_null src(r) target(offset)

           Jumps to offset target from the current instruction, if and
           only if register src is not null.
        */
        int src = vPC[1].u.operand;
        int target = vPC[2].u.operand;
        JSValue srcValue = callFrame->r(src).jsValue();

        if (!srcValue.isUndefinedOrNull() && (!srcValue.isCell() || !srcValue.asCell()->structure()->typeInfo().masqueradesAsUndefined())) {
            vPC += target;
            NEXT_INSTRUCTION();
        }

        vPC += OPCODE_LENGTH(op_jneq_null);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_jneq_ptr) {
        /* jneq_ptr src(r) ptr(jsCell) target(offset)
         
           Jumps to offset target from the current instruction, if the value r is equal
           to ptr, using pointer equality.
         */
        int src = vPC[1].u.operand;
        int target = vPC[3].u.operand;
        JSValue srcValue = callFrame->r(src).jsValue();
        if (srcValue != vPC[2].u.jsCell.get()) {
            vPC += target;
            NEXT_INSTRUCTION();
        }

        vPC += OPCODE_LENGTH(op_jneq_ptr);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_loop_if_less) {
        /* loop_if_less src1(r) src2(r) target(offset)

           Checks whether register src1 is less than register src2, as
           with the ECMAScript '<' operator, and then jumps to offset
           target from the current instruction, if and only if the 
           result of the comparison is true.

           Additionally this loop instruction may terminate JS execution is
           the JS timeout is reached.
         */
        JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
        JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
        int target = vPC[3].u.operand;
        
        bool result = jsLess<true>(callFrame, src1, src2);
        CHECK_FOR_EXCEPTION();
        
        if (result) {
            vPC += target;
            CHECK_FOR_TIMEOUT();
            NEXT_INSTRUCTION();
        }
        
        vPC += OPCODE_LENGTH(op_loop_if_less);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_loop_if_lesseq) {
        /* loop_if_lesseq src1(r) src2(r) target(offset)

           Checks whether register src1 is less than or equal to register
           src2, as with the ECMAScript '<=' operator, and then jumps to
           offset target from the current instruction, if and only if the 
           result of the comparison is true.

           Additionally this loop instruction may terminate JS execution is
           the JS timeout is reached.
        */
        JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
        JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
        int target = vPC[3].u.operand;
        
        bool result = jsLessEq<true>(callFrame, src1, src2);
        CHECK_FOR_EXCEPTION();
        
        if (result) {
            vPC += target;
            CHECK_FOR_TIMEOUT();
            NEXT_INSTRUCTION();
        }
        
        vPC += OPCODE_LENGTH(op_loop_if_lesseq);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_loop_if_greater) {
        /* loop_if_greater src1(r) src2(r) target(offset)

           Checks whether register src1 is greater than register src2, as
           with the ECMAScript '>' operator, and then jumps to offset
           target from the current instruction, if and only if the 
           result of the comparison is true.

           Additionally this loop instruction may terminate JS execution is
           the JS timeout is reached.
         */
        JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
        JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
        int target = vPC[3].u.operand;
        
        bool result = jsLess<false>(callFrame, src2, src1);
        CHECK_FOR_EXCEPTION();
        
        if (result) {
            vPC += target;
            CHECK_FOR_TIMEOUT();
            NEXT_INSTRUCTION();
        }
        
        vPC += OPCODE_LENGTH(op_loop_if_greater);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_loop_if_greatereq) {
        /* loop_if_greatereq src1(r) src2(r) target(offset)

           Checks whether register src1 is greater than or equal to register
           src2, as with the ECMAScript '>=' operator, and then jumps to
           offset target from the current instruction, if and only if the 
           result of the comparison is true.

           Additionally this loop instruction may terminate JS execution is
           the JS timeout is reached.
        */
        JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
        JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
        int target = vPC[3].u.operand;
        
        bool result = jsLessEq<false>(callFrame, src2, src1);
        CHECK_FOR_EXCEPTION();
        
        if (result) {
            vPC += target;
            CHECK_FOR_TIMEOUT();
            NEXT_INSTRUCTION();
        }
        
        vPC += OPCODE_LENGTH(op_loop_if_greatereq);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_jless) {
        /* jless src1(r) src2(r) target(offset)

           Checks whether register src1 is less than register src2, as
           with the ECMAScript '<' operator, and then jumps to offset
           target from the current instruction, if and only if the 
           result of the comparison is true.
        */
        JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
        JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
        int target = vPC[3].u.operand;

        bool result = jsLess<true>(callFrame, src1, src2);
        CHECK_FOR_EXCEPTION();
        
        if (result) {
            vPC += target;
            NEXT_INSTRUCTION();
        }

        vPC += OPCODE_LENGTH(op_jless);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_jlesseq) {
        /* jlesseq src1(r) src2(r) target(offset)
         
         Checks whether register src1 is less than or equal to
         register src2, as with the ECMAScript '<=' operator,
         and then jumps to offset target from the current instruction,
         if and only if the result of the comparison is true.
         */
        JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
        JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
        int target = vPC[3].u.operand;
        
        bool result = jsLessEq<true>(callFrame, src1, src2);
        CHECK_FOR_EXCEPTION();
        
        if (result) {
            vPC += target;
            NEXT_INSTRUCTION();
        }
        
        vPC += OPCODE_LENGTH(op_jlesseq);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_jgreater) {
        /* jgreater src1(r) src2(r) target(offset)

           Checks whether register src1 is greater than register src2, as
           with the ECMAScript '>' operator, and then jumps to offset
           target from the current instruction, if and only if the 
           result of the comparison is true.
        */
        JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
        JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
        int target = vPC[3].u.operand;

        bool result = jsLess<false>(callFrame, src2, src1);
        CHECK_FOR_EXCEPTION();
        
        if (result) {
            vPC += target;
            NEXT_INSTRUCTION();
        }

        vPC += OPCODE_LENGTH(op_jgreater);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_jgreatereq) {
        /* jgreatereq src1(r) src2(r) target(offset)
         
         Checks whether register src1 is greater than or equal to
         register src2, as with the ECMAScript '>=' operator,
         and then jumps to offset target from the current instruction,
         if and only if the result of the comparison is true.
         */
        JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
        JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
        int target = vPC[3].u.operand;
        
        bool result = jsLessEq<false>(callFrame, src2, src1);
        CHECK_FOR_EXCEPTION();
        
        if (result) {
            vPC += target;
            NEXT_INSTRUCTION();
        }
        
        vPC += OPCODE_LENGTH(op_jgreatereq);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_jnless) {
        /* jnless src1(r) src2(r) target(offset)

           Checks whether register src1 is less than register src2, as
           with the ECMAScript '<' operator, and then jumps to offset
           target from the current instruction, if and only if the 
           result of the comparison is false.
        */
        JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
        JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
        int target = vPC[3].u.operand;

        bool result = jsLess<true>(callFrame, src1, src2);
        CHECK_FOR_EXCEPTION();
        
        if (!result) {
            vPC += target;
            NEXT_INSTRUCTION();
        }

        vPC += OPCODE_LENGTH(op_jnless);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_jnlesseq) {
        /* jnlesseq src1(r) src2(r) target(offset)

           Checks whether register src1 is less than or equal to
           register src2, as with the ECMAScript '<=' operator,
           and then jumps to offset target from the current instruction,
           if and only if theresult of the comparison is false.
        */
        JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
        JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
        int target = vPC[3].u.operand;

        bool result = jsLessEq<true>(callFrame, src1, src2);
        CHECK_FOR_EXCEPTION();
        
        if (!result) {
            vPC += target;
            NEXT_INSTRUCTION();
        }

        vPC += OPCODE_LENGTH(op_jnlesseq);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_jngreater) {
        /* jngreater src1(r) src2(r) target(offset)

           Checks whether register src1 is greater than register src2, as
           with the ECMAScript '>' operator, and then jumps to offset
           target from the current instruction, if and only if the 
           result of the comparison is false.
        */
        JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
        JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
        int target = vPC[3].u.operand;

        bool result = jsLess<false>(callFrame, src2, src1);
        CHECK_FOR_EXCEPTION();
        
        if (!result) {
            vPC += target;
            NEXT_INSTRUCTION();
        }

        vPC += OPCODE_LENGTH(op_jngreater);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_jngreatereq) {
        /* jngreatereq src1(r) src2(r) target(offset)

           Checks whether register src1 is greater than or equal to
           register src2, as with the ECMAScript '>=' operator,
           and then jumps to offset target from the current instruction,
           if and only if theresult of the comparison is false.
        */
        JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
        JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
        int target = vPC[3].u.operand;

        bool result = jsLessEq<false>(callFrame, src2, src1);
        CHECK_FOR_EXCEPTION();
        
        if (!result) {
            vPC += target;
            NEXT_INSTRUCTION();
        }

        vPC += OPCODE_LENGTH(op_jngreatereq);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_switch_imm) {
        /* switch_imm tableIndex(n) defaultOffset(offset) scrutinee(r)

           Performs a range checked switch on the scrutinee value, using
           the tableIndex-th immediate switch jump table.  If the scrutinee value
           is an immediate number in the range covered by the referenced jump
           table, and the value at jumpTable[scrutinee value] is non-zero, then
           that value is used as the jump offset, otherwise defaultOffset is used.
         */
        int tableIndex = vPC[1].u.operand;
        int defaultOffset = vPC[2].u.operand;
        JSValue scrutinee = callFrame->r(vPC[3].u.operand).jsValue();
        if (scrutinee.isInt32())
            vPC += codeBlock->immediateSwitchJumpTable(tableIndex).offsetForValue(scrutinee.asInt32(), defaultOffset);
        else if (scrutinee.isDouble() && scrutinee.asDouble() == static_cast<int32_t>(scrutinee.asDouble()))
            vPC += codeBlock->immediateSwitchJumpTable(tableIndex).offsetForValue(static_cast<int32_t>(scrutinee.asDouble()), defaultOffset);
        else
            vPC += defaultOffset;
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_switch_char) {
        /* switch_char tableIndex(n) defaultOffset(offset) scrutinee(r)

           Performs a range checked switch on the scrutinee value, using
           the tableIndex-th character switch jump table.  If the scrutinee value
           is a single character string in the range covered by the referenced jump
           table, and the value at jumpTable[scrutinee value] is non-zero, then
           that value is used as the jump offset, otherwise defaultOffset is used.
         */
        int tableIndex = vPC[1].u.operand;
        int defaultOffset = vPC[2].u.operand;
        JSValue scrutinee = callFrame->r(vPC[3].u.operand).jsValue();
        if (!scrutinee.isString())
            vPC += defaultOffset;
        else {
            StringImpl* value = asString(scrutinee)->value(callFrame).impl();
            if (value->length() != 1)
                vPC += defaultOffset;
            else
                vPC += codeBlock->characterSwitchJumpTable(tableIndex).offsetForValue((*value)[0], defaultOffset);
        }
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_switch_string) {
        /* switch_string tableIndex(n) defaultOffset(offset) scrutinee(r)

           Performs a sparse hashmap based switch on the value in the scrutinee
           register, using the tableIndex-th string switch jump table.  If the 
           scrutinee value is a string that exists as a key in the referenced 
           jump table, then the value associated with the string is used as the 
           jump offset, otherwise defaultOffset is used.
         */
        int tableIndex = vPC[1].u.operand;
        int defaultOffset = vPC[2].u.operand;
        JSValue scrutinee = callFrame->r(vPC[3].u.operand).jsValue();
        if (!scrutinee.isString())
            vPC += defaultOffset;
        else 
            vPC += codeBlock->stringSwitchJumpTable(tableIndex).offsetForValue(asString(scrutinee)->value(callFrame).impl(), defaultOffset);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_new_func) {
        /* new_func dst(r) func(f)

           Constructs a new Function instance from function func and
           the current scope chain using the original Function
           constructor, using the rules for function declarations, and
           puts the result in register dst.
        */
        int dst = vPC[1].u.operand;
        int func = vPC[2].u.operand;
        int shouldCheck = vPC[3].u.operand;
        ASSERT(codeBlock->codeType() != FunctionCode || !codeBlock->needsFullScopeChain() || callFrame->r(codeBlock->activationRegister()).jsValue());
        if (!shouldCheck || !callFrame->r(dst).jsValue())
            callFrame->uncheckedR(dst) = JSValue(codeBlock->functionDecl(func)->make(callFrame, callFrame->scopeChain()));

        vPC += OPCODE_LENGTH(op_new_func);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_new_func_exp) {
        /* new_func_exp dst(r) func(f)

           Constructs a new Function instance from function func and
           the current scope chain using the original Function
           constructor, using the rules for function expressions, and
           puts the result in register dst.
        */
        int dst = vPC[1].u.operand;
        int funcIndex = vPC[2].u.operand;
        
        ASSERT(codeBlock->codeType() != FunctionCode || !codeBlock->needsFullScopeChain() || callFrame->r(codeBlock->activationRegister()).jsValue());
        FunctionExecutable* function = codeBlock->functionExpr(funcIndex);
        JSFunction* func = function->make(callFrame, callFrame->scopeChain());

        /* 
            The Identifier in a FunctionExpression can be referenced from inside
            the FunctionExpression's FunctionBody to allow the function to call
            itself recursively. However, unlike in a FunctionDeclaration, the
            Identifier in a FunctionExpression cannot be referenced from and
            does not affect the scope enclosing the FunctionExpression.
         */
        if (!function->name().isNull()) {
            JSStaticScopeObject* functionScopeObject = JSStaticScopeObject::create(callFrame, function->name(), func, ReadOnly | DontDelete);
            func->setScope(*globalData, func->scope()->push(functionScopeObject));
        }

        callFrame->uncheckedR(dst) = JSValue(func);

        vPC += OPCODE_LENGTH(op_new_func_exp);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_call_eval) {
        /* call_eval func(r) argCount(n) registerOffset(n)

           Call a function named "eval" with no explicit "this" value
           (which may therefore be the eval operator). If register
           thisVal is the global object, and register func contains
           that global object's original global eval function, then
           perform the eval operator in local scope (interpreting
           the argument registers as for the "call"
           opcode). Otherwise, act exactly as the "call" opcode would.
         */

        int func = vPC[1].u.operand;
        int argCount = vPC[2].u.operand;
        int registerOffset = vPC[3].u.operand;
        
        ASSERT(codeBlock->codeType() != FunctionCode || !codeBlock->needsFullScopeChain() || callFrame->r(codeBlock->activationRegister()).jsValue());
        JSValue funcVal = callFrame->r(func).jsValue();

        if (isHostFunction(funcVal, globalFuncEval)) {
            CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset);
            newCallFrame->init(0, vPC + OPCODE_LENGTH(op_call_eval), callFrame->scopeChain(), callFrame, argCount, asFunction(funcVal));

            JSValue result = eval(newCallFrame);
            if ((exceptionValue = globalData->exception))
                goto vm_throw;
            functionReturnValue = result;

            vPC += OPCODE_LENGTH(op_call_eval);
            NEXT_INSTRUCTION();
        }

        // We didn't find the blessed version of eval, so process this
        // instruction as a normal function call.
        // fall through to op_call
    }
    DEFINE_OPCODE(op_call) {
        /* call func(r) argCount(n) registerOffset(n)

           Perform a function call.
           
           registerOffset is the distance the callFrame pointer should move
           before the VM initializes the new call frame's header.
           
           dst is where op_ret should store its result.
         */

        int func = vPC[1].u.operand;
        int argCount = vPC[2].u.operand;
        int registerOffset = vPC[3].u.operand;

        JSValue v = callFrame->r(func).jsValue();

        CallData callData;
        CallType callType = getCallData(v, callData);

        if (callType == CallTypeJS) {
            ScopeChainNode* callDataScopeChain = callData.js.scopeChain;

            JSObject* error = callData.js.functionExecutable->compileForCall(callFrame, callDataScopeChain);
            if (UNLIKELY(!!error)) {
                exceptionValue = error;
                goto vm_throw;
            }

            CallFrame* previousCallFrame = callFrame;
            CodeBlock* newCodeBlock = &callData.js.functionExecutable->generatedBytecodeForCall();
            callFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, callFrame, registerOffset, argCount);
            if (UNLIKELY(!callFrame)) {
                callFrame = previousCallFrame;
                exceptionValue = createStackOverflowError(callFrame);
                goto vm_throw;
            }

            callFrame->init(newCodeBlock, vPC + OPCODE_LENGTH(op_call), callDataScopeChain, previousCallFrame, argCount, asFunction(v));
            codeBlock = newCodeBlock;
            ASSERT(codeBlock == callFrame->codeBlock());
            *topCallFrameSlot = callFrame;
            vPC = newCodeBlock->instructions().begin();

#if ENABLE(OPCODE_STATS)
            OpcodeStats::resetLastInstruction();
#endif

            NEXT_INSTRUCTION();
        }

        if (callType == CallTypeHost) {
            ScopeChainNode* scopeChain = callFrame->scopeChain();
            CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset);
            newCallFrame->init(0, vPC + OPCODE_LENGTH(op_call), scopeChain, callFrame, argCount, asObject(v));
            JSValue returnValue;
            {
                *topCallFrameSlot = newCallFrame;
                SamplingTool::HostCallRecord callRecord(m_sampler.get());
                returnValue = JSValue::decode(callData.native.function(newCallFrame));
                *topCallFrameSlot = callFrame;
            }
            CHECK_FOR_EXCEPTION();

            functionReturnValue = returnValue;

            vPC += OPCODE_LENGTH(op_call);
            NEXT_INSTRUCTION();
        }

        ASSERT(callType == CallTypeNone);

        exceptionValue = createNotAFunctionError(callFrame, v);
        goto vm_throw;
    }
    DEFINE_OPCODE(op_call_varargs) {
        /* call_varargs callee(r) thisValue(r) arguments(r) firstFreeRegister(n)
         
         Perform a function call with a dynamic set of arguments.
         
         registerOffset is the distance the callFrame pointer should move
         before the VM initializes the new call frame's header, excluding
         space for arguments.
         
         dst is where op_ret should store its result.
         */
        
        JSValue v = callFrame->r(vPC[1].u.operand).jsValue();
        JSValue thisValue = callFrame->r(vPC[2].u.operand).jsValue();
        JSValue arguments = callFrame->r(vPC[3].u.operand).jsValue();
        int firstFreeRegister = vPC[4].u.operand;

        CallFrame* newCallFrame = loadVarargs(callFrame, registerFile, thisValue, arguments, firstFreeRegister);
        if ((exceptionValue = globalData->exception))
            goto vm_throw;
        int argCount = newCallFrame->argumentCountIncludingThis();

        CallData callData;
        CallType callType = getCallData(v, callData);
        
        if (callType == CallTypeJS) {
            ScopeChainNode* callDataScopeChain = callData.js.scopeChain;

            JSObject* error = callData.js.functionExecutable->compileForCall(callFrame, callDataScopeChain);
            if (UNLIKELY(!!error)) {
                exceptionValue = error;
                goto vm_throw;
            }

            CodeBlock* newCodeBlock = &callData.js.functionExecutable->generatedBytecodeForCall();
            newCallFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, newCallFrame, 0, argCount);
            if (UNLIKELY(!newCallFrame)) {
                exceptionValue = createStackOverflowError(callFrame);
                goto vm_throw;
            }

            newCallFrame->init(newCodeBlock, vPC + OPCODE_LENGTH(op_call_varargs), callDataScopeChain, callFrame, argCount, asFunction(v));
            codeBlock = newCodeBlock;
            callFrame = newCallFrame;
            ASSERT(codeBlock == callFrame->codeBlock());
            *topCallFrameSlot = callFrame;
            vPC = newCodeBlock->instructions().begin();

#if ENABLE(OPCODE_STATS)
            OpcodeStats::resetLastInstruction();
#endif
            
            NEXT_INSTRUCTION();
        }
        
        if (callType == CallTypeHost) {
            ScopeChainNode* scopeChain = callFrame->scopeChain();
            newCallFrame->init(0, vPC + OPCODE_LENGTH(op_call_varargs), scopeChain, callFrame, argCount, asObject(v));
            
            JSValue returnValue;
            {
                *topCallFrameSlot = newCallFrame;
                SamplingTool::HostCallRecord callRecord(m_sampler.get());
                returnValue = JSValue::decode(callData.native.function(newCallFrame));
                *topCallFrameSlot = callFrame;
            }
            CHECK_FOR_EXCEPTION();
            
            functionReturnValue = returnValue;
            
            vPC += OPCODE_LENGTH(op_call_varargs);
            NEXT_INSTRUCTION();
        }
        
        ASSERT(callType == CallTypeNone);
        
        exceptionValue = createNotAFunctionError(callFrame, v);
        goto vm_throw;
    }
    DEFINE_OPCODE(op_tear_off_activation) {
        /* tear_off_activation activation(r) arguments(r)

           Copy locals and named parameters from the register file to the heap.
           Point the bindings in 'activation' and 'arguments' to this new backing
           store. (Note that 'arguments' may not have been created. If created,
           'arguments' already holds a copy of any extra / unnamed parameters.)

           This opcode appears before op_ret in functions that require full scope chains.
        */

        int activation = vPC[1].u.operand;
        int arguments = vPC[2].u.operand;
        ASSERT(codeBlock->needsFullScopeChain());
        JSValue activationValue = callFrame->r(activation).jsValue();
        if (activationValue) {
            asActivation(activationValue)->tearOff(*globalData);

            if (JSValue argumentsValue = callFrame->r(unmodifiedArgumentsRegister(arguments)).jsValue())
                asArguments(argumentsValue)->didTearOffActivation(*globalData, asActivation(activationValue));
        } else if (JSValue argumentsValue = callFrame->r(unmodifiedArgumentsRegister(arguments)).jsValue()) {
            if (!codeBlock->isStrictMode())
                asArguments(argumentsValue)->tearOff(callFrame);
        }

        vPC += OPCODE_LENGTH(op_tear_off_activation);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_tear_off_arguments) {
        /* tear_off_arguments arguments(r)

           Copy named parameters from the register file to the heap. Point the
           bindings in 'arguments' to this new backing store. (Note that
           'arguments' may not have been created. If created, 'arguments' already
           holds a copy of any extra / unnamed parameters.)

           This opcode appears before op_ret in functions that don't require full
           scope chains, but do use 'arguments'.
        */

        int src1 = vPC[1].u.operand;
        ASSERT(!codeBlock->needsFullScopeChain() && codeBlock->ownerExecutable()->usesArguments());

        if (JSValue arguments = callFrame->r(unmodifiedArgumentsRegister(src1)).jsValue())
            asArguments(arguments)->tearOff(callFrame);

        vPC += OPCODE_LENGTH(op_tear_off_arguments);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_ret) {
        /* ret result(r)
           
           Return register result as the return value of the current
           function call, writing it into functionReturnValue.
           In addition, unwind one call frame and restore the scope
           chain, code block instruction pointer and register base
           to those of the calling function.
        */

        int result = vPC[1].u.operand;

        JSValue returnValue = callFrame->r(result).jsValue();

        vPC = callFrame->returnVPC();
        callFrame = callFrame->callerFrame();

        if (callFrame->hasHostCallFrameFlag())
            return returnValue;

        *topCallFrameSlot = callFrame;
        functionReturnValue = returnValue;
        codeBlock = callFrame->codeBlock();
        ASSERT(codeBlock == callFrame->codeBlock());

        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_call_put_result) {
        /* op_call_put_result result(r)
           
           Move call result from functionReturnValue to caller's
           expected return value register.
        */

        callFrame->uncheckedR(vPC[1].u.operand) = functionReturnValue;

        vPC += OPCODE_LENGTH(op_call_put_result);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_ret_object_or_this) {
        /* ret result(r)
           
           Return register result as the return value of the current
           function call, writing it into the caller's expected return
           value register. In addition, unwind one call frame and
           restore the scope chain, code block instruction pointer and
           register base to those of the calling function.
        */

        int result = vPC[1].u.operand;

        JSValue returnValue = callFrame->r(result).jsValue();

        if (UNLIKELY(!returnValue.isObject()))
            returnValue = callFrame->r(vPC[2].u.operand).jsValue();

        vPC = callFrame->returnVPC();
        callFrame = callFrame->callerFrame();

        if (callFrame->hasHostCallFrameFlag())
            return returnValue;

        *topCallFrameSlot = callFrame;
        functionReturnValue = returnValue;
        codeBlock = callFrame->codeBlock();
        ASSERT(codeBlock == callFrame->codeBlock());

        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_enter) {
        /* enter

           Initializes local variables to undefined. If the code block requires
           an activation, enter_with_activation is used instead.

           This opcode appears only at the beginning of a code block.
        */

        size_t i = 0;
        for (size_t count = codeBlock->m_numVars; i < count; ++i)
            callFrame->uncheckedR(i) = jsUndefined();

        vPC += OPCODE_LENGTH(op_enter);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_create_activation) {
        /* create_activation dst(r)

           If the activation object for this callframe has not yet been created,
           this creates it and writes it back to dst.
        */

        int activationReg = vPC[1].u.operand;
        if (!callFrame->r(activationReg).jsValue()) {
            JSActivation* activation = JSActivation::create(*globalData, callFrame, static_cast<FunctionExecutable*>(codeBlock->ownerExecutable()));
            callFrame->r(activationReg) = JSValue(activation);
            callFrame->setScopeChain(callFrame->scopeChain()->push(activation));
        }
        vPC += OPCODE_LENGTH(op_create_activation);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_get_callee) {
        /* op_get_callee callee(r)

           Move callee into a register.
        */

        callFrame->uncheckedR(vPC[1].u.operand) = JSValue(callFrame->callee());

        vPC += OPCODE_LENGTH(op_get_callee);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_create_this) {
        /* op_create_this this(r) proto(r)

           Allocate an object as 'this', fr use in construction.

           This opcode should only be used at the beginning of a code
           block.
        */

        int thisRegister = vPC[1].u.operand;
        int protoRegister = vPC[2].u.operand;

        JSFunction* constructor = asFunction(callFrame->callee());
#if !ASSERT_DISABLED
        ConstructData constructData;
        ASSERT(constructor->methodTable()->getConstructData(constructor, constructData) == ConstructTypeJS);
#endif

        Structure* structure;
        JSValue proto = callFrame->r(protoRegister).jsValue();
        if (proto.isObject())
            structure = asObject(proto)->inheritorID(callFrame->globalData());
        else
            structure = constructor->scope()->globalObject->emptyObjectStructure();
        callFrame->uncheckedR(thisRegister) = constructEmptyObject(callFrame, structure);

        vPC += OPCODE_LENGTH(op_create_this);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_convert_this) {
        /* convert_this this(r)

           Takes the value in the 'this' register, converts it to a
           value that is suitable for use as the 'this' value, and
           stores it in the 'this' register. This opcode is emitted
           to avoid doing the conversion in the caller unnecessarily.

           This opcode should only be used at the beginning of a code
           block.
        */

        int thisRegister = vPC[1].u.operand;
        JSValue thisVal = callFrame->r(thisRegister).jsValue();
        if (thisVal.isPrimitive())
            callFrame->uncheckedR(thisRegister) = JSValue(thisVal.toThisObject(callFrame));

        vPC += OPCODE_LENGTH(op_convert_this);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_init_lazy_reg) {
        /* init_lazy_reg dst(r)

           Initialises dst(r) to JSValue().

           This opcode appears only at the beginning of a code block.
         */
        int dst = vPC[1].u.operand;

        callFrame->uncheckedR(dst) = JSValue();
        vPC += OPCODE_LENGTH(op_init_lazy_reg);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_create_arguments) {
        /* create_arguments dst(r)

           Creates the 'arguments' object and places it in both the
           'arguments' call frame slot and the local 'arguments'
           register, if it has not already been initialised.
         */
        
        int dst = vPC[1].u.operand;

        if (!callFrame->r(dst).jsValue()) {
            Arguments* arguments = Arguments::create(*globalData, callFrame);
            callFrame->uncheckedR(dst) = JSValue(arguments);
            callFrame->uncheckedR(unmodifiedArgumentsRegister(dst)) = JSValue(arguments);
        }
        vPC += OPCODE_LENGTH(op_create_arguments);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_construct) {
        /* construct func(r) argCount(n) registerOffset(n) proto(r) thisRegister(r)

           Invoke register "func" as a constructor. For JS
           functions, the calling convention is exactly as for the
           "call" opcode, except that the "this" value is a newly
           created Object. For native constructors, no "this"
           value is passed. In either case, the argCount and registerOffset
           registers are interpreted as for the "call" opcode.

           Register proto must contain the prototype property of
           register func. This is to enable polymorphic inline
           caching of this lookup.
        */

        int func = vPC[1].u.operand;
        int argCount = vPC[2].u.operand;
        int registerOffset = vPC[3].u.operand;

        JSValue v = callFrame->r(func).jsValue();

        ConstructData constructData;
        ConstructType constructType = getConstructData(v, constructData);

        if (constructType == ConstructTypeJS) {
            ScopeChainNode* callDataScopeChain = constructData.js.scopeChain;

            JSObject* error = constructData.js.functionExecutable->compileForConstruct(callFrame, callDataScopeChain);
            if (UNLIKELY(!!error)) {
                exceptionValue = error;
                goto vm_throw;
            }

            CallFrame* previousCallFrame = callFrame;
            CodeBlock* newCodeBlock = &constructData.js.functionExecutable->generatedBytecodeForConstruct();
            callFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, callFrame, registerOffset, argCount);
            if (UNLIKELY(!callFrame)) {
                callFrame = previousCallFrame;
                exceptionValue = createStackOverflowError(callFrame);
                goto vm_throw;
            }

            callFrame->init(newCodeBlock, vPC + OPCODE_LENGTH(op_construct), callDataScopeChain, previousCallFrame, argCount, asFunction(v));
            codeBlock = newCodeBlock;
            *topCallFrameSlot = callFrame;
            vPC = newCodeBlock->instructions().begin();
#if ENABLE(OPCODE_STATS)
            OpcodeStats::resetLastInstruction();
#endif

            NEXT_INSTRUCTION();
        }

        if (constructType == ConstructTypeHost) {
            ScopeChainNode* scopeChain = callFrame->scopeChain();
            CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset);
            newCallFrame->init(0, vPC + OPCODE_LENGTH(op_construct), scopeChain, callFrame, argCount, asObject(v));

            JSValue returnValue;
            {
                *topCallFrameSlot = newCallFrame;
                SamplingTool::HostCallRecord callRecord(m_sampler.get());
                returnValue = JSValue::decode(constructData.native.function(newCallFrame));
                *topCallFrameSlot = callFrame;
            }
            CHECK_FOR_EXCEPTION();
            functionReturnValue = returnValue;

            vPC += OPCODE_LENGTH(op_construct);
            NEXT_INSTRUCTION();
        }

        ASSERT(constructType == ConstructTypeNone);

        exceptionValue = createNotAConstructorError(callFrame, v);
        goto vm_throw;
    }
    DEFINE_OPCODE(op_strcat) {
        /* strcat dst(r) src(r) count(n)

           Construct a new String instance using the original
           constructor, and puts the result in register dst.
           The string will be the result of concatenating count
           strings with values taken from registers starting at
           register src.
        */
        int dst = vPC[1].u.operand;
        int src = vPC[2].u.operand;
        int count = vPC[3].u.operand;

        callFrame->uncheckedR(dst) = concatenateStrings(callFrame, &callFrame->registers()[src], count);
        CHECK_FOR_EXCEPTION();
        vPC += OPCODE_LENGTH(op_strcat);

        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_to_primitive) {
        int dst = vPC[1].u.operand;
        int src = vPC[2].u.operand;

        callFrame->uncheckedR(dst) = callFrame->r(src).jsValue().toPrimitive(callFrame);
        vPC += OPCODE_LENGTH(op_to_primitive);

        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_push_scope) {
        /* push_scope scope(r)

           Converts register scope to object, and pushes it onto the top
           of the current scope chain.  The contents of the register scope
           are replaced by the result of toObject conversion of the scope.
        */
        int scope = vPC[1].u.operand;
        JSValue v = callFrame->r(scope).jsValue();
        JSObject* o = v.toObject(callFrame);
        CHECK_FOR_EXCEPTION();

        callFrame->uncheckedR(scope) = JSValue(o);
        callFrame->setScopeChain(callFrame->scopeChain()->push(o));

        vPC += OPCODE_LENGTH(op_push_scope);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_pop_scope) {
        /* pop_scope

           Removes the top item from the current scope chain.
        */
        callFrame->setScopeChain(callFrame->scopeChain()->pop());

        vPC += OPCODE_LENGTH(op_pop_scope);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_get_pnames) {
        /* get_pnames dst(r) base(r) i(n) size(n) breakTarget(offset)

           Creates a property name list for register base and puts it
           in register dst, initializing i and size for iteration. If
           base is undefined or null, jumps to breakTarget.
        */
        int dst = vPC[1].u.operand;
        int base = vPC[2].u.operand;
        int i = vPC[3].u.operand;
        int size = vPC[4].u.operand;
        int breakTarget = vPC[5].u.operand;

        JSValue v = callFrame->r(base).jsValue();
        if (v.isUndefinedOrNull()) {
            vPC += breakTarget;
            NEXT_INSTRUCTION();
        }

        JSObject* o = v.toObject(callFrame);
        Structure* structure = o->structure();
        JSPropertyNameIterator* jsPropertyNameIterator = structure->enumerationCache();
        if (!jsPropertyNameIterator || jsPropertyNameIterator->cachedPrototypeChain() != structure->prototypeChain(callFrame))
            jsPropertyNameIterator = JSPropertyNameIterator::create(callFrame, o);

        callFrame->uncheckedR(dst) = jsPropertyNameIterator;
        callFrame->uncheckedR(base) = JSValue(o);
        callFrame->uncheckedR(i) = Register::withInt(0);
        callFrame->uncheckedR(size) = Register::withInt(jsPropertyNameIterator->size());
        vPC += OPCODE_LENGTH(op_get_pnames);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_next_pname) {
        /* next_pname dst(r) base(r) i(n) size(n) iter(r) target(offset)

           Copies the next name from the property name list in
           register iter to dst, then jumps to offset target. If there are no
           names left, invalidates the iterator and continues to the next
           instruction.
        */
        int dst = vPC[1].u.operand;
        int base = vPC[2].u.operand;
        int i = vPC[3].u.operand;
        int size = vPC[4].u.operand;
        int iter = vPC[5].u.operand;
        int target = vPC[6].u.operand;

        JSPropertyNameIterator* it = callFrame->r(iter).propertyNameIterator();
        while (callFrame->r(i).i() != callFrame->r(size).i()) {
            JSValue key = it->get(callFrame, asObject(callFrame->r(base).jsValue()), callFrame->r(i).i());
            CHECK_FOR_EXCEPTION();
            callFrame->uncheckedR(i) = Register::withInt(callFrame->r(i).i() + 1);
            if (key) {
                CHECK_FOR_TIMEOUT();
                callFrame->uncheckedR(dst) = key;
                vPC += target;
                NEXT_INSTRUCTION();
            }
        }

        vPC += OPCODE_LENGTH(op_next_pname);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_jmp_scopes) {
        /* jmp_scopes count(n) target(offset)

           Removes the a number of items from the current scope chain
           specified by immediate number count, then jumps to offset
           target.
        */
        int count = vPC[1].u.operand;
        int target = vPC[2].u.operand;

        ScopeChainNode* tmp = callFrame->scopeChain();
        while (count--)
            tmp = tmp->pop();
        callFrame->setScopeChain(tmp);

        vPC += target;
        NEXT_INSTRUCTION();
    }
#if ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
    // Appease GCC
    goto *(&&skip_new_scope);
#endif
    DEFINE_OPCODE(op_push_new_scope) {
        /* new_scope dst(r) property(id) value(r)
         
           Constructs a new StaticScopeObject with property set to value.  That scope
           object is then pushed onto the ScopeChain.  The scope object is then stored
           in dst for GC.
         */
        callFrame->setScopeChain(createExceptionScope(callFrame, vPC));

        vPC += OPCODE_LENGTH(op_push_new_scope);
        NEXT_INSTRUCTION();
    }
#if ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
    skip_new_scope:
#endif
    DEFINE_OPCODE(op_catch) {
        /* catch ex(r)

           Retrieves the VM's current exception and puts it in register
           ex. This is only valid after an exception has been raised,
           and usually forms the beginning of an exception handler.
        */
        ASSERT(exceptionValue);
        ASSERT(!globalData->exception);
        int ex = vPC[1].u.operand;
        callFrame->uncheckedR(ex) = exceptionValue;
        exceptionValue = JSValue();

        vPC += OPCODE_LENGTH(op_catch);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_throw) {
        /* throw ex(r)

           Throws register ex as an exception. This involves three
           steps: first, it is set as the current exception in the
           VM's internal state, then the stack is unwound until an
           exception handler or a native code boundary is found, and
           then control resumes at the exception handler if any or
           else the script returns control to the nearest native caller.
        */

        int ex = vPC[1].u.operand;
        exceptionValue = callFrame->r(ex).jsValue();

        handler = throwException(callFrame, exceptionValue, vPC - codeBlock->instructions().begin());
        if (!handler)
            return throwError(callFrame, exceptionValue);

        codeBlock = callFrame->codeBlock();
        vPC = codeBlock->instructions().begin() + handler->target;
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_throw_reference_error) {
        /* op_throw_reference_error message(k)

           Constructs a new reference Error instance using the
           original constructor, using constant message as the
           message string. The result is thrown.
        */
        UString message = callFrame->r(vPC[1].u.operand).jsValue().toString(callFrame)->value(callFrame);
        exceptionValue = JSValue(createReferenceError(callFrame, message));
        goto vm_throw;
    }
    DEFINE_OPCODE(op_end) {
        /* end result(r)
           
           Return register result as the value of a global or eval
           program. Return control to the calling native code.
        */

        int result = vPC[1].u.operand;
        return callFrame->r(result).jsValue();
    }
    DEFINE_OPCODE(op_put_getter_setter) {
        /* put_getter_setter base(r) property(id) getter(r) setter(r)

           Puts accessor descriptor to register base as the named
           identifier property. Base and function may be objects
           or undefined, this op should only be used for accessors
           defined in object literal form.

           Unlike many opcodes, this one does not write any output to
           the register file.
        */
        int base = vPC[1].u.operand;
        int property = vPC[2].u.operand;
        int getterReg = vPC[3].u.operand;
        int setterReg = vPC[4].u.operand;

        ASSERT(callFrame->r(base).jsValue().isObject());
        JSObject* baseObj = asObject(callFrame->r(base).jsValue());
        Identifier& ident = codeBlock->identifier(property);

        GetterSetter* accessor = GetterSetter::create(callFrame);

        JSValue getter = callFrame->r(getterReg).jsValue();
        JSValue setter = callFrame->r(setterReg).jsValue();
        ASSERT(getter.isObject() || getter.isUndefined());
        ASSERT(setter.isObject() || setter.isUndefined());
        ASSERT(getter.isObject() || setter.isObject());

        if (!getter.isUndefined())
            accessor->setGetter(callFrame->globalData(), asObject(getter));
        if (!setter.isUndefined())
            accessor->setSetter(callFrame->globalData(), asObject(setter));
        baseObj->putDirectAccessor(callFrame->globalData(), ident, accessor, Accessor);

        vPC += OPCODE_LENGTH(op_put_getter_setter);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_method_check) {
        vPC++;
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_jsr) {
        /* jsr retAddrDst(r) target(offset)

           Places the address of the next instruction into the retAddrDst
           register and jumps to offset target from the current instruction.
        */
        int retAddrDst = vPC[1].u.operand;
        int target = vPC[2].u.operand;
        callFrame->r(retAddrDst) = vPC + OPCODE_LENGTH(op_jsr);

        vPC += target;
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_sret) {
        /* sret retAddrSrc(r)

         Jumps to the address stored in the retAddrSrc register. This
         differs from op_jmp because the target address is stored in a
         register, not as an immediate.
        */
        int retAddrSrc = vPC[1].u.operand;
        vPC = callFrame->r(retAddrSrc).vPC();
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_debug) {
        /* debug debugHookID(n) firstLine(n) lastLine(n)

         Notifies the debugger of the current state of execution. This opcode
         is only generated while the debugger is attached.
        */
        int debugHookID = vPC[1].u.operand;
        int firstLine = vPC[2].u.operand;
        int lastLine = vPC[3].u.operand;

        debug(callFrame, static_cast<DebugHookID>(debugHookID), firstLine, lastLine);

        vPC += OPCODE_LENGTH(op_debug);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_profile_will_call) {
        /* op_profile_will_call function(r)

         Notifies the profiler of the beginning of a function call. This opcode
         is only generated if developer tools are enabled.
        */
        int function = vPC[1].u.operand;

        if (*enabledProfilerReference)
            (*enabledProfilerReference)->willExecute(callFrame, callFrame->r(function).jsValue());

        vPC += OPCODE_LENGTH(op_profile_will_call);
        NEXT_INSTRUCTION();
    }
    DEFINE_OPCODE(op_profile_did_call) {
        /* op_profile_did_call function(r)

         Notifies the profiler of the end of a function call. This opcode
         is only generated if developer tools are enabled.
        */
        int function = vPC[1].u.operand;

        if (*enabledProfilerReference)
            (*enabledProfilerReference)->didExecute(callFrame, callFrame->r(function).jsValue());

        vPC += OPCODE_LENGTH(op_profile_did_call);
        NEXT_INSTRUCTION();
    }
    vm_throw: {
        globalData->exception = JSValue();
        if (!tickCount) {
            // The exceptionValue is a lie! (GCC produces bad code for reasons I 
            // cannot fathom if we don't assign to the exceptionValue before branching)
            exceptionValue = createInterruptedExecutionException(globalData);
        }
        JSGlobalObject* globalObject = callFrame->lexicalGlobalObject();
        handler = throwException(callFrame, exceptionValue, vPC - codeBlock->instructions().begin());
        if (!handler) {
            // Can't use the callframe at this point as the scopechain, etc have
            // been released.
            return throwError(globalObject->globalExec(), exceptionValue);
        }

        codeBlock = callFrame->codeBlock();
        vPC = codeBlock->instructions().begin() + handler->target;
        NEXT_INSTRUCTION();
    }
    }
#if !ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
    } // iterator loop ends
#endif
    #undef NEXT_INSTRUCTION
    #undef DEFINE_OPCODE
    #undef CHECK_FOR_EXCEPTION
    #undef CHECK_FOR_TIMEOUT
#endif // ENABLE(CLASSIC_INTERPRETER)
}

JSValue Interpreter::retrieveArgumentsFromVMCode(CallFrame* callFrame, JSFunction* function) const
{
    CallFrame* functionCallFrame = findFunctionCallFrameFromVMCode(callFrame, function);
    if (!functionCallFrame)
        return jsNull();

    CodeBlock* codeBlock = functionCallFrame->codeBlock();
    if (codeBlock->usesArguments()) {
        ASSERT(codeBlock->codeType() == FunctionCode);
        int argumentsRegister = codeBlock->argumentsRegister();
        int realArgumentsRegister = unmodifiedArgumentsRegister(argumentsRegister);
        if (JSValue arguments = functionCallFrame->uncheckedR(argumentsRegister).jsValue())
            return arguments;
        JSValue arguments = JSValue(Arguments::create(callFrame->globalData(), functionCallFrame));
        functionCallFrame->r(argumentsRegister) = arguments;
        functionCallFrame->r(realArgumentsRegister) = arguments;
        return arguments;
    }

    Arguments* arguments = Arguments::create(functionCallFrame->globalData(), functionCallFrame);
    arguments->tearOff(functionCallFrame);
    return JSValue(arguments);
}

JSValue Interpreter::retrieveCallerFromVMCode(CallFrame* callFrame, JSFunction* function) const
{
    CallFrame* functionCallFrame = findFunctionCallFrameFromVMCode(callFrame, function);
    if (!functionCallFrame)
        return jsNull();
    
    if (functionCallFrame->callerFrame()->hasHostCallFrameFlag())
        return jsNull();

    CallFrame* callerFrame = functionCallFrame->trueCallerFrame();

    JSValue caller = callerFrame->callee();
    if (!caller)
        return jsNull();

    return caller;
}

void Interpreter::retrieveLastCaller(CallFrame* callFrame, int& lineNumber, intptr_t& sourceID, UString& sourceURL, JSValue& function) const
{
    function = JSValue();
    lineNumber = -1;
    sourceURL = UString();

    CallFrame* callerFrame = callFrame->callerFrame();
    if (callerFrame->hasHostCallFrameFlag())
        return;

    CodeBlock* callerCodeBlock = callerFrame->codeBlock();
    if (!callerCodeBlock)
        return;
    unsigned bytecodeOffset = 0;
#if ENABLE(CLASSIC_INTERPRETER)
    if (!callerFrame->globalData().canUseJIT())
        bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnVPC());
#if ENABLE(JIT)
    else
        bytecodeOffset = callerCodeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
#endif
#else
    bytecodeOffset = callerCodeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
#endif
    lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset - 1);
    sourceID = callerCodeBlock->ownerExecutable()->sourceID();
    sourceURL = callerCodeBlock->ownerExecutable()->sourceURL();
    function = callerFrame->callee();
}

CallFrame* Interpreter::findFunctionCallFrameFromVMCode(CallFrame* callFrame, JSFunction* function)
{
    for (CallFrame* candidate = callFrame->trueCallFrameFromVMCode(); candidate; candidate = candidate->trueCallerFrame()) {
        if (candidate->callee() == function)
            return candidate;
    }
    return 0;
}

void Interpreter::enableSampler()
{
#if ENABLE(OPCODE_SAMPLING)
    if (!m_sampler) {
        m_sampler = adoptPtr(new SamplingTool(this));
        m_sampler->setup();
    }
#endif
}
void Interpreter::dumpSampleData(ExecState* exec)
{
#if ENABLE(OPCODE_SAMPLING)
    if (m_sampler)
        m_sampler->dump(exec);
#else
    UNUSED_PARAM(exec);
#endif
}
void Interpreter::startSampling()
{
#if ENABLE(SAMPLING_THREAD)
    if (!m_sampleEntryDepth)
        SamplingThread::start();

    m_sampleEntryDepth++;
#endif
}
void Interpreter::stopSampling()
{
#if ENABLE(SAMPLING_THREAD)
    m_sampleEntryDepth--;
    if (!m_sampleEntryDepth)
        SamplingThread::stop();
#endif
}

} // namespace JSC
