JSMainThreadExecState.h [plain text]
#ifndef JSMainThreadExecState_h
#define JSMainThreadExecState_h
#include "InspectorInstrumentation.h"
#include "JSDOMBinding.h"
#include <runtime/Completion.h>
#include <runtime/Executable.h>
#ifndef NDEBUG
#include <wtf/MainThread.h>
#endif
#include "WebCoreThread.h"
namespace WebCore {
class ScriptExecutionContext;
class JSMainThreadExecState {
WTF_MAKE_NONCOPYABLE(JSMainThreadExecState);
public:
static JSC::ExecState* currentState()
{
ASSERT((isMainThread() || pthread_main_np()) && WebThreadIsLockedOrDisabled());
return s_mainThreadState;
};
static JSC::JSValue call(JSC::ExecState* exec, JSC::JSValue functionObject, JSC::CallType callType, const JSC::CallData& callData, JSC::JSValue thisValue, const JSC::ArgList& args)
{
JSMainThreadExecState currentState(exec);
if (thisValue.isObject())
thisValue = thisValue.toThisObject(exec);
return JSC::call(exec, functionObject, callType, callData, thisValue, args);
};
static inline InspectorInstrumentationCookie instrumentFunctionCall(ScriptExecutionContext* context, JSC::CallType callType, const JSC::CallData& callData)
{
if (!InspectorInstrumentation::hasFrontends())
return InspectorInstrumentationCookie();
String resourceName;
int lineNumber = 1;
if (callType == JSC::CallTypeJS) {
resourceName = ustringToString(callData.js.functionExecutable->sourceURL());
lineNumber = callData.js.functionExecutable->lineNo();
} else
resourceName = "undefined";
return InspectorInstrumentation::willCallFunction(context, resourceName, lineNumber);
}
static JSC::JSValue evaluate(JSC::ExecState* exec, JSC::ScopeChainNode* chain, const JSC::SourceCode& source, JSC::JSValue thisValue, JSC::JSValue* exception)
{
JSMainThreadExecState currentState(exec);
JSC::JSLockHolder lock(exec);
return JSC::evaluate(exec, chain, source, thisValue, exception);
};
protected:
explicit JSMainThreadExecState(JSC::ExecState* exec)
: m_previousState(s_mainThreadState)
{
ASSERT((isMainThread() || pthread_main_np()) && WebThreadIsLockedOrDisabled());
s_mainThreadState = exec;
};
~JSMainThreadExecState()
{
ASSERT((isMainThread() || pthread_main_np()) && WebThreadIsLockedOrDisabled());
#if ENABLE(MUTATION_OBSERVERS)
bool didExitJavaScript = s_mainThreadState && !m_previousState;
#endif
s_mainThreadState = m_previousState;
#if ENABLE(MUTATION_OBSERVERS)
if (didExitJavaScript)
didLeaveScriptContext();
#endif
}
private:
static JSC::ExecState* s_mainThreadState;
JSC::ExecState* m_previousState;
#if ENABLE(MUTATION_OBSERVERS)
static void didLeaveScriptContext();
#endif
};
class JSMainThreadNullState : private JSMainThreadExecState {
public:
explicit JSMainThreadNullState() : JSMainThreadExecState(0) {};
};
}
#endif // JSMainThreadExecState_h