]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - bytecode/CodeBlock.h
JavaScriptCore-584.tar.gz
[apple/javascriptcore.git] / bytecode / CodeBlock.h
index e5d78d3ea8edee610002915a7adfb4239e71ecd8..eb874cc4c17b8a39a270f3c0d746e0641c72e819 100644 (file)
 
 #include "EvalCodeCache.h"
 #include "Instruction.h"
+#include "JITCode.h"
 #include "JSGlobalObject.h"
 #include "JumpTable.h"
 #include "Nodes.h"
+#include "PtrAndFlags.h"
 #include "RegExp.h"
 #include "UString.h"
+#include <wtf/FastAllocBase.h>
 #include <wtf/RefPtr.h>
 #include <wtf/Vector.h>
 
 #include "StructureStubInfo.h"
 #endif
 
+// Register numbers used in bytecode operations have different meaning accoring to their ranges:
+//      0x80000000-0xFFFFFFFF  Negative indicies from the CallFrame pointer are entries in the call frame, see RegisterFile.h.
+//      0x00000000-0x3FFFFFFF  Forwards indices from the CallFrame pointer are local vars and temporaries with the function's callframe.
+//      0x40000000-0x7FFFFFFF  Positive indices from 0x40000000 specify entries in the constant pool on the CodeBlock.
+static const int FirstConstantRegisterIndex = 0x40000000;
+
 namespace JSC {
 
+    enum HasSeenShouldRepatch {
+        hasSeenShouldRepatch
+    };
+
     class ExecState;
 
     enum CodeType { GlobalCode, EvalCode, FunctionCode };
@@ -58,38 +71,10 @@ namespace JSC {
         uint32_t target;
         uint32_t scopeDepth;
 #if ENABLE(JIT)
-        void* nativeCode;
+        CodeLocationLabel nativeCode;
 #endif
     };
 
-#if ENABLE(JIT)
-    // The code, and the associated pool from which it was allocated.
-    struct JITCodeRef {
-        void* code;
-#ifndef NDEBUG
-        unsigned codeSize;
-#endif
-        RefPtr<ExecutablePool> executablePool;
-
-        JITCodeRef()
-            : code(0)
-#ifndef NDEBUG
-            , codeSize(0)
-#endif
-        {
-        }
-        
-        JITCodeRef(void* code, PassRefPtr<ExecutablePool> executablePool)
-            : code(code)
-#ifndef NDEBUG
-            , codeSize(0)
-#endif
-            , executablePool(executablePool)
-        {
-        }
-    };
-#endif
-
     struct ExpressionRangeInfo {
         enum {
             MaxOffset = (1 << 7) - 1, 
@@ -117,24 +102,52 @@ namespace JSC {
 #if ENABLE(JIT)
     struct CallLinkInfo {
         CallLinkInfo()
-            : callReturnLocation(0)
-            , hotPathBegin(0)
-            , hotPathOther(0)
-            , coldPathOther(0)
-            , callee(0)
+            : callee(0)
         {
         }
     
         unsigned bytecodeIndex;
-        void* callReturnLocation;
-        void* hotPathBegin;
-        void* hotPathOther;
-        void* coldPathOther;
+        CodeLocationNearCall callReturnLocation;
+        CodeLocationDataLabelPtr hotPathBegin;
+        CodeLocationNearCall hotPathOther;
+        PtrAndFlags<CodeBlock, HasSeenShouldRepatch> ownerCodeBlock;
         CodeBlock* callee;
         unsigned position;
         
         void setUnlinked() { callee = 0; }
         bool isLinked() { return callee; }
+
+        bool seenOnce()
+        {
+            return ownerCodeBlock.isFlagSet(hasSeenShouldRepatch);
+        }
+
+        void setSeen()
+        {
+            ownerCodeBlock.setFlag(hasSeenShouldRepatch);
+        }
+    };
+
+    struct MethodCallLinkInfo {
+        MethodCallLinkInfo()
+            : cachedStructure(0)
+        {
+        }
+
+        bool seenOnce()
+        {
+            return cachedPrototypeStructure.isFlagSet(hasSeenShouldRepatch);
+        }
+
+        void setSeen()
+        {
+            cachedPrototypeStructure.setFlag(hasSeenShouldRepatch);
+        }
+
+        CodeLocationCall callReturnLocation;
+        CodeLocationDataLabelPtr structureLabel;
+        Structure* cachedStructure;
+        PtrAndFlags<Structure, HasSeenShouldRepatch> cachedPrototypeStructure;
     };
 
     struct FunctionRegisterInfo {
@@ -161,14 +174,18 @@ namespace JSC {
         unsigned bytecodeOffset;
     };
 
-    struct PC {
-        PC(ptrdiff_t nativePCOffset, unsigned bytecodeIndex)
-            : nativePCOffset(nativePCOffset)
+    // This structure is used to map from a call return location
+    // (given as an offset in bytes into the JIT code) back to
+    // the bytecode index of the corresponding bytecode operation.
+    // This is then used to look up the corresponding handler.
+    struct CallReturnOffsetToBytecodeIndex {
+        CallReturnOffsetToBytecodeIndex(unsigned callReturnOffset, unsigned bytecodeIndex)
+            : callReturnOffset(callReturnOffset)
             , bytecodeIndex(bytecodeIndex)
         {
         }
 
-        ptrdiff_t nativePCOffset;
+        unsigned callReturnOffset;
         unsigned bytecodeIndex;
     };
 
@@ -176,17 +193,22 @@ namespace JSC {
 
     inline void* getStructureStubInfoReturnLocation(StructureStubInfo* structureStubInfo)
     {
-        return structureStubInfo->callReturnLocation;
+        return structureStubInfo->callReturnLocation.executableAddress();
     }
 
     inline void* getCallLinkInfoReturnLocation(CallLinkInfo* callLinkInfo)
     {
-        return callLinkInfo->callReturnLocation;
+        return callLinkInfo->callReturnLocation.executableAddress();
+    }
+
+    inline void* getMethodCallLinkInfoReturnLocation(MethodCallLinkInfo* methodCallLinkInfo)
+    {
+        return methodCallLinkInfo->callReturnLocation.executableAddress();
     }
 
-    inline ptrdiff_t getNativePCOffset(PC* pc)
+    inline unsigned getCallReturnOffset(CallReturnOffsetToBytecodeIndex* pc)
     {
-        return pc->nativePCOffset;
+        return pc->callReturnOffset;
     }
 
     // Binary chop algorithm, calls valueAtPosition on pre-sorted elements in array,
@@ -226,16 +248,27 @@ namespace JSC {
     }
 #endif
 
-    class CodeBlock {
+    struct ExceptionInfo : FastAllocBase {
+        Vector<ExpressionRangeInfo> m_expressionInfo;
+        Vector<LineInfo> m_lineInfo;
+        Vector<GetByIdExceptionInfo> m_getByIdExceptionInfo;
+
+#if ENABLE(JIT)
+        Vector<CallReturnOffsetToBytecodeIndex> m_callReturnIndexVector;
+#endif
+    };
+
+    class CodeBlock : public FastAllocBase {
         friend class JIT;
+    protected:
+        CodeBlock(ScriptExecutable* ownerExecutable, CodeType, PassRefPtr<SourceProvider>, unsigned sourceOffset, SymbolTable* symbolTable);
     public:
-        CodeBlock(ScopeNode* ownerNode, CodeType, PassRefPtr<SourceProvider>, unsigned sourceOffset);
-        ~CodeBlock();
+        virtual ~CodeBlock();
 
-        void mark();
+        void markAggregate(MarkStack&);
         void refStructures(Instruction* vPC) const;
         void derefStructures(Instruction* vPC) const;
-#if ENABLE(JIT)
+#if ENABLE(JIT_OPTIMIZE_CALL)
         void unlinkCallers();
 #endif
 
@@ -258,19 +291,9 @@ namespace JSC {
             return false;
         }
 
-        ALWAYS_INLINE bool isConstantRegisterIndex(int index)
-        {
-            return index >= m_numVars && index < m_numVars + m_numConstants;
-        }
-
-        ALWAYS_INLINE JSValuePtr getConstant(int index)
-        {
-            return m_constantRegisters[index - m_numVars].getJSValue();
-        }
-
         ALWAYS_INLINE bool isTemporaryRegisterIndex(int index)
         {
-            return index >= m_numVars + m_numConstants;
+            return index >= m_numVars;
         }
 
         HandlerInfo* handlerForBytecodeOffset(unsigned bytecodeOffset);
@@ -298,21 +321,25 @@ namespace JSC {
             m_linkedCallerList.shrink(lastPos);
         }
 
-        StructureStubInfo& getStubInfo(void* returnAddress)
+        StructureStubInfo& getStubInfo(ReturnAddressPtr returnAddress)
         {
-            return *(binaryChop<StructureStubInfo, void*, getStructureStubInfoReturnLocation>(m_structureStubInfos.begin(), m_structureStubInfos.size(), returnAddress));
+            return *(binaryChop<StructureStubInfo, void*, getStructureStubInfoReturnLocation>(m_structureStubInfos.begin(), m_structureStubInfos.size(), returnAddress.value()));
         }
 
-        CallLinkInfo& getCallLinkInfo(void* returnAddress)
+        CallLinkInfo& getCallLinkInfo(ReturnAddressPtr returnAddress)
         {
-            return *(binaryChop<CallLinkInfo, void*, getCallLinkInfoReturnLocation>(m_callLinkInfos.begin(), m_callLinkInfos.size(), returnAddress));
+            return *(binaryChop<CallLinkInfo, void*, getCallLinkInfoReturnLocation>(m_callLinkInfos.begin(), m_callLinkInfos.size(), returnAddress.value()));
         }
 
-        unsigned getBytecodeIndex(CallFrame* callFrame, void* nativePC)
+        MethodCallLinkInfo& getMethodCallLinkInfo(ReturnAddressPtr returnAddress)
+        {
+            return *(binaryChop<MethodCallLinkInfo, void*, getMethodCallLinkInfoReturnLocation>(m_methodCallLinkInfos.begin(), m_methodCallLinkInfos.size(), returnAddress.value()));
+        }
+
+        unsigned getBytecodeIndex(CallFrame* callFrame, ReturnAddressPtr returnAddress)
         {
             reparseForExceptionInfoIfNecessary(callFrame);
-            ptrdiff_t nativePCOffset = reinterpret_cast<void**>(nativePC) - reinterpret_cast<void**>(m_jitCode.code);
-            return binaryChop<PC, ptrdiff_t, getNativePCOffset>(m_exceptionInfo->m_pcVector.begin(), m_exceptionInfo->m_pcVector.size(), nativePCOffset)->bytecodeIndex;
+            return binaryChop<CallReturnOffsetToBytecodeIndex, unsigned, getCallReturnOffset>(callReturnIndexVector().begin(), callReturnIndexVector().size(), ownerExecutable()->generatedJITCode().offsetOf(returnAddress.value()))->bytecodeIndex;
         }
         
         bool functionRegisterForBytecodeOffset(unsigned bytecodeOffset, int& functionRegisterIndex);
@@ -322,17 +349,19 @@ namespace JSC {
         bool isNumericCompareFunction() { return m_isNumericCompareFunction; }
 
         Vector<Instruction>& instructions() { return m_instructions; }
+        void discardBytecode() { m_instructions.clear(); }
+
 #ifndef NDEBUG
+        unsigned instructionCount() { return m_instructionCount; }
         void setInstructionCount(unsigned instructionCount) { m_instructionCount = instructionCount; }
 #endif
 
 #if ENABLE(JIT)
-        void setJITCode(JITCodeRef& jitCode);
-        void* jitCode() { return m_jitCode.code; }
-        ExecutablePool* executablePool() { return m_jitCode.executablePool.get(); }
+        JITCode& getJITCode() { return ownerExecutable()->generatedJITCode(); }
+        ExecutablePool* executablePool() { return ownerExecutable()->getExecutablePool(); }
 #endif
 
-        ScopeNode* ownerNode() const { return m_ownerNode; }
+        ScriptExecutable* ownerExecutable() const { return m_ownerExecutable; }
 
         void setGlobalData(JSGlobalData* globalData) { m_globalData = globalData; }
 
@@ -373,6 +402,9 @@ namespace JSC {
         void addCallLinkInfo() { m_callLinkInfos.append(CallLinkInfo()); }
         CallLinkInfo& callLinkInfo(int index) { return m_callLinkInfos[index]; }
 
+        void addMethodCallLinkInfos(unsigned n) { m_methodCallLinkInfos.grow(n); }
+        MethodCallLinkInfo& methodCallLinkInfo(int index) { return m_methodCallLinkInfos[index]; }
+
         void addFunctionRegisterInfo(unsigned bytecodeOffset, int functionIndex) { createRareDataIfNecessary(); m_rareData->m_functionRegisterInfos.append(FunctionRegisterInfo(bytecodeOffset, functionIndex)); }
 #endif
 
@@ -384,6 +416,7 @@ namespace JSC {
 
         bool hasExceptionInfo() const { return m_exceptionInfo; }
         void clearExceptionInfo() { m_exceptionInfo.clear(); }
+        ExceptionInfo* extractExceptionInfo() { ASSERT(m_exceptionInfo); return m_exceptionInfo.release(); }
 
         void addExpressionInfo(const ExpressionRangeInfo& expressionInfo) { ASSERT(m_exceptionInfo); m_exceptionInfo->m_expressionInfo.append(expressionInfo); }
         void addGetByIdExceptionInfo(const GetByIdExceptionInfo& info) { ASSERT(m_exceptionInfo); m_exceptionInfo->m_getByIdExceptionInfo.append(info); }
@@ -393,7 +426,7 @@ namespace JSC {
         LineInfo& lastLineInfo() { ASSERT(m_exceptionInfo); return m_exceptionInfo->m_lineInfo.last(); }
 
 #if ENABLE(JIT)
-        Vector<PC>& pcVector() { ASSERT(m_exceptionInfo); return m_exceptionInfo->m_pcVector; }
+        Vector<CallReturnOffsetToBytecodeIndex>& callReturnIndexVector() { ASSERT(m_exceptionInfo); return m_exceptionInfo->m_callReturnIndexVector; }
 #endif
 
         // Constant Pool
@@ -404,18 +437,15 @@ namespace JSC {
 
         size_t numberOfConstantRegisters() const { return m_constantRegisters.size(); }
         void addConstantRegister(const Register& r) { return m_constantRegisters.append(r); }
-        Register& constantRegister(int index) { return m_constantRegisters[index]; }
-
-        unsigned addFunctionExpression(FuncExprNode* n) { unsigned size = m_functionExpressions.size(); m_functionExpressions.append(n); return size; }
-        FuncExprNode* functionExpression(int index) const { return m_functionExpressions[index].get(); }
-
-        unsigned addFunction(FuncDeclNode* n) { createRareDataIfNecessary(); unsigned size = m_rareData->m_functions.size(); m_rareData->m_functions.append(n); return size; }
-        FuncDeclNode* function(int index) const { ASSERT(m_rareData); return m_rareData->m_functions[index].get(); }
+        Register& constantRegister(int index) { return m_constantRegisters[index - FirstConstantRegisterIndex]; }
+        ALWAYS_INLINE bool isConstantRegisterIndex(int index) const { return index >= FirstConstantRegisterIndex; }
+        ALWAYS_INLINE JSValue getConstant(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex].jsValue(); }
 
-        bool hasFunctions() const { return m_functionExpressions.size() || (m_rareData && m_rareData->m_functions.size()); }
-
-        unsigned addUnexpectedConstant(JSValuePtr v) { createRareDataIfNecessary(); unsigned size = m_rareData->m_unexpectedConstants.size(); m_rareData->m_unexpectedConstants.append(v); return size; }
-        JSValuePtr unexpectedConstant(int index) const { ASSERT(m_rareData); return m_rareData->m_unexpectedConstants[index]; }
+        unsigned addFunctionDecl(NonNullPassRefPtr<FunctionExecutable> n) { unsigned size = m_functionDecls.size(); m_functionDecls.append(n); return size; }
+        FunctionExecutable* functionDecl(int index) { return m_functionDecls[index].get(); }
+        int numberOfFunctionDecls() { return m_functionDecls.size(); }
+        unsigned addFunctionExpr(NonNullPassRefPtr<FunctionExecutable> n) { unsigned size = m_functionExprs.size(); m_functionExprs.append(n); return size; }
+        FunctionExecutable* functionExpr(int index) { return m_functionExprs[index].get(); }
 
         unsigned addRegExp(RegExp* r) { createRareDataIfNecessary(); unsigned size = m_rareData->m_regexps.size(); m_rareData->m_regexps.append(r); return size; }
         RegExp* regexp(int index) const { ASSERT(m_rareData); return m_rareData->m_regexps[index].get(); }
@@ -436,7 +466,8 @@ namespace JSC {
         StringJumpTable& stringSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_stringSwitchJumpTables[tableIndex]; }
 
 
-        SymbolTable& symbolTable() { return m_symbolTable; }
+        SymbolTable* symbolTable() { return m_symbolTable; }
+        SharedSymbolTable* sharedSymbolTable() { ASSERT(m_codeType == FunctionCode); return static_cast<SharedSymbolTable*>(m_symbolTable); }
 
         EvalCodeCache& evalCodeCache() { createRareDataIfNecessary(); return m_rareData->m_evalCodeCache; }
 
@@ -445,17 +476,19 @@ namespace JSC {
         // FIXME: Make these remaining members private.
 
         int m_numCalleeRegisters;
-        // NOTE: numConstants holds the number of constant registers allocated
-        // by the code generator, not the number of constant registers used.
-        // (Duplicate constants are uniqued during code generation, and spare
-        // constant registers may be allocated.)
-        int m_numConstants;
         int m_numVars;
         int m_numParameters;
 
     private:
 #if !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING)
         void dump(ExecState*, const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator&) const;
+
+        CString registerName(ExecState*, int r) const;
+        void printUnaryOp(ExecState*, int location, Vector<Instruction>::const_iterator&, const char* op) const;
+        void printBinaryOp(ExecState*, int location, Vector<Instruction>::const_iterator&, const char* op) const;
+        void printConditionalJump(ExecState*, const Vector<Instruction>::const_iterator&, Vector<Instruction>::const_iterator&, int location, const char* op) const;
+        void printGetByIdOp(ExecState*, int location, Vector<Instruction>::const_iterator&, const char* op) const;
+        void printPutByIdOp(ExecState*, int location, Vector<Instruction>::const_iterator&, const char* op) const;
 #endif
 
         void reparseForExceptionInfoIfNecessary(CallFrame*);
@@ -466,16 +499,13 @@ namespace JSC {
                 m_rareData.set(new RareData);
         }
 
-        ScopeNode* m_ownerNode;
+        ScriptExecutable* m_ownerExecutable;
         JSGlobalData* m_globalData;
 
         Vector<Instruction> m_instructions;
 #ifndef NDEBUG
         unsigned m_instructionCount;
 #endif
-#if ENABLE(JIT)
-        JITCodeRef m_jitCode;
-#endif
 
         int m_thisRegister;
 
@@ -496,6 +526,7 @@ namespace JSC {
         Vector<StructureStubInfo> m_structureStubInfos;
         Vector<GlobalResolveInfo> m_globalResolveInfos;
         Vector<CallLinkInfo> m_callLinkInfos;
+        Vector<MethodCallLinkInfo> m_methodCallLinkInfos;
         Vector<CallLinkInfo*> m_linkedCallerList;
 #endif
 
@@ -504,27 +535,17 @@ namespace JSC {
         // Constant Pool
         Vector<Identifier> m_identifiers;
         Vector<Register> m_constantRegisters;
-        Vector<RefPtr<FuncExprNode> > m_functionExpressions;
-
-        SymbolTable m_symbolTable;
+        Vector<RefPtr<FunctionExecutable> > m_functionDecls;
+        Vector<RefPtr<FunctionExecutable> > m_functionExprs;
 
-        struct ExceptionInfo {
-            Vector<ExpressionRangeInfo> m_expressionInfo;
-            Vector<LineInfo> m_lineInfo;
-            Vector<GetByIdExceptionInfo> m_getByIdExceptionInfo;
+        SymbolTable* m_symbolTable;
 
-#if ENABLE(JIT)
-            Vector<PC> m_pcVector;
-#endif
-        };
         OwnPtr<ExceptionInfo> m_exceptionInfo;
 
-        struct RareData {
+        struct RareData : FastAllocBase {
             Vector<HandlerInfo> m_exceptionHandlers;
 
             // Rare Constants
-            Vector<RefPtr<FuncDeclNode> > m_functions;
-            Vector<JSValuePtr> m_unexpectedConstants;
             Vector<RefPtr<RegExp> > m_regexps;
 
             // Jump Tables
@@ -544,16 +565,16 @@ namespace JSC {
     // Program code is not marked by any function, so we make the global object
     // responsible for marking it.
 
-    class ProgramCodeBlock : public CodeBlock {
+    class GlobalCodeBlock : public CodeBlock {
     public:
-        ProgramCodeBlock(ScopeNode* ownerNode, CodeType codeType, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider)
-            : CodeBlock(ownerNode, codeType, sourceProvider, 0)
+        GlobalCodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, JSGlobalObject* globalObject)
+            : CodeBlock(ownerExecutable, codeType, sourceProvider, sourceOffset, &m_unsharedSymbolTable)
             , m_globalObject(globalObject)
         {
             m_globalObject->codeBlocks().add(this);
         }
 
-        ~ProgramCodeBlock()
+        ~GlobalCodeBlock()
         {
             if (m_globalObject)
                 m_globalObject->codeBlocks().remove(this);
@@ -563,22 +584,64 @@ namespace JSC {
 
     private:
         JSGlobalObject* m_globalObject; // For program and eval nodes, the global object that marks the constant pool.
+        SymbolTable m_unsharedSymbolTable;
     };
 
-    class EvalCodeBlock : public ProgramCodeBlock {
+    class ProgramCodeBlock : public GlobalCodeBlock {
     public:
-        EvalCodeBlock(ScopeNode* ownerNode, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, int baseScopeDepth)
-            : ProgramCodeBlock(ownerNode, EvalCode, globalObject, sourceProvider)
+        ProgramCodeBlock(ProgramExecutable* ownerExecutable, CodeType codeType, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider)
+            : GlobalCodeBlock(ownerExecutable, codeType, sourceProvider, 0, globalObject)
+        {
+        }
+    };
+
+    class EvalCodeBlock : public GlobalCodeBlock {
+    public:
+        EvalCodeBlock(EvalExecutable* ownerExecutable, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, int baseScopeDepth)
+            : GlobalCodeBlock(ownerExecutable, EvalCode, sourceProvider, 0, globalObject)
             , m_baseScopeDepth(baseScopeDepth)
         {
         }
 
         int baseScopeDepth() const { return m_baseScopeDepth; }
 
+        const Identifier& variable(unsigned index) { return m_variables[index]; }
+        unsigned numVariables() { return m_variables.size(); }
+        void adoptVariables(Vector<Identifier>& variables)
+        {
+            ASSERT(m_variables.isEmpty());
+            m_variables.swap(variables);
+        }
+
     private:
         int m_baseScopeDepth;
+        Vector<Identifier> m_variables;
     };
 
+    class FunctionCodeBlock : public CodeBlock {
+    public:
+        // Rather than using the usual RefCounted::create idiom for SharedSymbolTable we just use new
+        // as we need to initialise the CodeBlock before we could initialise any RefPtr to hold the shared
+        // symbol table, so we just pass as a raw pointer with a ref count of 1.  We then manually deref
+        // in the destructor.
+        FunctionCodeBlock(FunctionExecutable* ownerExecutable, CodeType codeType, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset)
+            : CodeBlock(ownerExecutable, codeType, sourceProvider, sourceOffset, new SharedSymbolTable)
+        {
+        }
+        ~FunctionCodeBlock()
+        {
+            sharedSymbolTable()->deref();
+        }
+    };
+
+    inline Register& ExecState::r(int index)
+    {
+        CodeBlock* codeBlock = this->codeBlock();
+        if (codeBlock->isConstantRegisterIndex(index))
+            return codeBlock->constantRegister(index);
+        return this[index];
+    }
+
 } // namespace JSC
 
 #endif // CodeBlock_h