+
+#if ENABLE(JIT)
+protected:
+ virtual JSObject* compileOptimized(ExecState*, JSScope*, unsigned bytecodeIndex);
+ virtual void jettisonImpl();
+ virtual bool jitCompileImpl(ExecState*);
+ virtual CodeBlock* replacement();
+ virtual DFG::CapabilityLevel canCompileWithDFGInternal();
+#endif
+};
+
+class EvalCodeBlock : public GlobalCodeBlock {
+public:
+ EvalCodeBlock(CopyParsedBlockTag, EvalCodeBlock& other)
+ : GlobalCodeBlock(CopyParsedBlock, other)
+ {
+ }
+
+ EvalCodeBlock(EvalExecutable* ownerExecutable, UnlinkedEvalCodeBlock* unlinkedCodeBlock, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, int baseScopeDepth, PassOwnPtr<CodeBlock> alternative)
+ : GlobalCodeBlock(ownerExecutable, unlinkedCodeBlock, globalObject, baseScopeDepth, sourceProvider, 0, 1, alternative)
+ {
+ }
+
+ const Identifier& variable(unsigned index) { return unlinkedEvalCodeBlock()->variable(index); }
+ unsigned numVariables() { return unlinkedEvalCodeBlock()->numVariables(); }
+
+#if ENABLE(JIT)
+protected:
+ virtual JSObject* compileOptimized(ExecState*, JSScope*, unsigned bytecodeIndex);
+ virtual void jettisonImpl();
+ virtual bool jitCompileImpl(ExecState*);
+ virtual CodeBlock* replacement();
+ virtual DFG::CapabilityLevel canCompileWithDFGInternal();
+#endif
+
+private:
+ UnlinkedEvalCodeBlock* unlinkedEvalCodeBlock() const { return jsCast<UnlinkedEvalCodeBlock*>(unlinkedCodeBlock()); }
+};
+
+class FunctionCodeBlock : public CodeBlock {
+public:
+ FunctionCodeBlock(CopyParsedBlockTag, FunctionCodeBlock& other)
+ : CodeBlock(CopyParsedBlock, other)
+ {
+ }
+
+ FunctionCodeBlock(FunctionExecutable* ownerExecutable, UnlinkedFunctionCodeBlock* unlinkedCodeBlock, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, unsigned firstLineColumnOffset, PassOwnPtr<CodeBlock> alternative = nullptr)
+ : CodeBlock(ownerExecutable, unlinkedCodeBlock, globalObject, 0, sourceProvider, sourceOffset, firstLineColumnOffset, alternative)
+ {
+ }
+
+#if ENABLE(JIT)
+protected:
+ virtual JSObject* compileOptimized(ExecState*, JSScope*, unsigned bytecodeIndex);
+ virtual void jettisonImpl();
+ virtual bool jitCompileImpl(ExecState*);
+ virtual CodeBlock* replacement();
+ virtual DFG::CapabilityLevel canCompileWithDFGInternal();
+#endif
+};
+
+inline CodeBlock* baselineCodeBlockForInlineCallFrame(InlineCallFrame* inlineCallFrame)
+{
+ RELEASE_ASSERT(inlineCallFrame);
+ ExecutableBase* executable = inlineCallFrame->executable.get();
+ RELEASE_ASSERT(executable->structure()->classInfo() == &FunctionExecutable::s_info);
+ return static_cast<FunctionExecutable*>(executable)->baselineCodeBlockFor(inlineCallFrame->isCall ? CodeForCall : CodeForConstruct);
+}
+
+inline CodeBlock* baselineCodeBlockForOriginAndBaselineCodeBlock(const CodeOrigin& codeOrigin, CodeBlock* baselineCodeBlock)
+{
+ if (codeOrigin.inlineCallFrame)
+ return baselineCodeBlockForInlineCallFrame(codeOrigin.inlineCallFrame);
+ return baselineCodeBlock;
+}
+
+inline int CodeBlock::argumentIndexAfterCapture(size_t argument)
+{
+ if (argument >= static_cast<size_t>(symbolTable()->parameterCount()))
+ return CallFrame::argumentOffset(argument);
+
+ const SlowArgument* slowArguments = symbolTable()->slowArguments();
+ if (!slowArguments || slowArguments[argument].status == SlowArgument::Normal)
+ return CallFrame::argumentOffset(argument);
+
+ ASSERT(slowArguments[argument].status == SlowArgument::Captured);
+ return slowArguments[argument].index;
+}
+
+inline Register& ExecState::r(int index)
+{
+ CodeBlock* codeBlock = this->codeBlock();
+ if (codeBlock->isConstantRegisterIndex(index))
+ return *reinterpret_cast<Register*>(&codeBlock->constantRegister(index));
+ return this[index];
+}
+
+inline Register& ExecState::uncheckedR(int index)
+{
+ RELEASE_ASSERT(index < FirstConstantRegisterIndex);
+ return this[index];
+}
+
+#if ENABLE(DFG_JIT)
+inline bool ExecState::isInlineCallFrame()
+{
+ if (LIKELY(!codeBlock() || codeBlock()->getJITType() != JITCode::DFGJIT))
+ return false;
+ return isInlineCallFrameSlow();
+}
+#endif
+
+inline JSValue ExecState::argumentAfterCapture(size_t argument)
+{
+ if (argument >= argumentCount())
+ return jsUndefined();
+
+ if (!codeBlock())
+ return this[argumentOffset(argument)].jsValue();
+
+ return this[codeBlock()->argumentIndexAfterCapture(argument)].jsValue();
+}
+
+#if ENABLE(DFG_JIT)
+inline void DFGCodeBlocks::mark(void* candidateCodeBlock)
+{
+ // We have to check for 0 and -1 because those are used by the HashMap as markers.
+ uintptr_t value = reinterpret_cast<uintptr_t>(candidateCodeBlock);
+
+ // This checks for both of those nasty cases in one go.
+ // 0 + 1 = 1
+ // -1 + 1 = 0
+ if (value + 1 <= 1)
+ return;
+
+ HashSet<CodeBlock*>::iterator iter = m_set.find(static_cast<CodeBlock*>(candidateCodeBlock));
+ if (iter == m_set.end())
+ return;
+
+ (*iter)->m_dfgData->mayBeExecuting = true;
+}
+#endif