]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - interpreter/Interpreter.cpp
JavaScriptCore-584.tar.gz
[apple/javascriptcore.git] / interpreter / Interpreter.cpp
index a9e00995a81ce2441351d95cb6af845277cfca50..56ee7ea9c5f522925fe95949f5ebb08649038028 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
+ * 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
@@ -58,6 +58,7 @@
 #include "RegExpPrototype.h"
 #include "Register.h"
 #include "SamplingTool.h"
+#include <limits.h>
 #include <stdio.h>
 #include <wtf/Threading.h>
 
@@ -90,8 +91,8 @@ static int depth(CodeBlock* codeBlock, ScopeChain& sc)
 #if USE(INTERPRETER)
 NEVER_INLINE bool Interpreter::resolve(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue)
 {
-    int dst = (vPC + 1)->u.operand;
-    int property = (vPC + 2)->u.operand;
+    int dst = vPC[1].u.operand;
+    int property = vPC[2].u.operand;
 
     ScopeChainNode* scopeChain = callFrame->scopeChain();
     ScopeChainIterator iter = scopeChain->begin();
@@ -120,9 +121,9 @@ NEVER_INLINE bool Interpreter::resolveSkip(CallFrame* callFrame, Instruction* vP
 {
     CodeBlock* codeBlock = callFrame->codeBlock();
 
-    int dst = (vPC + 1)->u.operand;
-    int property = (vPC + 2)->u.operand;
-    int skip = (vPC + 3)->u.operand + codeBlock->needsFullScopeChain();
+    int dst = vPC[1].u.operand;
+    int property = vPC[2].u.operand;
+    int skip = vPC[3].u.operand + codeBlock->needsFullScopeChain();
 
     ScopeChainNode* scopeChain = callFrame->scopeChain();
     ScopeChainIterator iter = scopeChain->begin();
@@ -151,12 +152,12 @@ NEVER_INLINE bool Interpreter::resolveSkip(CallFrame* callFrame, Instruction* vP
 
 NEVER_INLINE bool Interpreter::resolveGlobal(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue)
 {
-    int dst = (vPC + 1)->u.operand;
-    JSGlobalObject* globalObject = static_cast<JSGlobalObject*>((vPC + 2)->u.jsCell);
+    int dst = vPC[1].u.operand;
+    JSGlobalObject* globalObject = static_cast<JSGlobalObject*>(vPC[2].u.jsCell);
     ASSERT(globalObject->isGlobalObject());
-    int property = (vPC + 3)->u.operand;
-    Structure* structure = (vPC + 4)->u.structure;
-    int offset = (vPC + 5)->u.operand;
+    int property = vPC[3].u.operand;
+    Structure* structure = vPC[4].u.structure;
+    int offset = vPC[5].u.operand;
 
     if (structure == globalObject->structure()) {
         callFrame->r(dst) = JSValue(globalObject->getDirectOffset(offset));
@@ -191,16 +192,16 @@ NEVER_INLINE bool Interpreter::resolveGlobal(CallFrame* callFrame, Instruction*
 
 NEVER_INLINE void Interpreter::resolveBase(CallFrame* callFrame, Instruction* vPC)
 {
-    int dst = (vPC + 1)->u.operand;
-    int property = (vPC + 2)->u.operand;
+    int dst = vPC[1].u.operand;
+    int property = vPC[2].u.operand;
     callFrame->r(dst) = JSValue(JSC::resolveBase(callFrame, callFrame->codeBlock()->identifier(property), callFrame->scopeChain()));
 }
 
 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;
+    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();
@@ -232,51 +233,6 @@ NEVER_INLINE bool Interpreter::resolveBaseAndProperty(CallFrame* callFrame, Inst
     return false;
 }
 
-NEVER_INLINE bool Interpreter::resolveBaseAndFunc(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue)
-{
-    int baseDst = (vPC + 1)->u.operand;
-    int funcDst = (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;
-        PropertySlot slot(base);
-        if (base->getPropertySlot(callFrame, ident, slot)) {            
-            // ECMA 11.2.3 says that if we hit an activation the this value should be null.
-            // However, section 10.2.3 says that in the case where the value provided
-            // by the caller is null, the global object should be used. It also says
-            // that the section does not apply to internal functions, but for simplicity
-            // of implementation we use the global object anyway here. This guarantees
-            // that in host objects you always get a valid object for this.
-            // We also handle wrapper substitution for the global object at the same time.
-            JSObject* thisObj = base->toThisObject(callFrame);
-            JSValue result = slot.getValue(callFrame, ident);
-            exceptionValue = callFrame->globalData().exception;
-            if (exceptionValue)
-                return false;
-
-            callFrame->r(baseDst) = JSValue(thisObj);
-            callFrame->r(funcDst) = JSValue(result);
-            return true;
-        }
-        ++iter;
-    } while (iter != end);
-
-    exceptionValue = createUndefinedVariableError(callFrame, ident, vPC - codeBlock->instructions().begin(), codeBlock);
-    return false;
-}
-
 #endif // USE(INTERPRETER)
 
 ALWAYS_INLINE CallFrame* Interpreter::slideRegisterWindowForCall(CodeBlock* newCodeBlock, RegisterFile* registerFile, CallFrame* callFrame, size_t registerOffset, int argc)
@@ -344,26 +300,25 @@ NEVER_INLINE JSValue Interpreter::callEval(CallFrame* callFrame, RegisterFile* r
     if (!program.isString())
         return program;
 
-    UString programSource = asString(program)->value();
+    UString programSource = asString(program)->value(callFrame);
 
     LiteralParser preparser(callFrame, programSource, LiteralParser::NonStrictJSON);
     if (JSValue parsedObject = preparser.tryLiteralParse())
         return parsedObject;
-    
-    
+
     ScopeChainNode* scopeChain = callFrame->scopeChain();
     CodeBlock* codeBlock = callFrame->codeBlock();
-    RefPtr<EvalNode> evalNode = codeBlock->evalCodeCache().get(callFrame, programSource, scopeChain, exceptionValue);
+    RefPtr<EvalExecutable> eval = codeBlock->evalCodeCache().get(callFrame, programSource, scopeChain, exceptionValue);
 
     JSValue result = jsUndefined();
-    if (evalNode)
-        result = callFrame->globalData().interpreter->execute(evalNode.get(), callFrame, callFrame->thisValue().toThisObject(callFrame), callFrame->registers() - registerFile->start() + registerOffset, scopeChain, &exceptionValue);
+    if (eval)
+        result = callFrame->globalData().interpreter->execute(eval.get(), callFrame, callFrame->thisValue().toThisObject(callFrame), callFrame->registers() - registerFile->start() + registerOffset, scopeChain, &exceptionValue);
 
     return result;
 }
 
 Interpreter::Interpreter()
-    : m_sampler(0)
+    : m_sampleEntryDepth(0)
     , m_reentryDepth(0)
 {
 #if HAVE(COMPUTED_GOTO)
@@ -372,6 +327,10 @@ Interpreter::Interpreter()
     for (int i = 0; i < numOpcodeIDs; ++i)
         m_opcodeIDTable.add(m_opcodeTable[i], static_cast<OpcodeID>(i));
 #endif // HAVE(COMPUTED_GOTO)
+
+#if ENABLE(OPCODE_SAMPLING)
+    enableSampler();
+#endif
 }
 
 #ifndef NDEBUG
@@ -390,7 +349,7 @@ void Interpreter::dumpRegisters(CallFrame* callFrame)
     printf("-----------------------------------------------------------------------------\n");
 
     CodeBlock* codeBlock = callFrame->codeBlock();
-    RegisterFile* registerFile = &callFrame->scopeChain()->globalObject()->globalData()->interpreter->registerFile();
+    RegisterFile* registerFile = &callFrame->scopeChain()->globalObject->globalData()->interpreter->registerFile();
     const Register* it;
     const Register* end;
     JSValue v;
@@ -494,21 +453,21 @@ NEVER_INLINE bool Interpreter::unwindCallFrame(CallFrame*& callFrame, JSValue ex
     if (Debugger* debugger = callFrame->dynamicGlobalObject()->debugger()) {
         DebuggerCallFrame debuggerCallFrame(callFrame, exceptionValue);
         if (callFrame->callee())
-            debugger->returnEvent(debuggerCallFrame, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->lastLine());
+            debugger->returnEvent(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->lastLine());
         else
-            debugger->didExecuteProgram(debuggerCallFrame, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->lastLine());
+            debugger->didExecuteProgram(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->lastLine());
     }
 
     if (Profiler* profiler = *Profiler::enabledProfilerReference()) {
         if (callFrame->callee())
             profiler->didExecute(callFrame, callFrame->callee());
         else
-            profiler->didExecute(callFrame, codeBlock->ownerNode()->sourceURL(), codeBlock->ownerNode()->lineNo());
+            profiler->didExecute(callFrame, codeBlock->ownerExecutable()->sourceURL(), codeBlock->ownerExecutable()->lineNo());
     }
 
     // If this call frame created an activation or an 'arguments' object, tear it off.
     if (oldCodeBlock->codeType() == FunctionCode && oldCodeBlock->needsFullScopeChain()) {
-        while (!scopeChain->object->isObject(&JSActivation::info))
+        while (!scopeChain->object->inherits(&JSActivation::info))
             scopeChain = scopeChain->pop();
         static_cast<JSActivation*>(scopeChain->object)->copyRegisters(callFrame->optionalCalleeArguments());
     } else if (Arguments* arguments = callFrame->optionalCalleeArguments()) {
@@ -559,8 +518,8 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV
                     exception->putWithAttributes(callFrame, Identifier(callFrame, expressionEndOffsetPropertyName), jsNumber(callFrame, divotPoint + endOffset), ReadOnly | DontDelete);
                 } else
                     exception->putWithAttributes(callFrame, Identifier(callFrame, "line"), jsNumber(callFrame, codeBlock->lineNumberForBytecodeOffset(callFrame, bytecodeOffset)), ReadOnly | DontDelete);
-                exception->putWithAttributes(callFrame, Identifier(callFrame, "sourceId"), jsNumber(callFrame, codeBlock->ownerNode()->sourceID()), ReadOnly | DontDelete);
-                exception->putWithAttributes(callFrame, Identifier(callFrame, "sourceURL"), jsOwnedString(callFrame, codeBlock->ownerNode()->sourceURL()), ReadOnly | DontDelete);
+                exception->putWithAttributes(callFrame, Identifier(callFrame, "sourceId"), jsNumber(callFrame, codeBlock->ownerExecutable()->sourceID()), ReadOnly | DontDelete);
+                exception->putWithAttributes(callFrame, Identifier(callFrame, "sourceURL"), jsOwnedString(callFrame, codeBlock->ownerExecutable()->sourceURL()), ReadOnly | DontDelete);
             }
             
             if (exception->isWatchdogException()) {
@@ -574,7 +533,8 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV
 
     if (Debugger* debugger = callFrame->dynamicGlobalObject()->debugger()) {
         DebuggerCallFrame debuggerCallFrame(callFrame, exceptionValue);
-        debugger->exception(debuggerCallFrame, codeBlock->ownerNode()->sourceID(), codeBlock->lineNumberForBytecodeOffset(callFrame, bytecodeOffset));
+        bool hasHandler = codeBlock->handlerForBytecodeOffset(bytecodeOffset);
+        debugger->exception(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->lineNumberForBytecodeOffset(callFrame, bytecodeOffset), hasHandler);
     }
 
     // If we throw in the middle of a call instruction, we need to notify
@@ -584,7 +544,7 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV
 #if !ENABLE(JIT)
         if (isCallBytecode(codeBlock->instructions()[bytecodeOffset].u.opcode))
             profiler->didExecute(callFrame, callFrame->r(codeBlock->instructions()[bytecodeOffset + 2].u.operand).jsValue());
-        else if (codeBlock->instructions()[bytecodeOffset + 8].u.opcode == getOpcode(op_construct))
+        else if (codeBlock->instructions().size() > (bytecodeOffset + 8) && codeBlock->instructions()[bytecodeOffset + 8].u.opcode == getOpcode(op_construct))
             profiler->didExecute(callFrame, callFrame->r(codeBlock->instructions()[bytecodeOffset + 10].u.operand).jsValue());
 #else
         int functionRegisterIndex;
@@ -614,7 +574,7 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV
     return handler;
 }
 
-JSValue Interpreter::execute(ProgramNode* programNode, CallFrame* callFrame, ScopeChainNode* scopeChain, JSObject* thisObj, JSValue* exception)
+JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, ScopeChainNode* scopeChain, JSObject* thisObj, JSValue* exception)
 {
     ASSERT(!scopeChain->globalData->exception);
 
@@ -625,7 +585,7 @@ JSValue Interpreter::execute(ProgramNode* programNode, CallFrame* callFrame, Sco
         }
     }
 
-    CodeBlock* codeBlock = &programNode->bytecode(scopeChain);
+    CodeBlock* codeBlock = &program->bytecode(callFrame, scopeChain);
 
     Register* oldEnd = m_registerFile.end();
     Register* newEnd = oldEnd + codeBlock->m_numParameters + RegisterFile::CallFrameHeaderSize + codeBlock->m_numCalleeRegisters;
@@ -634,7 +594,7 @@ JSValue Interpreter::execute(ProgramNode* programNode, CallFrame* callFrame, Sco
         return jsNull();
     }
 
-    DynamicGlobalObjectScope globalObjectScope(callFrame, scopeChain->globalObject());
+    DynamicGlobalObjectScope globalObjectScope(callFrame, scopeChain->globalObject);
 
     JSGlobalObject* lastGlobalObject = m_registerFile.globalObject();
     JSGlobalObject* globalObject = callFrame->dynamicGlobalObject();
@@ -649,15 +609,15 @@ JSValue Interpreter::execute(ProgramNode* programNode, CallFrame* callFrame, Sco
 
     Profiler** profiler = Profiler::enabledProfilerReference();
     if (*profiler)
-        (*profiler)->willExecute(newCallFrame, programNode->sourceURL(), programNode->lineNo());
+        (*profiler)->willExecute(newCallFrame, program->sourceURL(), program->lineNo());
 
     JSValue result;
     {
-        SamplingTool::CallRecord callRecord(m_sampler);
+        SamplingTool::CallRecord callRecord(m_sampler.get());
 
         m_reentryDepth++;
 #if ENABLE(JIT)
-        result = programNode->jitCode(scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
+        result = program->jitCode(newCallFrame, scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
 #else
         result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
 #endif
@@ -665,7 +625,7 @@ JSValue Interpreter::execute(ProgramNode* programNode, CallFrame* callFrame, Sco
     }
 
     if (*profiler)
-        (*profiler)->didExecute(callFrame, programNode->sourceURL(), programNode->lineNo());
+        (*profiler)->didExecute(callFrame, program->sourceURL(), program->lineNo());
 
     if (m_reentryDepth && lastGlobalObject && globalObject != lastGlobalObject)
         lastGlobalObject->copyGlobalsTo(m_registerFile);
@@ -675,7 +635,7 @@ JSValue Interpreter::execute(ProgramNode* programNode, CallFrame* callFrame, Sco
     return result;
 }
 
-JSValue Interpreter::execute(FunctionBodyNode* functionBodyNode, CallFrame* callFrame, JSFunction* function, JSObject* thisObj, const ArgList& args, ScopeChainNode* scopeChain, JSValue* exception)
+JSValue Interpreter::execute(FunctionExecutable* functionExecutable, CallFrame* callFrame, JSFunction* function, JSObject* thisObj, const ArgList& args, ScopeChainNode* scopeChain, JSValue* exception)
 {
     ASSERT(!scopeChain->globalData->exception);
 
@@ -694,7 +654,7 @@ JSValue Interpreter::execute(FunctionBodyNode* functionBodyNode, CallFrame* call
         return jsNull();
     }
 
-    DynamicGlobalObjectScope globalObjectScope(callFrame, callFrame->globalData().dynamicGlobalObject ? callFrame->globalData().dynamicGlobalObject : scopeChain->globalObject());
+    DynamicGlobalObjectScope globalObjectScope(callFrame, scopeChain->globalObject);
 
     CallFrame* newCallFrame = CallFrame::create(oldEnd);
     size_t dst = 0;
@@ -703,7 +663,7 @@ JSValue Interpreter::execute(FunctionBodyNode* functionBodyNode, CallFrame* call
     for (ArgList::const_iterator it = args.begin(); it != end; ++it)
         newCallFrame->r(++dst) = *it;
 
-    CodeBlock* codeBlock = &functionBodyNode->bytecode(scopeChain);
+    CodeBlock* codeBlock = &functionExecutable->bytecode(callFrame, scopeChain);
     newCallFrame = slideRegisterWindowForCall(codeBlock, &m_registerFile, newCallFrame, argc + RegisterFile::CallFrameHeaderSize, argc);
     if (UNLIKELY(!newCallFrame)) {
         *exception = createStackOverflowError(callFrame);
@@ -719,11 +679,11 @@ JSValue Interpreter::execute(FunctionBodyNode* functionBodyNode, CallFrame* call
 
     JSValue result;
     {
-        SamplingTool::CallRecord callRecord(m_sampler);
+        SamplingTool::CallRecord callRecord(m_sampler.get());
 
         m_reentryDepth++;
 #if ENABLE(JIT)
-        result = functionBodyNode->jitCode(scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
+        result = functionExecutable->jitCode(newCallFrame, scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
 #else
         result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
 #endif
@@ -737,7 +697,7 @@ JSValue Interpreter::execute(FunctionBodyNode* functionBodyNode, CallFrame* call
     return result;
 }
 
-CallFrameClosure Interpreter::prepareForRepeatCall(FunctionBodyNode* functionBodyNode, CallFrame* callFrame, JSFunction* function, int argCount, ScopeChainNode* scopeChain, JSValue* exception)
+CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* FunctionExecutable, CallFrame* callFrame, JSFunction* function, int argCount, ScopeChainNode* scopeChain, JSValue* exception)
 {
     ASSERT(!scopeChain->globalData->exception);
     
@@ -761,7 +721,7 @@ CallFrameClosure Interpreter::prepareForRepeatCall(FunctionBodyNode* functionBod
     for (int i = 0; i < argc; ++i)
         newCallFrame->r(++dst) = jsUndefined();
     
-    CodeBlock* codeBlock = &functionBodyNode->bytecode(scopeChain);
+    CodeBlock* codeBlock = &FunctionExecutable->bytecode(callFrame, scopeChain);
     newCallFrame = slideRegisterWindowForCall(codeBlock, &m_registerFile, newCallFrame, argc + RegisterFile::CallFrameHeaderSize, argc);
     if (UNLIKELY(!newCallFrame)) {
         *exception = createStackOverflowError(callFrame);
@@ -771,10 +731,10 @@ CallFrameClosure Interpreter::prepareForRepeatCall(FunctionBodyNode* functionBod
     // a 0 codeBlock indicates a built-in caller
     newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag(), 0, argc, function);
 #if ENABLE(JIT)
-    functionBodyNode->jitCode(scopeChain);
+    FunctionExecutable->jitCode(newCallFrame, scopeChain);
 #endif
 
-    CallFrameClosure result = { callFrame, newCallFrame, function, functionBodyNode, scopeChain->globalData, oldEnd, scopeChain, codeBlock->m_numParameters, argc };
+    CallFrameClosure result = { callFrame, newCallFrame, function, FunctionExecutable, scopeChain->globalData, oldEnd, scopeChain, codeBlock->m_numParameters, argc };
     return result;
 }
 
@@ -787,11 +747,11 @@ JSValue Interpreter::execute(CallFrameClosure& closure, JSValue* exception)
     
     JSValue result;
     {
-        SamplingTool::CallRecord callRecord(m_sampler);
+        SamplingTool::CallRecord callRecord(m_sampler.get());
         
         m_reentryDepth++;
 #if ENABLE(JIT)
-        result = closure.functionBody->generatedJITCode().execute(&m_registerFile, closure.newCallFrame, closure.globalData, exception);
+        result = closure.functionExecutable->generatedJITCode().execute(&m_registerFile, closure.newCallFrame, closure.globalData, exception);
 #else
         result = privateExecute(Normal, &m_registerFile, closure.newCallFrame, exception);
 #endif
@@ -808,12 +768,12 @@ void Interpreter::endRepeatCall(CallFrameClosure& closure)
     m_registerFile.shrink(closure.oldEnd);
 }
 
-JSValue Interpreter::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* thisObj, ScopeChainNode* scopeChain, JSValue* exception)
+JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObject* thisObj, ScopeChainNode* scopeChain, JSValue* exception)
 {
-    return execute(evalNode, callFrame, thisObj, m_registerFile.size() + evalNode->bytecode(scopeChain).m_numParameters + RegisterFile::CallFrameHeaderSize, scopeChain, exception);
+    return execute(eval, callFrame, thisObj, m_registerFile.size() + eval->bytecode(callFrame, scopeChain).m_numParameters + RegisterFile::CallFrameHeaderSize, scopeChain, exception);
 }
 
-JSValue Interpreter::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* thisObj, int globalRegisterOffset, ScopeChainNode* scopeChain, JSValue* exception)
+JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObject* thisObj, int globalRegisterOffset, ScopeChainNode* scopeChain, JSValue* exception)
 {
     ASSERT(!scopeChain->globalData->exception);
 
@@ -824,9 +784,9 @@ JSValue Interpreter::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject*
         }
     }
 
-    DynamicGlobalObjectScope globalObjectScope(callFrame, callFrame->globalData().dynamicGlobalObject ? callFrame->globalData().dynamicGlobalObject : scopeChain->globalObject());
+    DynamicGlobalObjectScope globalObjectScope(callFrame, scopeChain->globalObject);
 
-    EvalCodeBlock* codeBlock = &evalNode->bytecode(scopeChain);
+    EvalCodeBlock* codeBlock = &eval->bytecode(callFrame, scopeChain);
 
     JSVariableObject* variableObject;
     for (ScopeChainNode* node = scopeChain; ; node = node->next) {
@@ -841,21 +801,20 @@ JSValue Interpreter::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject*
 
         BatchedTransitionOptimizer optimizer(variableObject);
 
-        const DeclarationStacks::VarStack& varStack = codeBlock->ownerNode()->varStack();
-        DeclarationStacks::VarStack::const_iterator varStackEnd = varStack.end();
-        for (DeclarationStacks::VarStack::const_iterator it = varStack.begin(); it != varStackEnd; ++it) {
-            const Identifier& ident = (*it).first;
+        unsigned numVariables = codeBlock->numVariables();
+        for (unsigned i = 0; i < numVariables; ++i) {
+            const Identifier& ident = codeBlock->variable(i);
             if (!variableObject->hasProperty(callFrame, ident)) {
                 PutPropertySlot slot;
                 variableObject->put(callFrame, ident, jsUndefined(), slot);
             }
         }
 
-        const DeclarationStacks::FunctionStack& functionStack = codeBlock->ownerNode()->functionStack();
-        DeclarationStacks::FunctionStack::const_iterator functionStackEnd = functionStack.end();
-        for (DeclarationStacks::FunctionStack::const_iterator it = functionStack.begin(); it != functionStackEnd; ++it) {
+        int numFunctions = codeBlock->numberOfFunctionDecls();
+        for (int i = 0; i < numFunctions; ++i) {
+            FunctionExecutable* function = codeBlock->functionDecl(i);
             PutPropertySlot slot;
-            variableObject->put(callFrame, (*it)->m_ident, (*it)->makeFunction(callFrame, scopeChain), slot);
+            variableObject->put(callFrame, function->name(), function->make(callFrame, scopeChain), slot);
         }
 
     }
@@ -878,15 +837,15 @@ JSValue Interpreter::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject*
 
     Profiler** profiler = Profiler::enabledProfilerReference();
     if (*profiler)
-        (*profiler)->willExecute(newCallFrame, evalNode->sourceURL(), evalNode->lineNo());
+        (*profiler)->willExecute(newCallFrame, eval->sourceURL(), eval->lineNo());
 
     JSValue result;
     {
-        SamplingTool::CallRecord callRecord(m_sampler);
+        SamplingTool::CallRecord callRecord(m_sampler.get());
 
         m_reentryDepth++;
 #if ENABLE(JIT)
-        result = evalNode->jitCode(scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
+        result = eval->jitCode(newCallFrame, scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
 #else
         result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
 #endif
@@ -894,7 +853,7 @@ JSValue Interpreter::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject*
     }
 
     if (*profiler)
-        (*profiler)->didExecute(callFrame, evalNode->sourceURL(), evalNode->lineNo());
+        (*profiler)->didExecute(callFrame, eval->sourceURL(), eval->lineNo());
 
     m_registerFile.shrink(oldEnd);
     return result;
@@ -908,22 +867,22 @@ NEVER_INLINE void Interpreter::debug(CallFrame* callFrame, DebugHookID debugHook
 
     switch (debugHookID) {
         case DidEnterCallFrame:
-            debugger->callEvent(callFrame, callFrame->codeBlock()->ownerNode()->sourceID(), firstLine);
+            debugger->callEvent(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), firstLine);
             return;
         case WillLeaveCallFrame:
-            debugger->returnEvent(callFrame, callFrame->codeBlock()->ownerNode()->sourceID(), lastLine);
+            debugger->returnEvent(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine);
             return;
         case WillExecuteStatement:
-            debugger->atStatement(callFrame, callFrame->codeBlock()->ownerNode()->sourceID(), firstLine);
+            debugger->atStatement(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), firstLine);
             return;
         case WillExecuteProgram:
-            debugger->willExecuteProgram(callFrame, callFrame->codeBlock()->ownerNode()->sourceID(), firstLine);
+            debugger->willExecuteProgram(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), firstLine);
             return;
         case DidExecuteProgram:
-            debugger->didExecuteProgram(callFrame, callFrame->codeBlock()->ownerNode()->sourceID(), lastLine);
+            debugger->didExecuteProgram(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine);
             return;
         case DidReachBreakpoint:
-            debugger->didReachBreakpoint(callFrame, callFrame->codeBlock()->ownerNode()->sourceID(), lastLine);
+            debugger->didReachBreakpoint(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine);
             return;
     }
 }
@@ -931,10 +890,10 @@ NEVER_INLINE void Interpreter::debug(CallFrame* callFrame, DebugHookID debugHook
 #if USE(INTERPRETER)
 NEVER_INLINE ScopeChainNode* Interpreter::createExceptionScope(CallFrame* callFrame, const Instruction* vPC)
 {
-    int dst = (++vPC)->u.operand;
+    int dst = vPC[1].u.operand;
     CodeBlock* codeBlock = callFrame->codeBlock();
-    Identifier& property = codeBlock->identifier((++vPC)->u.operand);
-    JSValue value = callFrame->r((++vPC)->u.operand).jsValue();
+    Identifier& property = codeBlock->identifier(vPC[2].u.operand);
+    JSValue value = callFrame->r(vPC[3].u.operand).jsValue();
     JSObject* scope = new (callFrame) JSStaticScopeObject(callFrame, property, value, DontDelete);
     callFrame->r(dst) = JSValue(scope);
 
@@ -986,22 +945,20 @@ NEVER_INLINE void Interpreter::tryCachePutByID(CallFrame* callFrame, CodeBlock*
         return;
     }
 
-    StructureChain* protoChain = structure->prototypeChain(callFrame);
-    if (!protoChain->isCacheable()) {
-        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);
+
         vPC[0] = getOpcode(op_put_by_id_transition);
         vPC[4] = structure->previousID();
         vPC[5] = structure;
-        vPC[6] = protoChain;
+        vPC[6] = structure->prototypeChain(callFrame);
         vPC[7] = slot.cachedOffset();
         codeBlock->refStructures(vPC);
         return;
@@ -1114,15 +1071,9 @@ NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock*
         return;
     }
 
-    StructureChain* protoChain = structure->prototypeChain(callFrame);
-    if (!protoChain->isCacheable()) {
-        vPC[0] = getOpcode(op_get_by_id_generic);
-        return;
-    }
-
     vPC[0] = getOpcode(op_get_by_id_chain);
     vPC[4] = structure;
-    vPC[5] = protoChain;
+    vPC[5] = structure->prototypeChain(callFrame);
     vPC[6] = count;
     vPC[7] = offset;
     codeBlock->refStructures(vPC);
@@ -1224,10 +1175,10 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            Constructs a new empty Object instance using the original
            constructor, and puts the result in register dst.
         */
-        int dst = (++vPC)->u.operand;
+        int dst = vPC[1].u.operand;
         callFrame->r(dst) = JSValue(constructEmptyObject(callFrame));
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_new_object);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_new_array) {
@@ -1238,13 +1189,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            The array will contain argCount elements with values
            taken from registers starting at register firstArg.
         */
-        int dst = (++vPC)->u.operand;
-        int firstArg = (++vPC)->u.operand;
-        int argCount = (++vPC)->u.operand;
+        int dst = vPC[1].u.operand;
+        int firstArg = vPC[2].u.operand;
+        int argCount = vPC[3].u.operand;
         ArgList args(callFrame->registers() + firstArg, argCount);
         callFrame->r(dst) = JSValue(constructArray(callFrame, args));
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_new_array);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_new_regexp) {
@@ -1254,11 +1205,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            constructor from regexp regExp, and puts the result in
            register dst.
         */
-        int dst = (++vPC)->u.operand;
-        int regExp = (++vPC)->u.operand;
-        callFrame->r(dst) = JSValue(new (globalData) RegExpObject(callFrame->scopeChain()->globalObject()->regExpStructure(), callFrame->codeBlock()->regexp(regExp)));
+        int dst = vPC[1].u.operand;
+        int regExp = vPC[2].u.operand;
+        callFrame->r(dst) = JSValue(new (globalData) RegExpObject(callFrame->scopeChain()->globalObject->regExpStructure(), callFrame->codeBlock()->regexp(regExp)));
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_new_regexp);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_mov) {
@@ -1266,11 +1217,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
 
            Copies register src to register dst.
         */
-        int dst = (++vPC)->u.operand;
-        int src = (++vPC)->u.operand;
+        int dst = vPC[1].u.operand;
+        int src = vPC[2].u.operand;
         callFrame->r(dst) = callFrame->r(src);
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_mov);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_eq) {
@@ -1280,9 +1231,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            as with the ECMAScript '==' operator, and puts the result
            as a boolean in register dst.
         */
-        int dst = (++vPC)->u.operand;
-        JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
-        JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
+        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->r(dst) = jsBoolean(src1.asInt32() == src2.asInt32());
         else {
@@ -1291,7 +1242,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
             callFrame->r(dst) = result;
         }
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_eq);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_eq_null) {
@@ -1300,17 +1251,17 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            Checks whether register src is null, as with the ECMAScript '!='
            operator, and puts the result as a boolean in register dst.
         */
-        int dst = (++vPC)->u.operand;
-        JSValue src = callFrame->r((++vPC)->u.operand).jsValue();
+        int dst = vPC[1].u.operand;
+        JSValue src = callFrame->r(vPC[2].u.operand).jsValue();
 
         if (src.isUndefinedOrNull()) {
             callFrame->r(dst) = jsBoolean(true);
-            ++vPC;
+            vPC += OPCODE_LENGTH(op_eq_null);
             NEXT_INSTRUCTION();
         }
         
         callFrame->r(dst) = jsBoolean(src.isCell() && src.asCell()->structure()->typeInfo().masqueradesAsUndefined());
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_eq_null);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_neq) {
@@ -1320,9 +1271,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            equal, as with the ECMAScript '!=' operator, and puts the
            result as a boolean in register dst.
         */
-        int dst = (++vPC)->u.operand;
-        JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
-        JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
+        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->r(dst) = jsBoolean(src1.asInt32() != src2.asInt32());
         else {
@@ -1331,7 +1282,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
             callFrame->r(dst) = result;
         }
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_neq);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_neq_null) {
@@ -1340,17 +1291,17 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            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)->u.operand;
-        JSValue src = callFrame->r((++vPC)->u.operand).jsValue();
+        int dst = vPC[1].u.operand;
+        JSValue src = callFrame->r(vPC[2].u.operand).jsValue();
 
         if (src.isUndefinedOrNull()) {
             callFrame->r(dst) = jsBoolean(false);
-            ++vPC;
+            vPC += OPCODE_LENGTH(op_neq_null);
             NEXT_INSTRUCTION();
         }
         
         callFrame->r(dst) = jsBoolean(!src.isCell() || !asCell(src)->structure()->typeInfo().masqueradesAsUndefined());
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_neq_null);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_stricteq) {
@@ -1360,12 +1311,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            equal, as with the ECMAScript '===' operator, and puts the
            result as a boolean in register dst.
         */
-        int dst = (++vPC)->u.operand;
-        JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
-        JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
-        callFrame->r(dst) = jsBoolean(JSValue::strictEqual(src1, src2));
+        int dst = vPC[1].u.operand;
+        JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
+        JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
+        callFrame->r(dst) = jsBoolean(JSValue::strictEqual(callFrame, src1, src2));
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_stricteq);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_nstricteq) {
@@ -1375,12 +1326,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            strictly equal, as with the ECMAScript '!==' operator, and
            puts the result as a boolean in register dst.
         */
-        int dst = (++vPC)->u.operand;
-        JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
-        JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
-        callFrame->r(dst) = jsBoolean(!JSValue::strictEqual(src1, src2));
+        int dst = vPC[1].u.operand;
+        JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
+        JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
+        callFrame->r(dst) = jsBoolean(!JSValue::strictEqual(callFrame, src1, src2));
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_nstricteq);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_less) {
@@ -1390,14 +1341,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            with the ECMAScript '<' operator, and puts the result as
            a boolean in register dst.
         */
-        int dst = (++vPC)->u.operand;
-        JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
-        JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
+        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(callFrame, src1, src2));
         CHECK_FOR_EXCEPTION();
         callFrame->r(dst) = result;
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_less);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_lesseq) {
@@ -1407,14 +1358,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            register src2, as with the ECMAScript '<=' operator, and
            puts the result as a boolean in register dst.
         */
-        int dst = (++vPC)->u.operand;
-        JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
-        JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
+        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(callFrame, src1, src2));
         CHECK_FOR_EXCEPTION();
         callFrame->r(dst) = result;
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_lesseq);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_pre_inc) {
@@ -1423,7 +1374,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            Converts register srcDst to number, adds one, and puts the result
            back in register srcDst.
         */
-        int srcDst = (++vPC)->u.operand;
+        int srcDst = vPC[1].u.operand;
         JSValue v = callFrame->r(srcDst).jsValue();
         if (v.isInt32() && v.asInt32() < INT_MAX)
             callFrame->r(srcDst) = jsNumber(callFrame, v.asInt32() + 1);
@@ -1433,7 +1384,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
             callFrame->r(srcDst) = result;
         }
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_pre_inc);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_pre_dec) {
@@ -1442,7 +1393,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            Converts register srcDst to number, subtracts one, and puts the result
            back in register srcDst.
         */
-        int srcDst = (++vPC)->u.operand;
+        int srcDst = vPC[1].u.operand;
         JSValue v = callFrame->r(srcDst).jsValue();
         if (v.isInt32() && v.asInt32() > INT_MIN)
             callFrame->r(srcDst) = jsNumber(callFrame, v.asInt32() - 1);
@@ -1452,7 +1403,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
             callFrame->r(srcDst) = result;
         }
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_pre_dec);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_post_inc) {
@@ -1462,8 +1413,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            written to register dst, and the number plus one is written
            back to register srcDst.
         */
-        int dst = (++vPC)->u.operand;
-        int srcDst = (++vPC)->u.operand;
+        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->r(srcDst) = jsNumber(callFrame, v.asInt32() + 1);
@@ -1475,7 +1426,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
             callFrame->r(dst) = number;
         }
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_post_inc);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_post_dec) {
@@ -1485,8 +1436,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            written to register dst, and the number minus one is written
            back to register srcDst.
         */
-        int dst = (++vPC)->u.operand;
-        int srcDst = (++vPC)->u.operand;
+        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->r(srcDst) = jsNumber(callFrame, v.asInt32() - 1);
@@ -1498,7 +1449,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
             callFrame->r(dst) = number;
         }
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_post_dec);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_to_jsnumber) {
@@ -1507,8 +1458,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            Converts register src to number, and puts the result
            in register dst.
         */
-        int dst = (++vPC)->u.operand;
-        int src = (++vPC)->u.operand;
+        int dst = vPC[1].u.operand;
+        int src = vPC[2].u.operand;
 
         JSValue srcVal = callFrame->r(src).jsValue();
 
@@ -1520,7 +1471,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
             callFrame->r(dst) = result;
         }
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_to_jsnumber);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_negate) {
@@ -1529,8 +1480,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            Converts register src to number, negates it, and puts the
            result in register dst.
         */
-        int dst = (++vPC)->u.operand;
-        JSValue src = callFrame->r((++vPC)->u.operand).jsValue();
+        int dst = vPC[1].u.operand;
+        JSValue src = callFrame->r(vPC[2].u.operand).jsValue();
         if (src.isInt32() && src.asInt32())
             callFrame->r(dst) = jsNumber(callFrame, -src.asInt32());
         else {
@@ -1539,7 +1490,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
             callFrame->r(dst) = result;
         }
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_negate);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_add) {
@@ -1549,17 +1500,17 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            in register dst. (JS add may be string concatenation or
            numeric add, depending on the types of the operands.)
         */
-        int dst = (++vPC)->u.operand;
-        JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
-        JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
-        if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | src2.asInt32() & 0xc0000000)) // no overflow
+        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->r(dst) = jsNumber(callFrame, src1.asInt32() + src2.asInt32());
         else {
             JSValue result = jsAdd(callFrame, src1, src2);
             CHECK_FOR_EXCEPTION();
             callFrame->r(dst) = result;
         }
-        vPC += 2;
+        vPC += OPCODE_LENGTH(op_add);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_mul) {
@@ -1568,9 +1519,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            Multiplies register src1 and register src2 (converted to
            numbers), and puts the product in register dst.
         */
-        int dst = (++vPC)->u.operand;
-        JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
-        JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
+        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->r(dst) = jsNumber(callFrame, src1.asInt32() * src2.asInt32());
         else {
@@ -1579,7 +1530,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
             callFrame->r(dst) = result;
         }
 
-        vPC += 2;
+        vPC += OPCODE_LENGTH(op_mul);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_div) {
@@ -1589,15 +1540,15 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            register divisor (converted to number), and puts the
            quotient in register dst.
         */
-        int dst = (++vPC)->u.operand;
-        JSValue dividend = callFrame->r((++vPC)->u.operand).jsValue();
-        JSValue divisor = callFrame->r((++vPC)->u.operand).jsValue();
+        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(callFrame, dividend.toNumber(callFrame) / divisor.toNumber(callFrame));
         CHECK_FOR_EXCEPTION();
         callFrame->r(dst) = result;
 
-        vPC += 2;
+        vPC += OPCODE_LENGTH(op_div);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_mod) {
@@ -1607,15 +1558,15 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            register divisor (converted to number), and puts the
            remainder in register dst.
         */
-        int dst = (++vPC)->u.operand;
-        JSValue dividend = callFrame->r((++vPC)->u.operand).jsValue();
-        JSValue divisor = callFrame->r((++vPC)->u.operand).jsValue();
+        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(callFrame, dividend.asInt32() % divisor.asInt32());
             ASSERT(result);
             callFrame->r(dst) = result;
-            ++vPC;
+            vPC += OPCODE_LENGTH(op_mod);
             NEXT_INSTRUCTION();
         }
 
@@ -1626,7 +1577,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         JSValue result = jsNumber(callFrame, fmod(d1, d2));
         CHECK_FOR_EXCEPTION();
         callFrame->r(dst) = result;
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_mod);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_sub) {
@@ -1636,17 +1587,17 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            src1 (converted to number), and puts the difference in
            register dst.
         */
-        int dst = (++vPC)->u.operand;
-        JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
-        JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
-        if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | src2.asInt32() & 0xc0000000)) // no overflow
+        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->r(dst) = jsNumber(callFrame, src1.asInt32() - src2.asInt32());
         else {
             JSValue result = jsNumber(callFrame, src1.toNumber(callFrame) - src2.toNumber(callFrame));
             CHECK_FOR_EXCEPTION();
             callFrame->r(dst) = result;
         }
-        vPC += 2;
+        vPC += OPCODE_LENGTH(op_sub);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_lshift) {
@@ -1656,9 +1607,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            register shift (converted to uint32), and puts the result
            in register dst.
         */
-        int dst = (++vPC)->u.operand;
-        JSValue val = callFrame->r((++vPC)->u.operand).jsValue();
-        JSValue shift = callFrame->r((++vPC)->u.operand).jsValue();
+        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->r(dst) = jsNumber(callFrame, val.asInt32() << (shift.asInt32() & 0x1f));
@@ -1668,7 +1619,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
             callFrame->r(dst) = result;
         }
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_lshift);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_rshift) {
@@ -1678,9 +1629,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            to int32) by register shift (converted to
            uint32), and puts the result in register dst.
         */
-        int dst = (++vPC)->u.operand;
-        JSValue val = callFrame->r((++vPC)->u.operand).jsValue();
-        JSValue shift = callFrame->r((++vPC)->u.operand).jsValue();
+        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->r(dst) = jsNumber(callFrame, val.asInt32() >> (shift.asInt32() & 0x1f));
@@ -1690,7 +1641,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
             callFrame->r(dst) = result;
         }
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_rshift);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_urshift) {
@@ -1700,9 +1651,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            to uint32) by register shift (converted to
            uint32), and puts the result in register dst.
         */
-        int dst = (++vPC)->u.operand;
-        JSValue val = callFrame->r((++vPC)->u.operand).jsValue();
-        JSValue shift = callFrame->r((++vPC)->u.operand).jsValue();
+        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->r(dst) = jsNumber(callFrame, val.asInt32() >> (shift.asInt32() & 0x1f));
         else {
@@ -1711,7 +1662,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
             callFrame->r(dst) = result;
         }
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_urshift);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_bitand) {
@@ -1721,9 +1672,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            and register src2 (converted to int32), and puts the result
            in register dst.
         */
-        int dst = (++vPC)->u.operand;
-        JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
-        JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
+        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->r(dst) = jsNumber(callFrame, src1.asInt32() & src2.asInt32());
         else {
@@ -1732,7 +1683,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
             callFrame->r(dst) = result;
         }
 
-        vPC += 2;
+        vPC += OPCODE_LENGTH(op_bitand);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_bitxor) {
@@ -1742,9 +1693,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            and register src2 (converted to int32), and puts the result
            in register dst.
         */
-        int dst = (++vPC)->u.operand;
-        JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
-        JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
+        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->r(dst) = jsNumber(callFrame, src1.asInt32() ^ src2.asInt32());
         else {
@@ -1753,7 +1704,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
             callFrame->r(dst) = result;
         }
 
-        vPC += 2;
+        vPC += OPCODE_LENGTH(op_bitxor);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_bitor) {
@@ -1763,9 +1714,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            and register src2 (converted to int32), and puts the
            result in register dst.
         */
-        int dst = (++vPC)->u.operand;
-        JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
-        JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
+        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->r(dst) = jsNumber(callFrame, src1.asInt32() | src2.asInt32());
         else {
@@ -1774,7 +1725,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
             callFrame->r(dst) = result;
         }
 
-        vPC += 2;
+        vPC += OPCODE_LENGTH(op_bitor);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_bitnot) {
@@ -1783,8 +1734,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            Computes bitwise NOT of register src1 (converted to int32),
            and puts the result in register dst.
         */
-        int dst = (++vPC)->u.operand;
-        JSValue src = callFrame->r((++vPC)->u.operand).jsValue();
+        int dst = vPC[1].u.operand;
+        JSValue src = callFrame->r(vPC[2].u.operand).jsValue();
         if (src.isInt32())
             callFrame->r(dst) = jsNumber(callFrame, ~src.asInt32());
         else {
@@ -1792,7 +1743,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
             CHECK_FOR_EXCEPTION();
             callFrame->r(dst) = result;
         }
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_bitnot);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_not) {
@@ -1801,13 +1752,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            Computes logical NOT of register src (converted to
            boolean), and puts the result in register dst.
         */
-        int dst = (++vPC)->u.operand;
-        int src = (++vPC)->u.operand;
+        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->r(dst) = result;
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_not);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_instanceof) {
@@ -1837,7 +1788,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         CHECK_FOR_EXCEPTION();
         callFrame->r(dst) = jsBoolean(result);
 
-        vPC += 5;
+        vPC += OPCODE_LENGTH(op_instanceof);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_typeof) {
@@ -1846,11 +1797,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            Determines the type string for src according to ECMAScript
            rules, and puts the result in register dst.
         */
-        int dst = (++vPC)->u.operand;
-        int src = (++vPC)->u.operand;
+        int dst = vPC[1].u.operand;
+        int src = vPC[2].u.operand;
         callFrame->r(dst) = JSValue(jsTypeStringForValue(callFrame, callFrame->r(src).jsValue()));
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_typeof);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_is_undefined) {
@@ -1860,12 +1811,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            the ECMAScript rules is "undefined", and puts the result
            in register dst.
         */
-        int dst = (++vPC)->u.operand;
-        int src = (++vPC)->u.operand;
+        int dst = vPC[1].u.operand;
+        int src = vPC[2].u.operand;
         JSValue v = callFrame->r(src).jsValue();
         callFrame->r(dst) = jsBoolean(v.isCell() ? v.asCell()->structure()->typeInfo().masqueradesAsUndefined() : v.isUndefined());
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_is_undefined);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_is_boolean) {
@@ -1875,11 +1826,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            the ECMAScript rules is "boolean", and puts the result
            in register dst.
         */
-        int dst = (++vPC)->u.operand;
-        int src = (++vPC)->u.operand;
+        int dst = vPC[1].u.operand;
+        int src = vPC[2].u.operand;
         callFrame->r(dst) = jsBoolean(callFrame->r(src).jsValue().isBoolean());
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_is_boolean);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_is_number) {
@@ -1889,11 +1840,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            the ECMAScript rules is "number", and puts the result
            in register dst.
         */
-        int dst = (++vPC)->u.operand;
-        int src = (++vPC)->u.operand;
+        int dst = vPC[1].u.operand;
+        int src = vPC[2].u.operand;
         callFrame->r(dst) = jsBoolean(callFrame->r(src).jsValue().isNumber());
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_is_number);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_is_string) {
@@ -1903,11 +1854,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            the ECMAScript rules is "string", and puts the result
            in register dst.
         */
-        int dst = (++vPC)->u.operand;
-        int src = (++vPC)->u.operand;
+        int dst = vPC[1].u.operand;
+        int src = vPC[2].u.operand;
         callFrame->r(dst) = jsBoolean(callFrame->r(src).jsValue().isString());
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_is_string);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_is_object) {
@@ -1917,11 +1868,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            the ECMAScript rules is "object", and puts the result
            in register dst.
         */
-        int dst = (++vPC)->u.operand;
-        int src = (++vPC)->u.operand;
+        int dst = vPC[1].u.operand;
+        int src = vPC[2].u.operand;
         callFrame->r(dst) = jsBoolean(jsIsObjectType(callFrame->r(src).jsValue()));
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_is_object);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_is_function) {
@@ -1931,11 +1882,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            the ECMAScript rules is "function", and puts the result
            in register dst.
         */
-        int dst = (++vPC)->u.operand;
-        int src = (++vPC)->u.operand;
+        int dst = vPC[1].u.operand;
+        int src = vPC[2].u.operand;
         callFrame->r(dst) = jsBoolean(jsIsFunctionType(callFrame->r(src).jsValue()));
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_is_function);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_in) {
@@ -1947,9 +1898,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            Raises an exception if register constructor is not an
            object.
         */
-        int dst = (++vPC)->u.operand;
-        int property = (++vPC)->u.operand;
-        int base = (++vPC)->u.operand;
+        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, callFrame->codeBlock(), vPC, baseVal, exceptionValue))
@@ -1968,7 +1919,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
             callFrame->r(dst) = jsBoolean(baseObj->hasProperty(callFrame, property));
         }
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_in);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_resolve) {
@@ -1981,7 +1932,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         if (UNLIKELY(!resolve(callFrame, vPC, exceptionValue)))
             goto vm_throw;
 
-        vPC += 3;
+        vPC += OPCODE_LENGTH(op_resolve);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_resolve_skip) {
@@ -1994,7 +1945,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         if (UNLIKELY(!resolveSkip(callFrame, vPC, exceptionValue)))
             goto vm_throw;
 
-        vPC += 4;
+        vPC += OPCODE_LENGTH(op_resolve_skip);
 
         NEXT_INSTRUCTION();
     }
@@ -2009,7 +1960,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         if (UNLIKELY(!resolveGlobal(callFrame, vPC, exceptionValue)))
             goto vm_throw;
         
-        vPC += 6;
+        vPC += OPCODE_LENGTH(op_resolve_global);
         
         NEXT_INSTRUCTION();
     }
@@ -2018,13 +1969,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
 
            Gets the global var at global slot index and places it in register dst.
          */
-        int dst = (++vPC)->u.operand;
-        JSGlobalObject* scope = static_cast<JSGlobalObject*>((++vPC)->u.jsCell);
+        int dst = vPC[1].u.operand;
+        JSGlobalObject* scope = static_cast<JSGlobalObject*>(vPC[2].u.jsCell);
         ASSERT(scope->isGlobalObject());
-        int index = (++vPC)->u.operand;
+        int index = vPC[3].u.operand;
 
         callFrame->r(dst) = scope->registerAt(index);
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_get_global_var);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_put_global_var) {
@@ -2032,13 +1983,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
          
            Puts value into global slot index.
          */
-        JSGlobalObject* scope = static_cast<JSGlobalObject*>((++vPC)->u.jsCell);
+        JSGlobalObject* scope = static_cast<JSGlobalObject*>(vPC[1].u.jsCell);
         ASSERT(scope->isGlobalObject());
-        int index = (++vPC)->u.operand;
-        int value = (++vPC)->u.operand;
+        int index = vPC[2].u.operand;
+        int value = vPC[3].u.operand;
         
         scope->registerAt(index) = JSValue(callFrame->r(value).jsValue());
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_put_global_var);
         NEXT_INSTRUCTION();
     }            
     DEFINE_OPCODE(op_get_scoped_var) {
@@ -2047,9 +1998,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
          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)->u.operand;
-        int index = (++vPC)->u.operand;
-        int skip = (++vPC)->u.operand + callFrame->codeBlock()->needsFullScopeChain();
+        int dst = vPC[1].u.operand;
+        int index = vPC[2].u.operand;
+        int skip = vPC[3].u.operand + callFrame->codeBlock()->needsFullScopeChain();
 
         ScopeChainNode* scopeChain = callFrame->scopeChain();
         ScopeChainIterator iter = scopeChain->begin();
@@ -2063,16 +2014,16 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         ASSERT((*iter)->isVariableObject());
         JSVariableObject* scope = static_cast<JSVariableObject*>(*iter);
         callFrame->r(dst) = scope->registerAt(index);
-        ++vPC;
+        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)->u.operand;
-        int skip = (++vPC)->u.operand + callFrame->codeBlock()->needsFullScopeChain();
-        int value = (++vPC)->u.operand;
+        int index = vPC[1].u.operand;
+        int skip = vPC[2].u.operand + callFrame->codeBlock()->needsFullScopeChain();
+        int value = vPC[3].u.operand;
 
         ScopeChainNode* scopeChain = callFrame->scopeChain();
         ScopeChainIterator iter = scopeChain->begin();
@@ -2086,7 +2037,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         ASSERT((*iter)->isVariableObject());
         JSVariableObject* scope = static_cast<JSVariableObject*>(*iter);
         scope->registerAt(index) = JSValue(callFrame->r(value).jsValue());
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_put_scoped_var);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_resolve_base) {
@@ -2099,7 +2050,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         */
         resolveBase(callFrame, vPC);
 
-        vPC += 3;
+        vPC += OPCODE_LENGTH(op_resolve_base);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_resolve_with_base) {
@@ -2117,7 +2068,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         if (UNLIKELY(!resolveBaseAndProperty(callFrame, vPC, exceptionValue)))
             goto vm_throw;
 
-        vPC += 4;
+        vPC += OPCODE_LENGTH(op_resolve_with_base);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_get_by_id) {
@@ -2140,7 +2091,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         tryCacheGetByID(callFrame, codeBlock, vPC, baseValue, ident, slot);
 
         callFrame->r(dst) = result;
-        vPC += 8;
+        vPC += OPCODE_LENGTH(op_get_by_id);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_get_by_id_self) {
@@ -2166,7 +2117,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
                 ASSERT(baseObject->get(callFrame, callFrame->codeBlock()->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset));
                 callFrame->r(dst) = JSValue(baseObject->getDirectOffset(offset));
 
-                vPC += 8;
+                vPC += OPCODE_LENGTH(op_get_by_id_self);
                 NEXT_INSTRUCTION();
             }
         }
@@ -2201,7 +2152,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
                     ASSERT(baseValue.get(callFrame, callFrame->codeBlock()->identifier(vPC[3].u.operand)) == protoObject->getDirectOffset(offset));
                     callFrame->r(dst) = JSValue(protoObject->getDirectOffset(offset));
 
-                    vPC += 8;
+                    vPC += OPCODE_LENGTH(op_get_by_id_proto);
                     NEXT_INSTRUCTION();
                 }
             }
@@ -2214,14 +2165,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         // Polymorphic self access caching currently only supported when JITting.
         ASSERT_NOT_REACHED();
         // This case of the switch must not be empty, else (op_get_by_id_self_list == op_get_by_id_chain)!
-        vPC += 8;
+        vPC += OPCODE_LENGTH(op_get_by_id_self_list);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_get_by_id_proto_list) {
         // Polymorphic prototype access caching currently only supported when JITting.
         ASSERT_NOT_REACHED();
         // This case of the switch must not be empty, else (op_get_by_id_proto_list == op_get_by_id_chain)!
-        vPC += 8;
+        vPC += OPCODE_LENGTH(op_get_by_id_proto_list);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_get_by_id_chain) {
@@ -2257,7 +2208,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
                         ASSERT(baseValue.get(callFrame, callFrame->codeBlock()->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset));
                         callFrame->r(dst) = JSValue(baseObject->getDirectOffset(offset));
 
-                        vPC += 8;
+                        vPC += OPCODE_LENGTH(op_get_by_id_chain);
                         NEXT_INSTRUCTION();
                     }
 
@@ -2287,7 +2238,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         CHECK_FOR_EXCEPTION();
 
         callFrame->r(dst) = result;
-        vPC += 8;
+        vPC += OPCODE_LENGTH(op_get_by_id_generic);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_get_array_length) {
@@ -2303,7 +2254,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         if (LIKELY(isJSArray(globalData, baseValue))) {
             int dst = vPC[1].u.operand;
             callFrame->r(dst) = jsNumber(callFrame, asArray(baseValue)->length());
-            vPC += 8;
+            vPC += OPCODE_LENGTH(op_get_array_length);
             NEXT_INSTRUCTION();
         }
 
@@ -2322,8 +2273,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         JSValue baseValue = callFrame->r(base).jsValue();
         if (LIKELY(isJSString(globalData, baseValue))) {
             int dst = vPC[1].u.operand;
-            callFrame->r(dst) = jsNumber(callFrame, asString(baseValue)->value().size());
-            vPC += 8;
+            callFrame->r(dst) = jsNumber(callFrame, asString(baseValue)->length());
+            vPC += OPCODE_LENGTH(op_get_string_length);
             NEXT_INSTRUCTION();
         }
 
@@ -2353,7 +2304,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
 
         tryCachePutByID(callFrame, codeBlock, vPC, baseValue, slot);
 
-        vPC += 8;
+        vPC += OPCODE_LENGTH(op_put_by_id);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_put_by_id_transition) {
@@ -2398,7 +2349,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
                 ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(callFrame->codeBlock()->identifier(vPC[2].u.operand))) == offset);
                 baseObject->putDirectOffset(offset, callFrame->r(value).jsValue());
 
-                vPC += 8;
+                vPC += OPCODE_LENGTH(op_put_by_id_transition);
                 NEXT_INSTRUCTION();
             }
         }
@@ -2433,7 +2384,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
                 ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(callFrame->codeBlock()->identifier(vPC[2].u.operand))) == offset);
                 baseObject->putDirectOffset(offset, callFrame->r(value).jsValue());
 
-                vPC += 8;
+                vPC += OPCODE_LENGTH(op_put_by_id_replace);
                 NEXT_INSTRUCTION();
             }
         }
@@ -2460,7 +2411,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         baseValue.put(callFrame, ident, callFrame->r(value).jsValue(), slot);
         CHECK_FOR_EXCEPTION();
 
-        vPC += 8;
+        vPC += OPCODE_LENGTH(op_put_by_id_generic);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_del_by_id) {
@@ -2471,16 +2422,43 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            boolean indicating success (if true) or failure (if false)
            to register dst.
         */
-        int dst = (++vPC)->u.operand;
-        int base = (++vPC)->u.operand;
-        int property = (++vPC)->u.operand;
+        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 = callFrame->codeBlock()->identifier(property);
         JSValue result = jsBoolean(baseObj->deleteProperty(callFrame, ident));
         CHECK_FOR_EXCEPTION();
         callFrame->r(dst) = result;
-        ++vPC;
+        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->r(dst) = asObject(baseValue)->getDirectOffset(offset);
+            vPC += OPCODE_LENGTH(op_get_by_pname);
+            NEXT_INSTRUCTION();
+        }
+        Identifier propertyName(callFrame, subscript.toString(callFrame));
+        result = baseValue.get(callFrame, propertyName);
+        CHECK_FOR_EXCEPTION();
+        callFrame->r(dst) = result;
+        vPC += OPCODE_LENGTH(op_get_by_pname);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_get_by_val) {
@@ -2491,9 +2469,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            in register dst. property is nominally converted to string
            but numbers are treated more efficiently.
         */
-        int dst = (++vPC)->u.operand;
-        int base = (++vPC)->u.operand;
-        int property = (++vPC)->u.operand;
+        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();
@@ -2509,7 +2487,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
                 else
                     result = jsArray->JSArray::get(callFrame, i);
             } else if (isJSString(globalData, baseValue) && asString(baseValue)->canGetIndex(i))
-                result = asString(baseValue)->getIndex(&callFrame->globalData(), i);
+                result = asString(baseValue)->getIndex(callFrame, i);
             else if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i))
                 result = asByteArray(baseValue)->getIndex(callFrame, i);
             else
@@ -2521,7 +2499,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
 
         CHECK_FOR_EXCEPTION();
         callFrame->r(dst) = result;
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_get_by_val);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_put_by_val) {
@@ -2535,9 +2513,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            Unlike many opcodes, this one does not write any output to
            the register file.
         */
-        int base = (++vPC)->u.operand;
-        int property = (++vPC)->u.operand;
-        int value = (++vPC)->u.operand;
+        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();
@@ -2571,7 +2549,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         }
 
         CHECK_FOR_EXCEPTION();
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_put_by_val);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_del_by_val) {
@@ -2582,9 +2560,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            boolean indicating success (if true) or failure (if false)
            to register dst.
         */
-        int dst = (++vPC)->u.operand;
-        int base = (++vPC)->u.operand;
-        int property = (++vPC)->u.operand;
+        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
 
@@ -2602,7 +2580,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
 
         CHECK_FOR_EXCEPTION();
         callFrame->r(dst) = result;
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_del_by_val);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_put_by_index) {
@@ -2617,13 +2595,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
 
            This opcode is mainly used to initialize array literals.
         */
-        int base = (++vPC)->u.operand;
-        unsigned property = (++vPC)->u.operand;
-        int value = (++vPC)->u.operand;
+        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;
+        vPC += OPCODE_LENGTH(op_put_by_index);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_loop) {
@@ -2638,7 +2616,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
 #if ENABLE(OPCODE_STATS)
         OpcodeStats::resetLastInstruction();
 #endif
-        int target = (++vPC)->u.operand;
+        int target = vPC[1].u.operand;
         CHECK_FOR_TIMEOUT();
         vPC += target;
         NEXT_INSTRUCTION();
@@ -2652,7 +2630,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
 #if ENABLE(OPCODE_STATS)
         OpcodeStats::resetLastInstruction();
 #endif
-        int target = (++vPC)->u.operand;
+        int target = vPC[1].u.operand;
 
         vPC += target;
         NEXT_INSTRUCTION();
@@ -2666,15 +2644,35 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            Additionally this loop instruction may terminate JS execution is
            the JS timeout is reached.
          */
-        int cond = (++vPC)->u.operand;
-        int target = (++vPC)->u.operand;
+        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;
+        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) {
@@ -2683,14 +2681,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            Jumps to offset target from the current instruction, if and
            only if register cond converts to boolean as true.
         */
-        int cond = (++vPC)->u.operand;
-        int target = (++vPC)->u.operand;
+        int cond = vPC[1].u.operand;
+        int target = vPC[2].u.operand;
         if (callFrame->r(cond).jsValue().toBoolean(callFrame)) {
             vPC += target;
             NEXT_INSTRUCTION();
         }
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_jtrue);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_jfalse) {
@@ -2699,14 +2697,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            Jumps to offset target from the current instruction, if and
            only if register cond converts to boolean as false.
         */
-        int cond = (++vPC)->u.operand;
-        int target = (++vPC)->u.operand;
+        int cond = vPC[1].u.operand;
+        int target = vPC[2].u.operand;
         if (!callFrame->r(cond).jsValue().toBoolean(callFrame)) {
             vPC += target;
             NEXT_INSTRUCTION();
         }
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_jfalse);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_jeq_null) {
@@ -2715,8 +2713,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            Jumps to offset target from the current instruction, if and
            only if register src is null.
         */
-        int src = (++vPC)->u.operand;
-        int target = (++vPC)->u.operand;
+        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())) {
@@ -2724,7 +2722,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
             NEXT_INSTRUCTION();
         }
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_jeq_null);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_jneq_null) {
@@ -2733,16 +2731,16 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            Jumps to offset target from the current instruction, if and
            only if register src is not null.
         */
-        int src = (++vPC)->u.operand;
-        int target = (++vPC)->u.operand;
+        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())) {
+        if (!srcValue.isUndefinedOrNull() && (!srcValue.isCell() || !srcValue.asCell()->structure()->typeInfo().masqueradesAsUndefined())) {
             vPC += target;
             NEXT_INSTRUCTION();
         }
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_jneq_null);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_jneq_ptr) {
@@ -2751,16 +2749,16 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            Jumps to offset target from the current instruction, if the value r is equal
            to ptr, using pointer equality.
          */
-        int src = (++vPC)->u.operand;
-        JSValue ptr = JSValue((++vPC)->u.jsCell);
-        int target = (++vPC)->u.operand;
+        int src = vPC[1].u.operand;
+        JSValue ptr = JSValue(vPC[2].u.jsCell);
+        int target = vPC[3].u.operand;
         JSValue srcValue = callFrame->r(src).jsValue();
         if (srcValue != ptr) {
             vPC += target;
             NEXT_INSTRUCTION();
         }
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_jneq_ptr);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_loop_if_less) {
@@ -2774,9 +2772,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            Additionally this loop instruction may terminate JS execution is
            the JS timeout is reached.
          */
-        JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
-        JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
-        int target = (++vPC)->u.operand;
+        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(callFrame, src1, src2);
         CHECK_FOR_EXCEPTION();
@@ -2787,7 +2785,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
             NEXT_INSTRUCTION();
         }
         
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_loop_if_less);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_loop_if_lesseq) {
@@ -2801,9 +2799,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            Additionally this loop instruction may terminate JS execution is
            the JS timeout is reached.
         */
-        JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
-        JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
-        int target = (++vPC)->u.operand;
+        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(callFrame, src1, src2);
         CHECK_FOR_EXCEPTION();
@@ -2814,7 +2812,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
             NEXT_INSTRUCTION();
         }
         
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_loop_if_lesseq);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_jnless) {
@@ -2825,9 +2823,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            target from the current instruction, if and only if the 
            result of the comparison is false.
         */
-        JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
-        JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
-        int target = (++vPC)->u.operand;
+        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(callFrame, src1, src2);
         CHECK_FOR_EXCEPTION();
@@ -2837,7 +2835,30 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
             NEXT_INSTRUCTION();
         }
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_jnless);
+        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(callFrame, src1, src2);
+        CHECK_FOR_EXCEPTION();
+        
+        if (result) {
+            vPC += target;
+            NEXT_INSTRUCTION();
+        }
+
+        vPC += OPCODE_LENGTH(op_jless);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_jnlesseq) {
@@ -2848,9 +2869,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            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)->u.operand).jsValue();
-        JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
-        int target = (++vPC)->u.operand;
+        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(callFrame, src1, src2);
         CHECK_FOR_EXCEPTION();
@@ -2860,7 +2881,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
             NEXT_INSTRUCTION();
         }
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_jnlesseq);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_switch_imm) {
@@ -2872,9 +2893,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            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)->u.operand;
-        int defaultOffset = (++vPC)->u.operand;
-        JSValue scrutinee = callFrame->r((++vPC)->u.operand).jsValue();
+        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 += callFrame->codeBlock()->immediateSwitchJumpTable(tableIndex).offsetForValue(scrutinee.asInt32(), defaultOffset);
         else {
@@ -2896,13 +2917,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            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)->u.operand;
-        int defaultOffset = (++vPC)->u.operand;
-        JSValue scrutinee = callFrame->r((++vPC)->u.operand).jsValue();
+        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 {
-            UString::Rep* value = asString(scrutinee)->value().rep();
+            UString::Rep* value = asString(scrutinee)->value(callFrame).rep();
             if (value->size() != 1)
                 vPC += defaultOffset;
             else
@@ -2919,13 +2940,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            jump table, then the value associated with the string is used as the 
            jump offset, otherwise defaultOffset is used.
          */
-        int tableIndex = (++vPC)->u.operand;
-        int defaultOffset = (++vPC)->u.operand;
-        JSValue scrutinee = callFrame->r((++vPC)->u.operand).jsValue();
+        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 += callFrame->codeBlock()->stringSwitchJumpTable(tableIndex).offsetForValue(asString(scrutinee)->value().rep(), defaultOffset);
+            vPC += callFrame->codeBlock()->stringSwitchJumpTable(tableIndex).offsetForValue(asString(scrutinee)->value(callFrame).rep(), defaultOffset);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_new_func) {
@@ -2936,12 +2957,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            constructor, using the rules for function declarations, and
            puts the result in register dst.
         */
-        int dst = (++vPC)->u.operand;
-        int func = (++vPC)->u.operand;
+        int dst = vPC[1].u.operand;
+        int func = vPC[2].u.operand;
 
-        callFrame->r(dst) = JSValue(callFrame->codeBlock()->function(func)->makeFunction(callFrame, callFrame->scopeChain()));
+        callFrame->r(dst) = JSValue(callFrame->codeBlock()->functionDecl(func)->make(callFrame, callFrame->scopeChain()));
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_new_func);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_new_func_exp) {
@@ -2952,12 +2973,27 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            constructor, using the rules for function expressions, and
            puts the result in register dst.
         */
-        int dst = (++vPC)->u.operand;
-        int func = (++vPC)->u.operand;
+        int dst = vPC[1].u.operand;
+        int funcIndex = vPC[2].u.operand;
 
-        callFrame->r(dst) = JSValue(callFrame->codeBlock()->functionExpression(func)->makeFunction(callFrame, callFrame->scopeChain()));
+        FunctionExecutable* function = callFrame->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 = new (callFrame) JSStaticScopeObject(callFrame, function->name(), func, ReadOnly | DontDelete);
+            func->scope().push(functionScopeObject);
+        }
 
-        ++vPC;
+        callFrame->r(dst) = JSValue(func);
+
+        vPC += OPCODE_LENGTH(op_new_func_exp);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_call_eval) {
@@ -2982,7 +3018,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         Register* newCallFrame = callFrame->registers() + registerOffset;
         Register* argv = newCallFrame - RegisterFile::CallFrameHeaderSize - argCount;
         JSValue thisValue = argv[0].jsValue();
-        JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject();
+        JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject;
 
         if (thisValue == globalObject && funcVal == globalObject->evalFunction()) {
             JSValue result = callEval(callFrame, registerFile, argv, argCount, registerOffset, exceptionValue);
@@ -2990,7 +3026,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
                 goto vm_throw;
             callFrame->r(dst) = result;
 
-            vPC += 5;
+            vPC += OPCODE_LENGTH(op_call_eval);
             NEXT_INSTRUCTION();
         }
 
@@ -3021,8 +3057,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
 
         if (callType == CallTypeJS) {
             ScopeChainNode* callDataScopeChain = callData.js.scopeChain;
-            FunctionBodyNode* functionBodyNode = callData.js.functionBody;
-            CodeBlock* newCodeBlock = &functionBodyNode->bytecode(callDataScopeChain);
+            CodeBlock* newCodeBlock = &callData.js.functionExecutable->bytecode(callFrame, callDataScopeChain);
 
             CallFrame* previousCallFrame = callFrame;
 
@@ -3058,14 +3093,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
 
             JSValue returnValue;
             {
-                SamplingTool::HostCallRecord callRecord(m_sampler);
+                SamplingTool::HostCallRecord callRecord(m_sampler.get());
                 returnValue = callData.native.function(newCallFrame, asObject(v), thisValue, args);
             }
             CHECK_FOR_EXCEPTION();
 
             callFrame->r(dst) = returnValue;
 
-            vPC += 5;
+            vPC += OPCODE_LENGTH(op_call);
             NEXT_INSTRUCTION();
         }
 
@@ -3075,22 +3110,24 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         goto vm_throw;
     }
     DEFINE_OPCODE(op_load_varargs) {
-        int argCountDst = (++vPC)->u.operand;
-        int argsOffset = (++vPC)->u.operand;
+        int argCountDst = vPC[1].u.operand;
+        int argsOffset = vPC[2].u.operand;
         
         JSValue arguments = callFrame->r(argsOffset).jsValue();
-        int32_t argCount = 0;
+        uint32_t argCount = 0;
         if (!arguments) {
             argCount = (uint32_t)(callFrame->argumentCount()) - 1;
+            argCount = min<uint32_t>(argCount, Arguments::MaxArguments);
             int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize;
             Register* newEnd = callFrame->registers() + sizeDelta;
             if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) {
                 exceptionValue = createStackOverflowError(callFrame);
                 goto vm_throw;
             }
-            int32_t expectedParams = callFrame->callee()->body()->parameterCount();
-            int32_t inplaceArgs = min(argCount, expectedParams);
-            int32_t i = 0;
+            ASSERT(!callFrame->callee()->isHostFunction());
+            uint32_t expectedParams = callFrame->callee()->jsExecutable()->parameterCount();
+            uint32_t inplaceArgs = min(argCount, expectedParams);
+            uint32_t i = 0;
             Register* argStore = callFrame->registers() + argsOffset;
 
             // First step is to copy the "expected" parameters from their normal location relative to the callframe
@@ -3107,6 +3144,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
             if (asObject(arguments)->classInfo() == &Arguments::info) {
                 Arguments* args = asArguments(arguments);
                 argCount = args->numProvidedArguments(callFrame);
+                argCount = min<uint32_t>(argCount, Arguments::MaxArguments);
                 int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize;
                 Register* newEnd = callFrame->registers() + sizeDelta;
                 if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) {
@@ -3117,6 +3155,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
             } else if (isJSArray(&callFrame->globalData(), arguments)) {
                 JSArray* array = asArray(arguments);
                 argCount = array->length();
+                argCount = min<uint32_t>(argCount, Arguments::MaxArguments);
                 int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize;
                 Register* newEnd = callFrame->registers() + sizeDelta;
                 if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) {
@@ -3127,6 +3166,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
             } else if (asObject(arguments)->inherits(&JSArray::info)) {
                 JSObject* argObject = asObject(arguments);
                 argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
+                argCount = min<uint32_t>(argCount, Arguments::MaxArguments);
                 int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize;
                 Register* newEnd = callFrame->registers() + sizeDelta;
                 if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) {
@@ -3134,7 +3174,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
                     goto vm_throw;
                 }
                 Register* argsBuffer = callFrame->registers() + argsOffset;
-                for (int32_t i = 0; i < argCount; ++i) {
+                for (uint32_t i = 0; i < argCount; ++i) {
                     argsBuffer[i] = asObject(arguments)->get(callFrame, i);
                     CHECK_FOR_EXCEPTION();
                 }
@@ -3147,7 +3187,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         }
         CHECK_FOR_EXCEPTION();
         callFrame->r(argCountDst) = Register::withInt(argCount + 1);
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_load_varargs);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_call_varargs) {
@@ -3175,8 +3215,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         
         if (callType == CallTypeJS) {
             ScopeChainNode* callDataScopeChain = callData.js.scopeChain;
-            FunctionBodyNode* functionBodyNode = callData.js.functionBody;
-            CodeBlock* newCodeBlock = &functionBodyNode->bytecode(callDataScopeChain);
+            CodeBlock* newCodeBlock = &callData.js.functionExecutable->bytecode(callFrame, callDataScopeChain);
             
             CallFrame* previousCallFrame = callFrame;
             
@@ -3212,14 +3251,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
             
             JSValue returnValue;
             {
-                SamplingTool::HostCallRecord callRecord(m_sampler);
+                SamplingTool::HostCallRecord callRecord(m_sampler.get());
                 returnValue = callData.native.function(newCallFrame, asObject(v), thisValue, args);
             }
             CHECK_FOR_EXCEPTION();
             
             callFrame->r(dst) = returnValue;
             
-            vPC += 5;
+            vPC += OPCODE_LENGTH(op_call_varargs);
             NEXT_INSTRUCTION();
         }
         
@@ -3241,12 +3280,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            This opcode should only be used immediately before op_ret.
         */
 
-        int src = (++vPC)->u.operand;
+        int src = vPC[1].u.operand;
         ASSERT(callFrame->codeBlock()->needsFullScopeChain());
 
         asActivation(callFrame->r(src).jsValue())->copyRegisters(callFrame->optionalCalleeArguments());
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_tear_off_activation);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_tear_off_arguments) {
@@ -3267,7 +3306,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         if (callFrame->optionalCalleeArguments())
             callFrame->optionalCalleeArguments()->copyRegisters();
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_tear_off_arguments);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_ret) {
@@ -3280,7 +3319,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            register base to those of the calling function.
         */
 
-        int result = (++vPC)->u.operand;
+        int result = vPC[1].u.operand;
 
         if (callFrame->codeBlock()->needsFullScopeChain())
             callFrame->scopeChain()->deref();
@@ -3315,7 +3354,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         for (size_t count = codeBlock->m_numVars; i < count; ++i)
             callFrame->r(i) = jsUndefined();
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_enter);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_enter_with_activation) {
@@ -3337,12 +3376,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         for (size_t count = codeBlock->m_numVars; i < count; ++i)
             callFrame->r(i) = jsUndefined();
 
-        int dst = (++vPC)->u.operand;
-        JSActivation* activation = new (globalData) JSActivation(callFrame, static_cast<FunctionBodyNode*>(codeBlock->ownerNode()));
+        int dst = vPC[1].u.operand;
+        JSActivation* activation = new (globalData) JSActivation(callFrame, static_cast<FunctionExecutable*>(codeBlock->ownerExecutable()));
         callFrame->r(dst) = JSValue(activation);
         callFrame->setScopeChain(callFrame->scopeChain()->copy()->push(activation));
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_enter_with_activation);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_convert_this) {
@@ -3357,12 +3396,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            block.
         */
 
-        int thisRegister = (++vPC)->u.operand;
+        int thisRegister = vPC[1].u.operand;
         JSValue thisVal = callFrame->r(thisRegister).jsValue();
         if (thisVal.needsThisConversion())
             callFrame->r(thisRegister) = JSValue(thisVal.toThisObject(callFrame));
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_convert_this);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_init_arguments) {
@@ -3376,7 +3415,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            block.
          */
         callFrame->r(RegisterFile::ArgumentsRegister) = JSValue();
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_init_arguments);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_create_arguments) {
@@ -3392,7 +3431,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
              callFrame->setCalleeArguments(arguments);
              callFrame->r(RegisterFile::ArgumentsRegister) = JSValue(arguments);
          }
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_create_arguments);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_construct) {
@@ -3424,15 +3463,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
 
         if (constructType == ConstructTypeJS) {
             ScopeChainNode* callDataScopeChain = constructData.js.scopeChain;
-            FunctionBodyNode* functionBodyNode = constructData.js.functionBody;
-            CodeBlock* newCodeBlock = &functionBodyNode->bytecode(callDataScopeChain);
+            CodeBlock* newCodeBlock = &constructData.js.functionExecutable->bytecode(callFrame, callDataScopeChain);
 
             Structure* structure;
             JSValue prototype = callFrame->r(proto).jsValue();
             if (prototype.isObject())
                 structure = asObject(prototype)->inheritorID();
             else
-                structure = callDataScopeChain->globalObject()->emptyObjectStructure();
+                structure = callDataScopeChain->globalObject->emptyObjectStructure();
             JSObject* newObject = new (globalData) JSObject(structure);
 
             callFrame->r(thisRegister) = JSValue(newObject); // "this" value
@@ -3465,13 +3503,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
 
             JSValue returnValue;
             {
-                SamplingTool::HostCallRecord callRecord(m_sampler);
+                SamplingTool::HostCallRecord callRecord(m_sampler.get());
                 returnValue = constructData.native.function(newCallFrame, asObject(v), args);
             }
             CHECK_FOR_EXCEPTION();
             callFrame->r(dst) = JSValue(returnValue);
 
-            vPC += 7;
+            vPC += OPCODE_LENGTH(op_construct);
             NEXT_INSTRUCTION();
         }
 
@@ -3489,32 +3527,33 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
 
         int dst = vPC[1].u.operand;
         if (LIKELY(callFrame->r(dst).jsValue().isObject())) {
-            vPC += 3;
+            vPC += OPCODE_LENGTH(op_construct_verify);
             NEXT_INSTRUCTION();
         }
 
         int override = vPC[2].u.operand;
         callFrame->r(dst) = callFrame->r(override);
 
-        vPC += 3;
+        vPC += OPCODE_LENGTH(op_construct_verify);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_strcat) {
-        int dst = (++vPC)->u.operand;
-        int src = (++vPC)->u.operand;
-        int count = (++vPC)->u.operand;
+        int dst = vPC[1].u.operand;
+        int src = vPC[2].u.operand;
+        int count = vPC[3].u.operand;
 
-        callFrame->r(dst) = concatenateStrings(callFrame, &callFrame->registers()[src], count);
-        ++vPC;
+        callFrame->r(dst) = jsString(callFrame, &callFrame->registers()[src], count);
+        CHECK_FOR_EXCEPTION();
+        vPC += OPCODE_LENGTH(op_strcat);
 
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_to_primitive) {
-        int dst = (++vPC)->u.operand;
-        int src = (++vPC)->u.operand;
+        int dst = vPC[1].u.operand;
+        int src = vPC[2].u.operand;
 
         callFrame->r(dst) = callFrame->r(src).jsValue().toPrimitive(callFrame);
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_to_primitive);
 
         NEXT_INSTRUCTION();
     }
@@ -3525,7 +3564,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            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)->u.operand;
+        int scope = vPC[1].u.operand;
         JSValue v = callFrame->r(scope).jsValue();
         JSObject* o = v.toObject(callFrame);
         CHECK_FOR_EXCEPTION();
@@ -3533,7 +3572,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         callFrame->r(scope) = JSValue(o);
         callFrame->setScopeChain(callFrame->scopeChain()->push(o));
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_push_scope);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_pop_scope) {
@@ -3543,47 +3582,69 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         */
         callFrame->setScopeChain(callFrame->scopeChain()->pop());
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_pop_scope);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_get_pnames) {
-        /* get_pnames dst(r) base(r)
+        /* 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. This is not a true JavaScript value, just
-           a synthetic value used to keep the iteration state in a
-           register.
+           in register dst, initializing i and size for iteration. If
+           base is undefined or null, jumps to breakTarget.
         */
-        int dst = (++vPC)->u.operand;
-        int base = (++vPC)->u.operand;
+        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->r(dst) = JSPropertyNameIterator::create(callFrame, callFrame->r(base).jsValue());
-        ++vPC;
+        callFrame->r(dst) = jsPropertyNameIterator;
+        callFrame->r(base) = JSValue(o);
+        callFrame->r(i) = Register::withInt(0);
+        callFrame->r(size) = Register::withInt(jsPropertyNameIterator->size());
+        vPC += OPCODE_LENGTH(op_get_pnames);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_next_pname) {
-        /* next_pname dst(r) iter(r) target(offset)
+        /* next_pname dst(r) base(r) i(n) size(n) iter(r) target(offset)
 
-           Tries to copies the next name from property name list in
-           register iter. If there are names left, then copies one to
-           register dst, and jumps to offset target. If there are none
-           left, invalidates the iterator and continues to the next
+           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)->u.operand;
-        int iter = (++vPC)->u.operand;
-        int target = (++vPC)->u.operand;
+        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();
-        if (JSValue temp = it->next(callFrame)) {
-            CHECK_FOR_TIMEOUT();
-            callFrame->r(dst) = JSValue(temp);
-            vPC += target;
-            NEXT_INSTRUCTION();
+        while (callFrame->r(i).i() != callFrame->r(size).i()) {
+            JSValue key = it->get(callFrame, asObject(callFrame->r(base).jsValue()), callFrame->r(i).i());
+            callFrame->r(i) = Register::withInt(callFrame->r(i).i() + 1);
+            if (key) {
+                CHECK_FOR_TIMEOUT();
+                callFrame->r(dst) = key;
+                vPC += target;
+                NEXT_INSTRUCTION();
+            }
         }
-        it->invalidate();
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_next_pname);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_jmp_scopes) {
@@ -3593,8 +3654,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            specified by immediate number count, then jumps to offset
            target.
         */
-        int count = (++vPC)->u.operand;
-        int target = (++vPC)->u.operand;
+        int count = vPC[1].u.operand;
+        int target = vPC[2].u.operand;
 
         ScopeChainNode* tmp = callFrame->scopeChain();
         while (count--)
@@ -3617,7 +3678,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
          */
         callFrame->setScopeChain(createExceptionScope(callFrame, vPC));
 
-        vPC += 4;
+        vPC += OPCODE_LENGTH(op_push_new_scope);
         NEXT_INSTRUCTION();
     }
 #if HAVE(COMPUTED_GOTO)
@@ -3632,11 +3693,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         */
         ASSERT(exceptionValue);
         ASSERT(!globalData->exception);
-        int ex = (++vPC)->u.operand;
+        int ex = vPC[1].u.operand;
         callFrame->r(ex) = exceptionValue;
         exceptionValue = JSValue();
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_catch);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_throw) {
@@ -3650,7 +3711,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            else the script returns control to the nearest native caller.
         */
 
-        int ex = (++vPC)->u.operand;
+        int ex = vPC[1].u.operand;
         exceptionValue = callFrame->r(ex).jsValue();
 
         handler = throwException(callFrame, exceptionValue, vPC - callFrame->codeBlock()->instructions().begin(), true);
@@ -3670,14 +3731,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            constant message as the message string. The result is
            written to register dst.
         */
-        int dst = (++vPC)->u.operand;
-        int type = (++vPC)->u.operand;
-        int message = (++vPC)->u.operand;
+        int dst = vPC[1].u.operand;
+        int type = vPC[2].u.operand;
+        int message = vPC[3].u.operand;
 
         CodeBlock* codeBlock = callFrame->codeBlock();
-        callFrame->r(dst) = JSValue(Error::create(callFrame, (ErrorType)type, callFrame->r(message).jsValue().toString(callFrame), codeBlock->lineNumberForBytecodeOffset(callFrame, vPC - codeBlock->instructions().begin()), codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL()));
+        callFrame->r(dst) = JSValue(Error::create(callFrame, (ErrorType)type, callFrame->r(message).jsValue().toString(callFrame), codeBlock->lineNumberForBytecodeOffset(callFrame, vPC - codeBlock->instructions().begin()), codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL()));
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_new_error);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_end) {
@@ -3692,7 +3753,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
             ASSERT(scopeChain->refCount > 1);
             scopeChain->deref();
         }
-        int result = (++vPC)->u.operand;
+        int result = vPC[1].u.operand;
         return callFrame->r(result).jsValue();
     }
     DEFINE_OPCODE(op_put_getter) {
@@ -3706,9 +3767,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            Unlike many opcodes, this one does not write any output to
            the register file.
         */
-        int base = (++vPC)->u.operand;
-        int property = (++vPC)->u.operand;
-        int function = (++vPC)->u.operand;
+        int base = vPC[1].u.operand;
+        int property = vPC[2].u.operand;
+        int function = vPC[3].u.operand;
 
         ASSERT(callFrame->r(base).jsValue().isObject());
         JSObject* baseObj = asObject(callFrame->r(base).jsValue());
@@ -3716,7 +3777,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         ASSERT(callFrame->r(function).jsValue().isObject());
         baseObj->defineGetter(callFrame, ident, asObject(callFrame->r(function).jsValue()));
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_put_getter);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_put_setter) {
@@ -3730,17 +3791,17 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            Unlike many opcodes, this one does not write any output to
            the register file.
         */
-        int base = (++vPC)->u.operand;
-        int property = (++vPC)->u.operand;
-        int function = (++vPC)->u.operand;
+        int base = vPC[1].u.operand;
+        int property = vPC[2].u.operand;
+        int function = vPC[3].u.operand;
 
         ASSERT(callFrame->r(base).jsValue().isObject());
         JSObject* baseObj = asObject(callFrame->r(base).jsValue());
         Identifier& ident = callFrame->codeBlock()->identifier(property);
         ASSERT(callFrame->r(function).jsValue().isObject());
-        baseObj->defineSetter(callFrame, ident, asObject(callFrame->r(function).jsValue()));
+        baseObj->defineSetter(callFrame, ident, asObject(callFrame->r(function).jsValue()), 0);
 
-        ++vPC;
+        vPC += OPCODE_LENGTH(op_put_setter);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_method_check) {
@@ -3753,9 +3814,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
            Places the address of the next instruction into the retAddrDst
            register and jumps to offset target from the current instruction.
         */
-        int retAddrDst = (++vPC)->u.operand;
-        int target = (++vPC)->u.operand;
-        callFrame->r(retAddrDst) = vPC + 1;
+        int retAddrDst = vPC[1].u.operand;
+        int target = vPC[2].u.operand;
+        callFrame->r(retAddrDst) = vPC + OPCODE_LENGTH(op_jsr);
 
         vPC += target;
         NEXT_INSTRUCTION();
@@ -3767,7 +3828,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
          differs from op_jmp because the target address is stored in a
          register, not as an immediate.
         */
-        int retAddrSrc = (++vPC)->u.operand;
+        int retAddrSrc = vPC[1].u.operand;
         vPC = callFrame->r(retAddrSrc).vPC();
         NEXT_INSTRUCTION();
     }
@@ -3777,13 +3838,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
          Notifies the debugger of the current state of execution. This opcode
          is only generated while the debugger is attached.
         */
-        int debugHookID = (++vPC)->u.operand;
-        int firstLine = (++vPC)->u.operand;
-        int lastLine = (++vPC)->u.operand;
+        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;
+        vPC += OPCODE_LENGTH(op_debug);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_profile_will_call) {
@@ -3797,7 +3858,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         if (*enabledProfilerReference)
             (*enabledProfilerReference)->willExecute(callFrame, callFrame->r(function).jsValue());
 
-        vPC += 2;
+        vPC += OPCODE_LENGTH(op_profile_will_call);
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_profile_did_call) {
@@ -3811,7 +3872,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         if (*enabledProfilerReference)
             (*enabledProfilerReference)->didExecute(callFrame, callFrame->r(function).jsValue());
 
-        vPC += 2;
+        vPC += OPCODE_LENGTH(op_profile_did_call);
         NEXT_INSTRUCTION();
     }
     vm_throw: {
@@ -3850,7 +3911,7 @@ JSValue Interpreter::retrieveArguments(CallFrame* callFrame, JSFunction* functio
     CodeBlock* codeBlock = functionCallFrame->codeBlock();
     if (codeBlock->usesArguments()) {
         ASSERT(codeBlock->codeType() == FunctionCode);
-        SymbolTable& symbolTable = codeBlock->symbolTable();
+        SymbolTable& symbolTable = *codeBlock->symbolTable();
         int argumentsIndex = symbolTable.get(functionCallFrame->propertyNames().arguments.ustring().rep()).getIndex();
         if (!functionCallFrame->r(argumentsIndex).jsValue()) {
             Arguments* arguments = new (callFrame) Arguments(functionCallFrame);
@@ -3903,8 +3964,8 @@ void Interpreter::retrieveLastCaller(CallFrame* callFrame, int& lineNumber, intp
 
     unsigned bytecodeOffset = bytecodeOffsetForPC(callerFrame, callerCodeBlock, callFrame->returnPC());
     lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(callerFrame, bytecodeOffset - 1);
-    sourceID = callerCodeBlock->ownerNode()->sourceID();
-    sourceURL = callerCodeBlock->ownerNode()->sourceURL();
+    sourceID = callerCodeBlock->ownerExecutable()->sourceID();
+    sourceURL = callerCodeBlock->ownerExecutable()->sourceURL();
     function = callerFrame->callee();
 }
 
@@ -3917,4 +3978,40 @@ CallFrame* Interpreter::findFunctionCallFrame(CallFrame* callFrame, InternalFunc
     return 0;
 }
 
+void Interpreter::enableSampler()
+{
+#if ENABLE(OPCODE_SAMPLING)
+    if (!m_sampler) {
+        m_sampler.set(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