+ CodeBlockHash hashFor(CodeSpecializationKind) const;
+
+ NativeFunction function() { return m_function; }
+ NativeFunction constructor() { return m_constructor; }
+
+ NativeFunction nativeFunctionFor(CodeSpecializationKind kind)
+ {
+ if (kind == CodeForCall)
+ return function();
+ ASSERT(kind == CodeForConstruct);
+ return constructor();
+ }
+
+ static ptrdiff_t offsetOfNativeFunctionFor(CodeSpecializationKind kind)
+ {
+ if (kind == CodeForCall)
+ return OBJECT_OFFSETOF(NativeExecutable, m_function);
+ ASSERT(kind == CodeForConstruct);
+ return OBJECT_OFFSETOF(NativeExecutable, m_constructor);
+ }
+
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(vm, globalObject, proto, TypeInfo(CellType, StructureFlags), info()); }
+
+ DECLARE_INFO;
+
+ Intrinsic intrinsic() const;
+
+protected:
+ void finishCreation(VM& vm, PassRefPtr<JITCode> callThunk, PassRefPtr<JITCode> constructThunk, Intrinsic intrinsic)
+ {
+ Base::finishCreation(vm);
+ m_jitCodeForCall = callThunk;
+ m_jitCodeForConstruct = constructThunk;
+ m_intrinsic = intrinsic;
+ }
+
+private:
+ NativeExecutable(VM& vm, NativeFunction function, NativeFunction constructor)
+ : ExecutableBase(vm, vm.nativeExecutableStructure.get(), NUM_PARAMETERS_IS_HOST)
+ , m_function(function)
+ , m_constructor(constructor)
+ {
+ }
+
+ NativeFunction m_function;
+ NativeFunction m_constructor;
+
+ Intrinsic m_intrinsic;
+};
+
+class ScriptExecutable : public ExecutableBase {
+public:
+ typedef ExecutableBase Base;
+ static const unsigned StructureFlags = Base::StructureFlags;
+
+ static void destroy(JSCell*);
+
+ CodeBlockHash hashFor(CodeSpecializationKind) const;
+
+ const SourceCode& source() const { return m_source; }
+ intptr_t sourceID() const { return m_source.providerID(); }
+ const String& sourceURL() const { return m_source.provider()->url(); }
+ int firstLine() const { return m_firstLine; }
+ void setOverrideLineNumber(int overrideLineNumber) { m_overrideLineNumber = overrideLineNumber; }
+ bool hasOverrideLineNumber() const { return m_overrideLineNumber != -1; }
+ int overrideLineNumber() const { return m_overrideLineNumber; }
+ int lastLine() const { return m_lastLine; }
+ unsigned startColumn() const { return m_startColumn; }
+ unsigned endColumn() const { return m_endColumn; }
+ unsigned typeProfilingStartOffset() const { return m_typeProfilingStartOffset; }
+ unsigned typeProfilingEndOffset() const { return m_typeProfilingEndOffset; }
+
+ bool usesEval() const { return m_features & EvalFeature; }
+ bool usesArguments() const { return m_features & ArgumentsFeature; }
+ bool needsActivation() const { return m_hasCapturedVariables || m_features & (EvalFeature | WithFeature | CatchFeature); }
+ bool isStrictMode() const { return m_features & StrictModeFeature; }
+ ECMAMode ecmaMode() const { return isStrictMode() ? StrictMode : NotStrictMode; }
+
+ void setNeverInline(bool value) { m_neverInline = value; }
+ void setDidTryToEnterInLoop(bool value) { m_didTryToEnterInLoop = value; }
+ bool neverInline() const { return m_neverInline; }
+ bool didTryToEnterInLoop() const { return m_didTryToEnterInLoop; }
+ bool isInliningCandidate() const { return !neverInline(); }
+
+ bool* addressOfDidTryToEnterInLoop() { return &m_didTryToEnterInLoop; }
+
+ void unlinkCalls();
+
+ CodeFeatures features() const { return m_features; }
+
+ DECLARE_INFO;
+
+ void recordParse(CodeFeatures features, bool hasCapturedVariables, int firstLine, int lastLine, unsigned startColumn, unsigned endColumn)
+ {
+ m_features = features;
+ m_hasCapturedVariables = hasCapturedVariables;
+ m_firstLine = firstLine;
+ m_lastLine = lastLine;
+ ASSERT(startColumn != UINT_MAX);
+ m_startColumn = startColumn;
+ ASSERT(endColumn != UINT_MAX);
+ m_endColumn = endColumn;
+ }
+
+ void installCode(CodeBlock*);
+ RefPtr<CodeBlock> newCodeBlockFor(CodeSpecializationKind, JSFunction*, JSScope*, JSObject*& exception);
+ PassRefPtr<CodeBlock> newReplacementCodeBlockFor(CodeSpecializationKind);
+
+ JSObject* prepareForExecution(ExecState* exec, JSFunction* function, JSScope* scope, CodeSpecializationKind kind)
+ {
+ if (hasJITCodeFor(kind))
+ return 0;
+ return prepareForExecutionImpl(exec, function, scope, kind);
+ }
+
+ template <typename Functor> void forEachCodeBlock(Functor&&);
+
+private:
+ JSObject* prepareForExecutionImpl(ExecState*, JSFunction*, JSScope*, CodeSpecializationKind);
+
+protected:
+ ScriptExecutable(Structure* structure, VM& vm, const SourceCode& source, bool isInStrictContext);
+
+ void finishCreation(VM& vm)
+ {
+ Base::finishCreation(vm);
+ vm.heap.addCompiledCode(this); // Balanced by Heap::deleteUnmarkedCompiledCode().