summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/debugger
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/debugger')
-rw-r--r--Source/JavaScriptCore/debugger/Breakpoint.h57
-rw-r--r--Source/JavaScriptCore/debugger/Debugger.cpp301
-rw-r--r--Source/JavaScriptCore/debugger/Debugger.h82
-rw-r--r--Source/JavaScriptCore/debugger/DebuggerActivation.cpp98
-rw-r--r--Source/JavaScriptCore/debugger/DebuggerActivation.h71
-rw-r--r--Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp99
-rw-r--r--Source/JavaScriptCore/debugger/DebuggerCallFrame.h26
-rw-r--r--Source/JavaScriptCore/debugger/DebuggerEvalEnabler.h63
-rw-r--r--Source/JavaScriptCore/debugger/DebuggerPrimitives.h2
-rw-r--r--Source/JavaScriptCore/debugger/DebuggerScope.cpp218
-rw-r--r--Source/JavaScriptCore/debugger/DebuggerScope.h122
-rw-r--r--Source/JavaScriptCore/debugger/ScriptProfilingScope.h93
12 files changed, 390 insertions, 842 deletions
diff --git a/Source/JavaScriptCore/debugger/Breakpoint.h b/Source/JavaScriptCore/debugger/Breakpoint.h
index 78d208a2b..95b92881d 100644
--- a/Source/JavaScriptCore/debugger/Breakpoint.h
+++ b/Source/JavaScriptCore/debugger/Breakpoint.h
@@ -27,67 +27,38 @@
#define Breakpoint_h
#include "DebuggerPrimitives.h"
-#include <wtf/DoublyLinkedList.h>
-#include <wtf/RefCounted.h>
#include <wtf/text/WTFString.h>
namespace JSC {
-struct Breakpoint : public DoublyLinkedListNode<Breakpoint> {
+struct Breakpoint {
Breakpoint()
+ : id(noBreakpointID)
+ , sourceID(noSourceID)
+ , line(0)
+ , column(0)
+ , autoContinue(false)
{
}
- Breakpoint(SourceID sourceID, unsigned line, unsigned column, const String& condition, bool autoContinue, unsigned ignoreCount)
- : sourceID(sourceID)
+ Breakpoint(SourceID sourceID, unsigned line, unsigned column, String condition, bool autoContinue)
+ : id(noBreakpointID)
+ , sourceID(sourceID)
, line(line)
, column(column)
, condition(condition)
, autoContinue(autoContinue)
- , ignoreCount(ignoreCount)
{
}
- Breakpoint(const Breakpoint& other)
- : id(other.id)
- , sourceID(other.sourceID)
- , line(other.line)
- , column(other.column)
- , condition(other.condition)
- , autoContinue(other.autoContinue)
- , ignoreCount(other.ignoreCount)
- , hitCount(other.hitCount)
- {
- }
-
- BreakpointID id { noBreakpointID };
- SourceID sourceID { noSourceID };
- unsigned line { 0 };
- unsigned column { 0 };
+ BreakpointID id;
+ SourceID sourceID;
+ unsigned line;
+ unsigned column;
String condition;
- bool autoContinue { false };
- unsigned ignoreCount { 0 };
- unsigned hitCount { 0 };
+ bool autoContinue;
static const unsigned unspecifiedColumn = UINT_MAX;
-
-private:
- Breakpoint* m_prev;
- Breakpoint* m_next;
-
- friend class WTF::DoublyLinkedListNode<Breakpoint>;
-};
-
-class BreakpointsList : public DoublyLinkedList<Breakpoint>,
- public RefCounted<BreakpointsList> {
-public:
- ~BreakpointsList()
- {
- Breakpoint* breakpoint;
- while ((breakpoint = removeHead()))
- delete breakpoint;
- ASSERT(isEmpty());
- }
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/debugger/Debugger.cpp b/Source/JavaScriptCore/debugger/Debugger.cpp
index f50d54be5..afa7546c8 100644
--- a/Source/JavaScriptCore/debugger/Debugger.cpp
+++ b/Source/JavaScriptCore/debugger/Debugger.cpp
@@ -25,12 +25,13 @@
#include "CodeBlock.h"
#include "DebuggerCallFrame.h"
#include "Error.h"
+
#include "HeapIterationScope.h"
#include "Interpreter.h"
#include "JSCJSValueInlines.h"
#include "JSFunction.h"
#include "JSGlobalObject.h"
-#include "JSCInlines.h"
+#include "Operations.h"
#include "Parser.h"
#include "Protect.h"
#include "VMEntryScope.h"
@@ -39,41 +40,65 @@ namespace {
using namespace JSC;
-struct GatherSourceProviders : public MarkedBlock::VoidFunctor {
- HashSet<SourceProvider*> sourceProviders;
- JSGlobalObject* m_globalObject;
+class Recompiler : public MarkedBlock::VoidFunctor {
+public:
+ Recompiler(JSC::Debugger*);
+ ~Recompiler();
+ void operator()(JSCell*);
- GatherSourceProviders(JSGlobalObject* globalObject)
- : m_globalObject(globalObject) { }
+private:
+ typedef HashSet<FunctionExecutable*> FunctionExecutableSet;
+ typedef HashMap<SourceProvider*, ExecState*> SourceProviderMap;
+
+ JSC::Debugger* m_debugger;
+ FunctionExecutableSet m_functionExecutables;
+ SourceProviderMap m_sourceProviders;
+};
- IterationStatus operator()(JSCell* cell)
- {
- JSFunction* function = jsDynamicCast<JSFunction*>(cell);
- if (!function)
- return IterationStatus::Continue;
+inline Recompiler::Recompiler(JSC::Debugger* debugger)
+ : m_debugger(debugger)
+{
+}
+
+inline Recompiler::~Recompiler()
+{
+ // Call sourceParsed() after reparsing all functions because it will execute
+ // JavaScript in the inspector.
+ SourceProviderMap::const_iterator end = m_sourceProviders.end();
+ for (SourceProviderMap::const_iterator iter = m_sourceProviders.begin(); iter != end; ++iter)
+ m_debugger->sourceParsed(iter->value, iter->key, -1, String());
+}
- if (function->scope()->globalObject() != m_globalObject)
- return IterationStatus::Continue;
+inline void Recompiler::operator()(JSCell* cell)
+{
+ if (!cell->inherits(JSFunction::info()))
+ return;
- if (!function->executable()->isFunctionExecutable())
- return IterationStatus::Continue;
+ JSFunction* function = jsCast<JSFunction*>(cell);
+ if (function->executable()->isHostFunction())
+ return;
- if (function->isHostOrBuiltinFunction())
- return IterationStatus::Continue;
+ FunctionExecutable* executable = function->jsExecutable();
- sourceProviders.add(
- jsCast<FunctionExecutable*>(function->executable())->source().provider());
- return IterationStatus::Continue;
- }
-};
+ // Check if the function is already in the set - if so,
+ // we've already retranslated it, nothing to do here.
+ if (!m_functionExecutables.add(executable).isNewEntry)
+ return;
+
+ ExecState* exec = function->scope()->globalObject()->JSGlobalObject::globalExec();
+ executable->clearCodeIfNotCompiling();
+ executable->clearUnlinkedCodeForRecompilationIfNotCompiling();
+ if (m_debugger == function->scope()->globalObject()->debugger())
+ m_sourceProviders.add(executable->source().provider(), exec);
+}
} // namespace
namespace JSC {
-class DebuggerPausedScope {
+class DebuggerCallFrameScope {
public:
- DebuggerPausedScope(Debugger& debugger)
+ DebuggerCallFrameScope(Debugger& debugger)
: m_debugger(debugger)
{
ASSERT(!m_debugger.m_currentDebuggerCallFrame);
@@ -81,11 +106,11 @@ public:
m_debugger.m_currentDebuggerCallFrame = DebuggerCallFrame::create(debugger.m_currentCallFrame);
}
- ~DebuggerPausedScope()
+ ~DebuggerCallFrameScope()
{
if (m_debugger.m_currentDebuggerCallFrame) {
m_debugger.m_currentDebuggerCallFrame->invalidate();
- m_debugger.m_currentDebuggerCallFrame = nullptr;
+ m_debugger.m_currentDebuggerCallFrame = 0;
}
}
@@ -113,14 +138,14 @@ private:
Debugger& m_debugger;
};
-Debugger::Debugger(VM& vm)
- : m_vm(vm)
+Debugger::Debugger(bool isInWorkerThread)
+ : m_vm(nullptr)
, m_pauseOnExceptionsState(DontPauseOnExceptions)
, m_pauseOnNextStatement(false)
, m_isPaused(false)
, m_breakpointsActivated(true)
, m_hasHandlerForExceptionCallback(false)
- , m_suppressAllPauses(false)
+ , m_isInWorkerThread(isInWorkerThread)
, m_steppingMode(SteppingModeDisabled)
, m_reasonForPause(NotPaused)
, m_pauseOnCallFrame(0)
@@ -128,7 +153,6 @@ Debugger::Debugger(VM& vm)
, m_lastExecutedLine(UINT_MAX)
, m_lastExecutedSourceID(noSourceID)
, m_topBreakpointID(noBreakpointID)
- , m_pausingBreakpointID(noBreakpointID)
{
}
@@ -142,19 +166,12 @@ Debugger::~Debugger()
void Debugger::attach(JSGlobalObject* globalObject)
{
ASSERT(!globalObject->debugger());
+ if (!m_vm)
+ m_vm = &globalObject->vm();
+ else
+ ASSERT(m_vm == &globalObject->vm());
globalObject->setDebugger(this);
m_globalObjects.add(globalObject);
-
- m_vm.setShouldBuildPCToCodeOriginMapping();
-
- // Call sourceParsed because it will execute JavaScript in the inspector.
- GatherSourceProviders gatherSourceProviders(globalObject);
- {
- HeapIterationScope iterationScope(m_vm.heap);
- m_vm.heap.objectSpace().forEachLiveCell(iterationScope, gatherSourceProviders);
- }
- for (auto* sourceProvider : gatherSourceProviders.sourceProviders)
- sourceParsed(globalObject->globalExec(), sourceProvider, -1, String());
}
void Debugger::detach(JSGlobalObject* globalObject, ReasonForDetach reason)
@@ -178,11 +195,8 @@ void Debugger::detach(JSGlobalObject* globalObject, ReasonForDetach reason)
clearDebuggerRequests(globalObject);
globalObject->setDebugger(0);
-}
-
-bool Debugger::isAttached(JSGlobalObject* globalObject)
-{
- return globalObject->debugger() == this;
+ if (!m_globalObjects.size())
+ m_vm = nullptr;
}
class Debugger::SetSteppingModeFunctor {
@@ -213,12 +227,12 @@ void Debugger::setSteppingMode(SteppingMode mode)
{
if (mode == m_steppingMode)
return;
-
- m_vm.heap.completeAllDFGPlans();
-
m_steppingMode = mode;
+
+ if (!m_vm)
+ return;
SetSteppingModeFunctor functor(this, mode);
- m_vm.heap.forEachCodeBlock(functor);
+ m_vm->heap.forEachCodeBlock(functor);
}
void Debugger::registerCodeBlock(CodeBlock* codeBlock)
@@ -228,27 +242,9 @@ void Debugger::registerCodeBlock(CodeBlock* codeBlock)
codeBlock->setSteppingMode(CodeBlock::SteppingModeEnabled);
}
-void Debugger::setProfilingClient(ProfilingClient* client)
-{
- ASSERT(!!m_profilingClient != !!client);
- m_profilingClient = client;
-
- recompileAllJSFunctions();
-}
-
-double Debugger::willEvaluateScript()
-{
- return m_profilingClient->willEvaluateScript();
-}
-
-void Debugger::didEvaluateScript(double startTime, ProfilingReason reason)
-{
- m_profilingClient->didEvaluateScript(startTime, reason);
-}
-
void Debugger::toggleBreakpoint(CodeBlock* codeBlock, Breakpoint& breakpoint, BreakpointState enabledOrNot)
{
- ScriptExecutable* executable = codeBlock->ownerScriptExecutable();
+ ScriptExecutable* executable = codeBlock->ownerExecutable();
SourceID sourceID = static_cast<SourceID>(executable->sourceID());
if (breakpoint.sourceID != sourceID)
@@ -257,7 +253,7 @@ void Debugger::toggleBreakpoint(CodeBlock* codeBlock, Breakpoint& breakpoint, Br
unsigned line = breakpoint.line;
unsigned column = breakpoint.column;
- unsigned startLine = executable->firstLine();
+ unsigned startLine = executable->lineNo();
unsigned startColumn = executable->startColumn();
unsigned endLine = executable->lastLine();
unsigned endColumn = executable->endColumn();
@@ -317,15 +313,26 @@ private:
void Debugger::toggleBreakpoint(Breakpoint& breakpoint, Debugger::BreakpointState enabledOrNot)
{
- m_vm.heap.completeAllDFGPlans();
-
+ if (!m_vm)
+ return;
ToggleBreakpointFunctor functor(this, breakpoint, enabledOrNot);
- m_vm.heap.forEachCodeBlock(functor);
+ m_vm->heap.forEachCodeBlock(functor);
}
-void Debugger::recompileAllJSFunctions()
+void Debugger::recompileAllJSFunctions(VM* vm)
{
- m_vm.deleteAllCode();
+ // If JavaScript is running, it's not safe to recompile, since we'll end
+ // up throwing away code that is live on the stack.
+ if (vm->entryScope) {
+ vm->entryScope->setRecompilationNeeded(true);
+ return;
+ }
+
+ vm->prepareToDiscardCode();
+
+ Recompiler recompiler(this);
+ HeapIterationScope iterationScope(vm->heap);
+ vm->heap.objectSpace().forEachLiveCell(iterationScope, recompiler);
}
BreakpointID Debugger::setBreakpoint(Breakpoint breakpoint, unsigned& actualLine, unsigned& actualColumn)
@@ -339,18 +346,18 @@ BreakpointID Debugger::setBreakpoint(Breakpoint breakpoint, unsigned& actualLine
it = m_sourceIDToBreakpoints.set(sourceID, LineToBreakpointsMap()).iterator;
LineToBreakpointsMap::iterator breaksIt = it->value.find(line);
if (breaksIt == it->value.end())
- breaksIt = it->value.set(line, adoptRef(new BreakpointsList)).iterator;
+ breaksIt = it->value.set(line, BreakpointsInLine()).iterator;
- BreakpointsList& breakpoints = *breaksIt->value;
- for (Breakpoint* current = breakpoints.head(); current; current = current->next()) {
- if (current->column == column) {
+ BreakpointsInLine& breakpoints = breaksIt->value;
+ unsigned breakpointsCount = breakpoints.size();
+ for (unsigned i = 0; i < breakpointsCount; i++)
+ if (breakpoints[i].column == column) {
// The breakpoint already exists. We're not allowed to create a new
// breakpoint at this location. Rather than returning the breakpointID
// of the pre-existing breakpoint, we need to return noBreakpointID
// to indicate that we're not creating a new one.
return noBreakpointID;
}
- }
BreakpointID id = ++m_topBreakpointID;
RELEASE_ASSERT(id != noBreakpointID);
@@ -359,9 +366,8 @@ BreakpointID Debugger::setBreakpoint(Breakpoint breakpoint, unsigned& actualLine
actualLine = line;
actualColumn = column;
- Breakpoint* newBreakpoint = new Breakpoint(breakpoint);
- breakpoints.append(newBreakpoint);
- m_breakpointIDToBreakpoint.set(id, newBreakpoint);
+ breakpoints.append(breakpoint);
+ m_breakpointIDToBreakpoint.set(id, &breakpoints.last());
toggleBreakpoint(breakpoint, BreakpointEnabled);
@@ -374,35 +380,31 @@ void Debugger::removeBreakpoint(BreakpointID id)
BreakpointIDToBreakpointMap::iterator idIt = m_breakpointIDToBreakpoint.find(id);
ASSERT(idIt != m_breakpointIDToBreakpoint.end());
- Breakpoint* breakpoint = idIt->value;
+ Breakpoint& breakpoint = *idIt->value;
- SourceID sourceID = breakpoint->sourceID;
+ SourceID sourceID = breakpoint.sourceID;
ASSERT(sourceID);
SourceIDToBreakpointsMap::iterator it = m_sourceIDToBreakpoints.find(sourceID);
ASSERT(it != m_sourceIDToBreakpoints.end());
- LineToBreakpointsMap::iterator breaksIt = it->value.find(breakpoint->line);
+ LineToBreakpointsMap::iterator breaksIt = it->value.find(breakpoint.line);
ASSERT(breaksIt != it->value.end());
- toggleBreakpoint(*breakpoint, BreakpointDisabled);
+ toggleBreakpoint(breakpoint, BreakpointDisabled);
- BreakpointsList& breakpoints = *breaksIt->value;
-#if !ASSERT_DISABLED
- bool found = false;
- for (Breakpoint* current = breakpoints.head(); current && !found; current = current->next()) {
- if (current->id == breakpoint->id)
- found = true;
- }
- ASSERT(found);
-#endif
-
- m_breakpointIDToBreakpoint.remove(idIt);
- breakpoints.remove(breakpoint);
- delete breakpoint;
+ BreakpointsInLine& breakpoints = breaksIt->value;
+ unsigned breakpointsCount = breakpoints.size();
+ for (unsigned i = 0; i < breakpointsCount; i++) {
+ if (breakpoints[i].id == breakpoint.id) {
+ breakpoints.remove(i);
+ m_breakpointIDToBreakpoint.remove(idIt);
- if (breakpoints.isEmpty()) {
- it->value.remove(breaksIt);
- if (it->value.isEmpty())
- m_sourceIDToBreakpoints.remove(it);
+ if (breakpoints.isEmpty()) {
+ it->value.remove(breaksIt);
+ if (it->value.isEmpty())
+ m_sourceIDToBreakpoints.remove(it);
+ }
+ break;
+ }
}
}
@@ -423,11 +425,12 @@ bool Debugger::hasBreakpoint(SourceID sourceID, const TextPosition& position, Br
return false;
bool hit = false;
- const BreakpointsList& breakpoints = *breaksIt->value;
- Breakpoint* breakpoint;
- for (breakpoint = breakpoints.head(); breakpoint; breakpoint = breakpoint->next()) {
- unsigned breakLine = breakpoint->line;
- unsigned breakColumn = breakpoint->column;
+ const BreakpointsInLine& breakpoints = breaksIt->value;
+ unsigned breakpointsCount = breakpoints.size();
+ unsigned i;
+ for (i = 0; i < breakpointsCount; i++) {
+ unsigned breakLine = breakpoints[i].line;
+ unsigned breakColumn = breakpoints[i].column;
// Since frontend truncates the indent, the first statement in a line must match the breakpoint (line,0).
ASSERT(this == m_currentCallFrame->codeBlock()->globalObject()->debugger());
if ((line != m_lastExecutedLine && line == breakLine && !breakColumn)
@@ -440,22 +443,17 @@ bool Debugger::hasBreakpoint(SourceID sourceID, const TextPosition& position, Br
return false;
if (hitBreakpoint)
- *hitBreakpoint = *breakpoint;
+ *hitBreakpoint = breakpoints[i];
- breakpoint->hitCount++;
- if (breakpoint->ignoreCount >= breakpoint->hitCount)
- return false;
-
- if (breakpoint->condition.isEmpty())
+ if (breakpoints[i].condition.isEmpty())
return true;
// We cannot stop in the debugger while executing condition code,
// so make it looks like the debugger is already paused.
TemporaryPausedState pausedState(*this);
- NakedPtr<Exception> exception;
- DebuggerCallFrame* debuggerCallFrame = currentDebuggerCallFrame();
- JSValue result = debuggerCallFrame->evaluate(breakpoint->condition, exception);
+ JSValue exception;
+ JSValue result = DebuggerCallFrame::evaluateWithCallFrame(m_currentCallFrame, breakpoints[i].condition, exception);
// We can lose the debugger while executing JavaScript.
if (!m_currentCallFrame)
@@ -490,14 +488,14 @@ private:
void Debugger::clearBreakpoints()
{
- m_vm.heap.completeAllDFGPlans();
-
m_topBreakpointID = noBreakpointID;
m_breakpointIDToBreakpoint.clear();
m_sourceIDToBreakpoints.clear();
+ if (!m_vm)
+ return;
ClearCodeBlockDebuggerRequestsFunctor functor(this);
- m_vm.heap.forEachCodeBlock(functor);
+ m_vm->heap.forEachCodeBlock(functor);
}
class Debugger::ClearDebuggerRequestsFunctor {
@@ -520,10 +518,9 @@ private:
void Debugger::clearDebuggerRequests(JSGlobalObject* globalObject)
{
- m_vm.heap.completeAllDFGPlans();
-
+ ASSERT(m_vm);
ClearDebuggerRequestsFunctor functor(globalObject);
- m_vm.heap.forEachCodeBlock(functor);
+ m_vm->heap.forEachCodeBlock(functor);
}
void Debugger::setBreakpointsActivated(bool activated)
@@ -548,12 +545,10 @@ void Debugger::breakProgram()
if (m_isPaused)
return;
- if (!m_vm.topCallFrame)
- return;
-
m_pauseOnNextStatement = true;
setSteppingMode(SteppingModeEnabled);
- m_currentCallFrame = m_vm.topCallFrame;
+ m_currentCallFrame = m_vm->topCallFrame;
+ ASSERT(m_currentCallFrame);
pauseIfNeeded(m_currentCallFrame);
}
@@ -590,8 +585,7 @@ void Debugger::stepOutOfFunction()
if (!m_isPaused)
return;
- VMEntryFrame* topVMEntryFrame = m_vm.topVMEntryFrame;
- m_pauseOnCallFrame = m_currentCallFrame ? m_currentCallFrame->callerFrame(topVMEntryFrame) : 0;
+ m_pauseOnCallFrame = m_currentCallFrame ? m_currentCallFrame->callerFrameSkippingVMEntrySentinel() : 0;
notifyDoneProcessingDebuggerEvents();
}
@@ -618,9 +612,6 @@ void Debugger::pauseIfNeeded(CallFrame* callFrame)
if (m_isPaused)
return;
- if (m_suppressAllPauses)
- return;
-
JSGlobalObject* vmEntryGlobalObject = callFrame->vmEntryGlobalObject();
if (!needPauseHandling(vmEntryGlobalObject))
return;
@@ -630,8 +621,6 @@ void Debugger::pauseIfNeeded(CallFrame* callFrame)
bool pauseNow = m_pauseOnNextStatement;
pauseNow |= (m_pauseOnCallFrame == m_currentCallFrame);
- DebuggerPausedScope debuggerPausedScope(*this);
-
intptr_t sourceID = DebuggerCallFrame::sourceIDForCallFrame(m_currentCallFrame);
TextPosition position = DebuggerCallFrame::positionForCallFrame(m_currentCallFrame);
pauseNow |= didHitBreakpoint = hasBreakpoint(sourceID, position, &breakpoint);
@@ -639,6 +628,8 @@ void Debugger::pauseIfNeeded(CallFrame* callFrame)
if (!pauseNow)
return;
+ DebuggerCallFrameScope debuggerCallFrameScope(*this);
+
// Make sure we are not going to pause again on breakpoint actions by
// reseting the pause state before executing any breakpoint actions.
TemporaryPausedState pausedState(*this);
@@ -646,21 +637,14 @@ void Debugger::pauseIfNeeded(CallFrame* callFrame)
m_pauseOnNextStatement = false;
if (didHitBreakpoint) {
- handleBreakpointHit(vmEntryGlobalObject, breakpoint);
+ handleBreakpointHit(breakpoint);
// Note that the actions can potentially stop the debugger, so we need to check that
// we still have a current call frame when we get back.
if (breakpoint.autoContinue || !m_currentCallFrame)
return;
- m_pausingBreakpointID = breakpoint.id;
- }
-
- {
- PauseReasonDeclaration reason(*this, didHitBreakpoint ? PausedForBreakpoint : m_reasonForPause);
- handlePause(vmEntryGlobalObject, m_reasonForPause);
- RELEASE_ASSERT(!callFrame->hadException());
}
- m_pausingBreakpointID = noBreakpointID;
+ handlePause(m_reasonForPause, vmEntryGlobalObject);
if (!m_pauseOnNextStatement && !m_pauseOnCallFrame) {
setSteppingMode(SteppingModeDisabled);
@@ -668,13 +652,13 @@ void Debugger::pauseIfNeeded(CallFrame* callFrame)
}
}
-void Debugger::exception(CallFrame* callFrame, JSValue exception, bool hasCatchHandler)
+void Debugger::exception(CallFrame* callFrame, JSValue exception, bool hasHandler)
{
if (m_isPaused)
return;
PauseReasonDeclaration reason(*this, PausedForException);
- if (m_pauseOnExceptionsState == PauseOnAllExceptions || (m_pauseOnExceptionsState == PauseOnUncaughtExceptions && !hasCatchHandler)) {
+ if (m_pauseOnExceptionsState == PauseOnAllExceptions || (m_pauseOnExceptionsState == PauseOnUncaughtExceptions && !hasHandler)) {
m_pauseOnNextStatement = true;
setSteppingMode(SteppingModeEnabled);
}
@@ -717,13 +701,10 @@ void Debugger::returnEvent(CallFrame* callFrame)
return;
// Treat stepping over a return statement like stepping out.
- if (m_currentCallFrame == m_pauseOnCallFrame) {
- VMEntryFrame* topVMEntryFrame = m_vm.topVMEntryFrame;
- m_pauseOnCallFrame = m_currentCallFrame->callerFrame(topVMEntryFrame);
- }
+ if (m_currentCallFrame == m_pauseOnCallFrame)
+ m_pauseOnCallFrame = m_currentCallFrame->callerFrameSkippingVMEntrySentinel();
- VMEntryFrame* topVMEntryFrame = m_vm.topVMEntryFrame;
- m_currentCallFrame = m_currentCallFrame->callerFrame(topVMEntryFrame);
+ m_currentCallFrame = m_currentCallFrame->callerFrameSkippingVMEntrySentinel();
}
void Debugger::willExecuteProgram(CallFrame* callFrame)
@@ -732,7 +713,13 @@ void Debugger::willExecuteProgram(CallFrame* callFrame)
return;
PauseReasonDeclaration reason(*this, PausedAtStartOfProgram);
- updateCallFrameAndPauseIfNeeded(callFrame);
+ // FIXME: This check for whether we're debugging a worker thread is a workaround
+ // for https://bugs.webkit.org/show_bug.cgi?id=102637. Remove it when we rework
+ // the debugger implementation to not require callbacks.
+ if (!m_isInWorkerThread)
+ updateCallFrameAndPauseIfNeeded(callFrame);
+ else if (isStepping())
+ updateCallFrame(callFrame);
}
void Debugger::didExecuteProgram(CallFrame* callFrame)
@@ -747,13 +734,11 @@ void Debugger::didExecuteProgram(CallFrame* callFrame)
if (!m_currentCallFrame)
return;
if (m_currentCallFrame == m_pauseOnCallFrame) {
- VMEntryFrame* topVMEntryFrame = m_vm.topVMEntryFrame;
- m_pauseOnCallFrame = m_currentCallFrame->callerFrame(topVMEntryFrame);
+ m_pauseOnCallFrame = m_currentCallFrame->callerFrameSkippingVMEntrySentinel();
if (!m_currentCallFrame)
return;
}
- VMEntryFrame* topVMEntryFrame = m_vm.topVMEntryFrame;
- m_currentCallFrame = m_currentCallFrame->callerFrame(topVMEntryFrame);
+ m_currentCallFrame = m_currentCallFrame->callerFrameSkippingVMEntrySentinel();
}
void Debugger::didReachBreakpoint(CallFrame* callFrame)
@@ -761,7 +746,7 @@ void Debugger::didReachBreakpoint(CallFrame* callFrame)
if (m_isPaused)
return;
- PauseReasonDeclaration reason(*this, PausedForDebuggerStatement);
+ PauseReasonDeclaration reason(*this, PausedForBreakpoint);
m_pauseOnNextStatement = true;
setSteppingMode(SteppingModeEnabled);
updateCallFrameAndPauseIfNeeded(callFrame);
diff --git a/Source/JavaScriptCore/debugger/Debugger.h b/Source/JavaScriptCore/debugger/Debugger.h
index 2e91aafbe..f7b734f37 100644
--- a/Source/JavaScriptCore/debugger/Debugger.h
+++ b/Source/JavaScriptCore/debugger/Debugger.h
@@ -23,19 +23,17 @@
#define Debugger_h
#include "Breakpoint.h"
-#include "CallData.h"
#include "DebuggerCallFrame.h"
#include "DebuggerPrimitives.h"
#include "JSCJSValue.h"
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
#include <wtf/text/TextPosition.h>
namespace JSC {
-class CodeBlock;
-class Exception;
class ExecState;
class JSGlobalObject;
class SourceProvider;
@@ -45,11 +43,9 @@ typedef ExecState CallFrame;
class JS_EXPORT_PRIVATE Debugger {
public:
- Debugger(VM&);
+ Debugger(bool isInWorkerThread = false);
virtual ~Debugger();
- VM& vm() { return m_vm; }
-
JSC::DebuggerCallFrame* currentDebuggerCallFrame() const;
bool hasHandlerForExceptionCallback() const
{
@@ -64,13 +60,12 @@ public:
bool needsExceptionCallbacks() const { return m_pauseOnExceptionsState != DontPauseOnExceptions; }
+ void attach(JSGlobalObject*);
enum ReasonForDetach {
TerminatingDebuggingSession,
GlobalObjectIsDestructing
};
- void attach(JSGlobalObject*);
- void detach(JSGlobalObject*, ReasonForDetach);
- bool isAttached(JSGlobalObject*);
+ virtual void detach(JSGlobalObject*, ReasonForDetach);
BreakpointID setBreakpoint(Breakpoint, unsigned& actualLine, unsigned& actualColumn);
void removeBreakpoint(BreakpointID);
@@ -87,20 +82,6 @@ public:
PauseOnExceptionsState pauseOnExceptionsState() const { return m_pauseOnExceptionsState; }
void setPauseOnExceptionsState(PauseOnExceptionsState);
- enum ReasonForPause {
- NotPaused,
- PausedForException,
- PausedAtStatement,
- PausedAfterCall,
- PausedBeforeReturn,
- PausedAtStartOfProgram,
- PausedAtEndOfProgram,
- PausedForBreakpoint,
- PausedForDebuggerStatement,
- };
- ReasonForPause reasonForPause() const { return m_reasonForPause; }
- BreakpointID pausingBreakpointID() const { return m_pausingBreakpointID; }
-
void setPauseOnNextStatement(bool);
void breakProgram();
void continueProgram();
@@ -108,15 +89,12 @@ public:
void stepOverStatement();
void stepOutOfFunction();
- bool isPaused() const { return m_isPaused; }
+ bool isPaused() { return m_isPaused; }
bool isStepping() const { return m_steppingMode == SteppingModeEnabled; }
- bool suppressAllPauses() const { return m_suppressAllPauses; }
- void setSuppressAllPauses(bool suppress) { m_suppressAllPauses = suppress; }
-
virtual void sourceParsed(ExecState*, SourceProvider*, int errorLineNumber, const WTF::String& errorMessage) = 0;
- void exception(CallFrame*, JSValue exceptionValue, bool hasCatchHandler);
+ void exception(CallFrame*, JSValue exceptionValue, bool hasHandler);
void atStatement(CallFrame*);
void callEvent(CallFrame*);
void returnEvent(CallFrame*);
@@ -124,35 +102,34 @@ public:
void didExecuteProgram(CallFrame*);
void didReachBreakpoint(CallFrame*);
- virtual void recompileAllJSFunctions();
+ void recompileAllJSFunctions(VM*);
void registerCodeBlock(CodeBlock*);
- class ProfilingClient {
- public:
- virtual ~ProfilingClient() { }
- virtual bool isAlreadyProfiling() const = 0;
- virtual double willEvaluateScript() = 0;
- virtual void didEvaluateScript(double startTime, ProfilingReason) = 0;
- };
-
- void setProfilingClient(ProfilingClient*);
- bool hasProfilingClient() const { return m_profilingClient != nullptr; }
- bool isAlreadyProfiling() const { return m_profilingClient && m_profilingClient->isAlreadyProfiling(); }
- double willEvaluateScript();
- void didEvaluateScript(double startTime, ProfilingReason);
-
protected:
virtual bool needPauseHandling(JSGlobalObject*) { return false; }
- virtual void handleBreakpointHit(JSGlobalObject*, const Breakpoint&) { }
- virtual void handleExceptionInBreakpointCondition(ExecState*, Exception*) const { }
- virtual void handlePause(JSGlobalObject*, ReasonForPause) { }
+ virtual void handleBreakpointHit(const Breakpoint&) { }
+ virtual void handleExceptionInBreakpointCondition(ExecState*, JSValue exception) const { UNUSED_PARAM(exception); }
+
+ enum ReasonForPause {
+ NotPaused,
+ PausedForException,
+ PausedAtStatement,
+ PausedAfterCall,
+ PausedBeforeReturn,
+ PausedAtStartOfProgram,
+ PausedAtEndOfProgram,
+ PausedForBreakpoint
+ };
+
+ virtual void handlePause(ReasonForPause, JSGlobalObject*) { }
virtual void notifyDoneProcessingDebuggerEvents() { }
private:
typedef HashMap<BreakpointID, Breakpoint*> BreakpointIDToBreakpointMap;
- typedef HashMap<unsigned, RefPtr<BreakpointsList>, WTF::IntHash<int>, WTF::UnsignedWithZeroKeyHashTraits<int>> LineToBreakpointsMap;
+ typedef Vector<Breakpoint> BreakpointsInLine;
+ typedef HashMap<unsigned, BreakpointsInLine, WTF::IntHash<int>, WTF::UnsignedWithZeroKeyHashTraits<int>> LineToBreakpointsMap;
typedef HashMap<SourceID, LineToBreakpointsMap, WTF::IntHash<SourceID>, WTF::UnsignedWithZeroKeyHashTraits<SourceID>> SourceIDToBreakpointsMap;
class ClearCodeBlockDebuggerRequestsFunctor;
@@ -205,7 +182,7 @@ private:
void clearDebuggerRequests(JSGlobalObject*);
- VM& m_vm;
+ VM* m_vm;
HashSet<JSGlobalObject*> m_globalObjects;
PauseOnExceptionsState m_pauseOnExceptionsState;
@@ -213,8 +190,8 @@ private:
bool m_isPaused : 1;
bool m_breakpointsActivated : 1;
bool m_hasHandlerForExceptionCallback : 1;
- bool m_suppressAllPauses : 1;
- unsigned m_steppingMode : 1; // SteppingMode
+ bool m_isInWorkerThread : 1;
+ SteppingMode m_steppingMode : 1;
ReasonForPause m_reasonForPause;
JSValue m_currentException;
@@ -224,15 +201,12 @@ private:
SourceID m_lastExecutedSourceID;
BreakpointID m_topBreakpointID;
- BreakpointID m_pausingBreakpointID;
BreakpointIDToBreakpointMap m_breakpointIDToBreakpoint;
SourceIDToBreakpointsMap m_sourceIDToBreakpoints;
RefPtr<JSC::DebuggerCallFrame> m_currentDebuggerCallFrame;
- ProfilingClient* m_profilingClient { nullptr };
-
- friend class DebuggerPausedScope;
+ friend class DebuggerCallFrameScope;
friend class TemporaryPausedState;
friend class LLIntOffsetsExtractor;
};
diff --git a/Source/JavaScriptCore/debugger/DebuggerActivation.cpp b/Source/JavaScriptCore/debugger/DebuggerActivation.cpp
new file mode 100644
index 000000000..75b08ea81
--- /dev/null
+++ b/Source/JavaScriptCore/debugger/DebuggerActivation.cpp
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DebuggerActivation.h"
+
+#include "JSActivation.h"
+#include "Operations.h"
+
+namespace JSC {
+
+STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(DebuggerActivation);
+
+const ClassInfo DebuggerActivation::s_info = { "DebuggerActivation", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(DebuggerActivation) };
+
+DebuggerActivation::DebuggerActivation(VM& vm)
+ : JSNonFinalObject(vm, vm.debuggerActivationStructure.get())
+{
+}
+
+void DebuggerActivation::finishCreation(VM& vm, JSObject* activation)
+{
+ Base::finishCreation(vm);
+ ASSERT(activation);
+ ASSERT(activation->isActivationObject());
+ m_activation.set(vm, this, jsCast<JSActivation*>(activation));
+}
+
+void DebuggerActivation::visitChildren(JSCell* cell, SlotVisitor& visitor)
+{
+ DebuggerActivation* thisObject = jsCast<DebuggerActivation*>(cell);
+ ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+ COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
+ ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
+
+ JSObject::visitChildren(thisObject, visitor);
+ visitor.append(&thisObject->m_activation);
+}
+
+String DebuggerActivation::className(const JSObject* object)
+{
+ const DebuggerActivation* thisObject = jsCast<const DebuggerActivation*>(object);
+ return thisObject->m_activation->methodTable()->className(thisObject->m_activation.get());
+}
+
+bool DebuggerActivation::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
+{
+ DebuggerActivation* thisObject = jsCast<DebuggerActivation*>(object);
+ return thisObject->m_activation->methodTable()->getOwnPropertySlot(thisObject->m_activation.get(), exec, propertyName, slot);
+}
+
+void DebuggerActivation::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
+{
+ DebuggerActivation* thisObject = jsCast<DebuggerActivation*>(cell);
+ thisObject->m_activation->methodTable()->put(thisObject->m_activation.get(), exec, propertyName, value, slot);
+}
+
+bool DebuggerActivation::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName)
+{
+ DebuggerActivation* thisObject = jsCast<DebuggerActivation*>(cell);
+ return thisObject->m_activation->methodTable()->deleteProperty(thisObject->m_activation.get(), exec, propertyName);
+}
+
+void DebuggerActivation::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
+{
+ DebuggerActivation* thisObject = jsCast<DebuggerActivation*>(object);
+ thisObject->m_activation->methodTable()->getPropertyNames(thisObject->m_activation.get(), exec, propertyNames, mode);
+}
+
+bool DebuggerActivation::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, const PropertyDescriptor& descriptor, bool shouldThrow)
+{
+ DebuggerActivation* thisObject = jsCast<DebuggerActivation*>(object);
+ return thisObject->m_activation->methodTable()->defineOwnProperty(thisObject->m_activation.get(), exec, propertyName, descriptor, shouldThrow);
+}
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/debugger/DebuggerActivation.h b/Source/JavaScriptCore/debugger/DebuggerActivation.h
new file mode 100644
index 000000000..e90383eaa
--- /dev/null
+++ b/Source/JavaScriptCore/debugger/DebuggerActivation.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DebuggerActivation_h
+#define DebuggerActivation_h
+
+#include "JSObject.h"
+
+namespace JSC {
+
+class DebuggerActivation : public JSNonFinalObject {
+public:
+ typedef JSNonFinalObject Base;
+
+ static DebuggerActivation* create(VM& vm, JSObject* object)
+ {
+ DebuggerActivation* activation = new (NotNull, allocateCell<DebuggerActivation>(vm.heap)) DebuggerActivation(vm);
+ activation->finishCreation(vm, object);
+ return activation;
+ }
+
+ static void visitChildren(JSCell*, SlotVisitor&);
+ static String className(const JSObject*);
+ static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
+ static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
+ static bool deleteProperty(JSCell*, ExecState*, PropertyName);
+ static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
+ static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
+
+ DECLARE_EXPORT_INFO;
+
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+ {
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+ }
+
+protected:
+ static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | JSObject::StructureFlags;
+
+ JS_EXPORT_PRIVATE void finishCreation(VM&, JSObject* activation);
+
+private:
+ JS_EXPORT_PRIVATE DebuggerActivation(VM&);
+ WriteBarrier<JSActivation> m_activation;
+};
+
+} // namespace JSC
+
+#endif // DebuggerActivation_h
diff --git a/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp b/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp
index f4794fd45..90cee8c23 100644
--- a/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp
+++ b/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -29,16 +29,13 @@
#include "config.h"
#include "DebuggerCallFrame.h"
+#include "JSFunction.h"
#include "CodeBlock.h"
-#include "DebuggerEvalEnabler.h"
-#include "DebuggerScope.h"
#include "Interpreter.h"
-#include "JSFunction.h"
-#include "JSLexicalEnvironment.h"
-#include "JSCInlines.h"
+#include "Operations.h"
#include "Parser.h"
#include "StackVisitor.h"
-#include "StrongInlines.h"
+#include "VMEntryScope.h"
namespace JSC {
@@ -58,36 +55,13 @@ private:
unsigned m_column;
};
-class FindCallerMidStackFunctor {
-public:
- FindCallerMidStackFunctor(CallFrame* callFrame)
- : m_callFrame(callFrame)
- , m_callerFrame(nullptr)
- { }
-
- StackVisitor::Status operator()(StackVisitor& visitor)
- {
- if (visitor->callFrame() == m_callFrame) {
- m_callerFrame = visitor->callerFrame();
- return StackVisitor::Done;
- }
- return StackVisitor::Continue;
- }
-
- CallFrame* getCallerFrame() const { return m_callerFrame; }
-
-private:
- CallFrame* m_callFrame;
- CallFrame* m_callerFrame;
-};
-
DebuggerCallFrame::DebuggerCallFrame(CallFrame* callFrame)
: m_callFrame(callFrame)
{
m_position = positionForCallFrame(m_callFrame);
}
-RefPtr<DebuggerCallFrame> DebuggerCallFrame::callerFrame()
+PassRefPtr<DebuggerCallFrame> DebuggerCallFrame::callerFrame()
{
ASSERT(isValid());
if (!isValid())
@@ -96,12 +70,9 @@ RefPtr<DebuggerCallFrame> DebuggerCallFrame::callerFrame()
if (m_caller)
return m_caller;
- FindCallerMidStackFunctor functor(m_callFrame);
- m_callFrame->vm().topCallFrame->iterate(functor);
-
- CallFrame* callerFrame = functor.getCallerFrame();
+ CallFrame* callerFrame = m_callFrame->callerFrameSkippingVMEntrySentinel();
if (!callerFrame)
- return nullptr;
+ return 0;
m_caller = DebuggerCallFrame::create(callerFrame);
return m_caller;
@@ -128,29 +99,19 @@ String DebuggerCallFrame::functionName() const
ASSERT(isValid());
if (!isValid())
return String();
- return m_callFrame->friendlyFunctionName();
+ JSObject* function = m_callFrame->callee();
+ if (!function)
+ return String();
+
+ return getCalculatedDisplayName(m_callFrame, function);
}
-DebuggerScope* DebuggerCallFrame::scope()
+JSScope* DebuggerCallFrame::scope() const
{
ASSERT(isValid());
if (!isValid())
return 0;
-
- if (!m_scope) {
- VM& vm = m_callFrame->vm();
- JSScope* scope;
- CodeBlock* codeBlock = m_callFrame->codeBlock();
- if (codeBlock && codeBlock->scopeRegister().isValid())
- scope = m_callFrame->scope(codeBlock->scopeRegister().offset());
- else if (JSCallee* callee = jsDynamicCast<JSCallee*>(m_callFrame->callee()))
- scope = callee->scope();
- else
- scope = m_callFrame->lexicalGlobalObject();
-
- m_scope.set(vm, DebuggerScope::create(vm, scope));
- }
- return m_scope.get();
+ return m_callFrame->scope();
}
DebuggerCallFrame::Type DebuggerCallFrame::type() const
@@ -159,7 +120,7 @@ DebuggerCallFrame::Type DebuggerCallFrame::type() const
if (!isValid())
return ProgramType;
- if (jsDynamicCast<JSFunction*>(m_callFrame->callee()))
+ if (m_callFrame->callee())
return FunctionType;
return ProgramType;
@@ -172,10 +133,14 @@ JSValue DebuggerCallFrame::thisValue() const
}
// Evaluate some JavaScript code in the scope of this frame.
-JSValue DebuggerCallFrame::evaluate(const String& script, NakedPtr<Exception>& exception)
+JSValue DebuggerCallFrame::evaluate(const String& script, JSValue& exception) const
{
ASSERT(isValid());
- CallFrame* callFrame = m_callFrame;
+ return evaluateWithCallFrame(m_callFrame, script, exception);
+}
+
+JSValue DebuggerCallFrame::evaluateWithCallFrame(CallFrame* callFrame, const String& script, JSValue& exception)
+{
if (!callFrame)
return jsNull();
@@ -184,15 +149,8 @@ JSValue DebuggerCallFrame::evaluate(const String& script, NakedPtr<Exception>& e
if (!callFrame->codeBlock())
return JSValue();
- DebuggerEvalEnabler evalEnabler(callFrame);
VM& vm = callFrame->vm();
- auto& codeBlock = *callFrame->codeBlock();
- ThisTDZMode thisTDZMode = codeBlock.unlinkedCodeBlock()->constructorKind() == ConstructorKind::Derived ? ThisTDZMode::AlwaysCheck : ThisTDZMode::CheckIfNeeded;
-
- VariableEnvironment variablesUnderTDZ;
- JSScope::collectVariablesUnderTDZ(scope()->jsScope(), variablesUnderTDZ);
-
- EvalExecutable* eval = EvalExecutable::create(callFrame, makeSource(script), codeBlock.isStrictMode(), thisTDZMode, codeBlock.unlinkedCodeBlock()->derivedContextType(), codeBlock.unlinkedCodeBlock()->isArrowFunction(), &variablesUnderTDZ);
+ EvalExecutable* eval = EvalExecutable::create(callFrame, makeSource(script), callFrame->codeBlock()->isStrictMode());
if (vm.exception()) {
exception = vm.exception();
vm.clearException();
@@ -200,7 +158,7 @@ JSValue DebuggerCallFrame::evaluate(const String& script, NakedPtr<Exception>& e
}
JSValue thisValue = thisValueForCallFrame(callFrame);
- JSValue result = vm.interpreter->execute(eval, callFrame, thisValue, scope()->jsScope());
+ JSValue result = vm.interpreter->execute(eval, callFrame, thisValue, callFrame->scope());
if (vm.exception()) {
exception = vm.exception();
vm.clearException();
@@ -211,13 +169,10 @@ JSValue DebuggerCallFrame::evaluate(const String& script, NakedPtr<Exception>& e
void DebuggerCallFrame::invalidate()
{
- RefPtr<DebuggerCallFrame> frame = this;
+ m_callFrame = nullptr;
+ RefPtr<DebuggerCallFrame> frame = m_caller.release();
while (frame) {
frame->m_callFrame = nullptr;
- if (frame->m_scope) {
- frame->m_scope->invalidateChain();
- frame->m_scope.clear();
- }
frame = frame->m_caller.release();
}
}
@@ -238,7 +193,7 @@ SourceID DebuggerCallFrame::sourceIDForCallFrame(CallFrame* callFrame)
CodeBlock* codeBlock = callFrame->codeBlock();
if (!codeBlock)
return noSourceID;
- return codeBlock->ownerScriptExecutable()->sourceID();
+ return codeBlock->ownerExecutable()->sourceID();
}
JSValue DebuggerCallFrame::thisValueForCallFrame(CallFrame* callFrame)
diff --git a/Source/JavaScriptCore/debugger/DebuggerCallFrame.h b/Source/JavaScriptCore/debugger/DebuggerCallFrame.h
index aa3cca52b..09c3fb9d8 100644
--- a/Source/JavaScriptCore/debugger/DebuggerCallFrame.h
+++ b/Source/JavaScriptCore/debugger/DebuggerCallFrame.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -29,32 +29,26 @@
#ifndef DebuggerCallFrame_h
#define DebuggerCallFrame_h
+#include "CallFrame.h"
#include "DebuggerPrimitives.h"
-#include "Strong.h"
-#include <wtf/NakedPtr.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/text/TextPosition.h>
namespace JSC {
-class DebuggerScope;
-class Exception;
-class ExecState;
-typedef ExecState CallFrame;
-
class DebuggerCallFrame : public RefCounted<DebuggerCallFrame> {
public:
enum Type { ProgramType, FunctionType };
- static Ref<DebuggerCallFrame> create(CallFrame* callFrame)
+ static PassRefPtr<DebuggerCallFrame> create(CallFrame* callFrame)
{
- return adoptRef(*new DebuggerCallFrame(callFrame));
+ return adoptRef(new DebuggerCallFrame(callFrame));
}
JS_EXPORT_PRIVATE explicit DebuggerCallFrame(CallFrame*);
- JS_EXPORT_PRIVATE RefPtr<DebuggerCallFrame> callerFrame();
+ JS_EXPORT_PRIVATE PassRefPtr<DebuggerCallFrame> callerFrame();
ExecState* exec() const { return m_callFrame; }
JS_EXPORT_PRIVATE SourceID sourceID() const;
@@ -64,11 +58,11 @@ public:
JS_EXPORT_PRIVATE const TextPosition& position() const { return m_position; }
JS_EXPORT_PRIVATE JSGlobalObject* vmEntryGlobalObject() const;
- JS_EXPORT_PRIVATE DebuggerScope* scope();
+ JS_EXPORT_PRIVATE JSScope* scope() const;
JS_EXPORT_PRIVATE String functionName() const;
JS_EXPORT_PRIVATE Type type() const;
JS_EXPORT_PRIVATE JSValue thisValue() const;
- JSValue evaluate(const String&, NakedPtr<Exception>&);
+ JS_EXPORT_PRIVATE JSValue evaluate(const String&, JSValue& exception) const;
bool isValid() const { return !!m_callFrame; }
JS_EXPORT_PRIVATE void invalidate();
@@ -76,6 +70,7 @@ public:
// The following are only public for the Debugger's use only. They will be
// made private soon. Other clients should not use these.
+ JS_EXPORT_PRIVATE static JSValue evaluateWithCallFrame(CallFrame*, const String& script, JSValue& exception);
JS_EXPORT_PRIVATE static TextPosition positionForCallFrame(CallFrame*);
JS_EXPORT_PRIVATE static SourceID sourceIDForCallFrame(CallFrame*);
static JSValue thisValueForCallFrame(CallFrame*);
@@ -84,9 +79,6 @@ private:
CallFrame* m_callFrame;
RefPtr<DebuggerCallFrame> m_caller;
TextPosition m_position;
- // The DebuggerPausedScope is responsible for calling invalidate() which,
- // in turn, will clear this strong ref.
- Strong<DebuggerScope> m_scope;
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/debugger/DebuggerEvalEnabler.h b/Source/JavaScriptCore/debugger/DebuggerEvalEnabler.h
deleted file mode 100644
index bb75b1f15..000000000
--- a/Source/JavaScriptCore/debugger/DebuggerEvalEnabler.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DebuggerEvalEnabler_h
-#define DebuggerEvalEnabler_h
-
-#include "CallFrame.h"
-#include "JSGlobalObject.h"
-
-namespace JSC {
-
-class DebuggerEvalEnabler {
-public:
- explicit DebuggerEvalEnabler(const ExecState* exec)
- : m_exec(exec)
- , m_evalWasDisabled(false)
- {
- if (exec) {
- JSGlobalObject* globalObject = exec->lexicalGlobalObject();
- m_evalWasDisabled = !globalObject->evalEnabled();
- if (m_evalWasDisabled)
- globalObject->setEvalEnabled(true, globalObject->evalDisabledErrorMessage());
- }
- }
-
- ~DebuggerEvalEnabler()
- {
- if (m_evalWasDisabled) {
- JSGlobalObject* globalObject = m_exec->lexicalGlobalObject();
- globalObject->setEvalEnabled(false, globalObject->evalDisabledErrorMessage());
- }
- }
-
-private:
- const ExecState* m_exec;
- bool m_evalWasDisabled;
-};
-
-} // namespace JSC
-
-#endif // DebuggerEvalEnabler_h
diff --git a/Source/JavaScriptCore/debugger/DebuggerPrimitives.h b/Source/JavaScriptCore/debugger/DebuggerPrimitives.h
index ab7301b5c..635a5bfe8 100644
--- a/Source/JavaScriptCore/debugger/DebuggerPrimitives.h
+++ b/Source/JavaScriptCore/debugger/DebuggerPrimitives.h
@@ -26,8 +26,6 @@
#ifndef DebuggerPrimitives_h
#define DebuggerPrimitives_h
-#include <stddef.h>
-
namespace JSC {
typedef size_t SourceID;
diff --git a/Source/JavaScriptCore/debugger/DebuggerScope.cpp b/Source/JavaScriptCore/debugger/DebuggerScope.cpp
deleted file mode 100644
index c3efbd56d..000000000
--- a/Source/JavaScriptCore/debugger/DebuggerScope.cpp
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2008-2009, 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "DebuggerScope.h"
-
-#include "JSLexicalEnvironment.h"
-#include "JSCInlines.h"
-#include "JSWithScope.h"
-
-namespace JSC {
-
-STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(DebuggerScope);
-
-const ClassInfo DebuggerScope::s_info = { "DebuggerScope", &Base::s_info, 0, CREATE_METHOD_TABLE(DebuggerScope) };
-
-DebuggerScope::DebuggerScope(VM& vm, JSScope* scope)
- : JSNonFinalObject(vm, scope->globalObject()->debuggerScopeStructure())
-{
- ASSERT(scope);
- m_scope.set(vm, this, scope);
-}
-
-void DebuggerScope::finishCreation(VM& vm)
-{
- Base::finishCreation(vm);
-}
-
-void DebuggerScope::visitChildren(JSCell* cell, SlotVisitor& visitor)
-{
- DebuggerScope* thisObject = jsCast<DebuggerScope*>(cell);
- ASSERT_GC_OBJECT_INHERITS(thisObject, info());
- JSObject::visitChildren(thisObject, visitor);
- visitor.append(&thisObject->m_scope);
- visitor.append(&thisObject->m_next);
-}
-
-String DebuggerScope::className(const JSObject* object)
-{
- const DebuggerScope* scope = jsCast<const DebuggerScope*>(object);
- ASSERT(scope->isValid());
- if (!scope->isValid())
- return String();
- JSObject* thisObject = JSScope::objectAtScope(scope->jsScope());
- return thisObject->methodTable()->className(thisObject);
-}
-
-bool DebuggerScope::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
-{
- DebuggerScope* scope = jsCast<DebuggerScope*>(object);
- ASSERT(scope->isValid());
- if (!scope->isValid())
- return false;
- JSObject* thisObject = JSScope::objectAtScope(scope->jsScope());
- slot.setThisValue(JSValue(thisObject));
-
- // By default, JSObject::getPropertySlot() will look in the DebuggerScope's prototype
- // chain and not the wrapped scope, and JSObject::getPropertySlot() cannot be overridden
- // to behave differently for the DebuggerScope.
- //
- // Instead, we'll treat all properties in the wrapped scope and its prototype chain as
- // the own properties of the DebuggerScope. This is fine because the WebInspector
- // does not presently need to distinguish between what's owned at each level in the
- // prototype chain. Hence, we'll invoke getPropertySlot() on the wrapped scope here
- // instead of getOwnPropertySlot().
- bool result = thisObject->getPropertySlot(exec, propertyName, slot);
- if (result && slot.isValue() && slot.getValue(exec, propertyName) == jsTDZValue()) {
- // FIXME:
- // We hit a scope property that has the TDZ empty value.
- // Currently, we just lie to the inspector and claim that this property is undefined.
- // This is not ideal and we should fix it.
- // https://bugs.webkit.org/show_bug.cgi?id=144977
- slot.setValue(slot.slotBase(), DontEnum, jsUndefined());
- return true;
- }
- return result;
-}
-
-void DebuggerScope::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
-{
- DebuggerScope* scope = jsCast<DebuggerScope*>(cell);
- ASSERT(scope->isValid());
- if (!scope->isValid())
- return;
- JSObject* thisObject = JSScope::objectAtScope(scope->jsScope());
- slot.setThisValue(JSValue(thisObject));
- thisObject->methodTable()->put(thisObject, exec, propertyName, value, slot);
-}
-
-bool DebuggerScope::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName)
-{
- DebuggerScope* scope = jsCast<DebuggerScope*>(cell);
- ASSERT(scope->isValid());
- if (!scope->isValid())
- return false;
- JSObject* thisObject = JSScope::objectAtScope(scope->jsScope());
- return thisObject->methodTable()->deleteProperty(thisObject, exec, propertyName);
-}
-
-void DebuggerScope::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
-{
- DebuggerScope* scope = jsCast<DebuggerScope*>(object);
- ASSERT(scope->isValid());
- if (!scope->isValid())
- return;
- JSObject* thisObject = JSScope::objectAtScope(scope->jsScope());
- thisObject->methodTable()->getPropertyNames(thisObject, exec, propertyNames, mode);
-}
-
-bool DebuggerScope::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, const PropertyDescriptor& descriptor, bool shouldThrow)
-{
- DebuggerScope* scope = jsCast<DebuggerScope*>(object);
- ASSERT(scope->isValid());
- if (!scope->isValid())
- return false;
- JSObject* thisObject = JSScope::objectAtScope(scope->jsScope());
- return thisObject->methodTable()->defineOwnProperty(thisObject, exec, propertyName, descriptor, shouldThrow);
-}
-
-DebuggerScope* DebuggerScope::next()
-{
- ASSERT(isValid());
- if (!m_next && m_scope->next()) {
- VM& vm = *m_scope->vm();
- DebuggerScope* nextScope = create(vm, m_scope->next());
- m_next.set(vm, this, nextScope);
- }
- return m_next.get();
-}
-
-void DebuggerScope::invalidateChain()
-{
- if (!isValid())
- return;
-
- DebuggerScope* scope = this;
- while (scope) {
- DebuggerScope* nextScope = scope->m_next.get();
- scope->m_next.clear();
- scope->m_scope.clear(); // This also marks this scope as invalid.
- scope = nextScope;
- }
-}
-
-bool DebuggerScope::isCatchScope() const
-{
- return m_scope->isCatchScope();
-}
-
-bool DebuggerScope::isFunctionNameScope() const
-{
- return m_scope->isFunctionNameScopeObject();
-}
-
-bool DebuggerScope::isWithScope() const
-{
- return m_scope->isWithScope();
-}
-
-bool DebuggerScope::isGlobalScope() const
-{
- return m_scope->isGlobalObject();
-}
-
-bool DebuggerScope::isGlobalLexicalEnvironment() const
-{
- return m_scope->isGlobalLexicalEnvironment();
-}
-
-bool DebuggerScope::isClosureScope() const
-{
- // In the current debugger implementation, every function or eval will create an
- // lexical environment object. Hence, a lexical environment object implies a
- // function or eval scope.
- return m_scope->isVarScope() || m_scope->isLexicalScope();
-}
-
-bool DebuggerScope::isNestedLexicalScope() const
-{
- return m_scope->isNestedLexicalScope();
-}
-
-JSValue DebuggerScope::caughtValue(ExecState* exec) const
-{
- ASSERT(isCatchScope());
- JSLexicalEnvironment* catchEnvironment = jsCast<JSLexicalEnvironment*>(m_scope.get());
- SymbolTable* catchSymbolTable = catchEnvironment->symbolTable();
- RELEASE_ASSERT(catchSymbolTable->size() == 1);
- PropertyName errorName(catchSymbolTable->begin(catchSymbolTable->m_lock)->key.get());
- PropertySlot slot(m_scope.get(), PropertySlot::InternalMethodType::Get);
- bool success = catchEnvironment->getOwnPropertySlot(catchEnvironment, exec, errorName, slot);
- RELEASE_ASSERT(success && slot.isValue());
- return slot.getValue(exec, errorName);
-}
-
-} // namespace JSC
diff --git a/Source/JavaScriptCore/debugger/DebuggerScope.h b/Source/JavaScriptCore/debugger/DebuggerScope.h
deleted file mode 100644
index fef60c899..000000000
--- a/Source/JavaScriptCore/debugger/DebuggerScope.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2008-2009, 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DebuggerScope_h
-#define DebuggerScope_h
-
-#include "JSObject.h"
-
-namespace JSC {
-
-class DebuggerCallFrame;
-class JSScope;
-
-class DebuggerScope : public JSNonFinalObject {
-public:
- typedef JSNonFinalObject Base;
- static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames;
-
- static DebuggerScope* create(VM& vm, JSScope* scope)
- {
- DebuggerScope* debuggerScope = new (NotNull, allocateCell<DebuggerScope>(vm.heap)) DebuggerScope(vm, scope);
- debuggerScope->finishCreation(vm);
- return debuggerScope;
- }
-
- static void visitChildren(JSCell*, SlotVisitor&);
- static String className(const JSObject*);
- static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
- static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
- static bool deleteProperty(JSCell*, ExecState*, PropertyName);
- static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
- static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
-
- DECLARE_EXPORT_INFO;
-
- static Structure* createStructure(VM& vm, JSGlobalObject* globalObject)
- {
- return Structure::create(vm, globalObject, jsNull(), TypeInfo(ObjectType, StructureFlags), info());
- }
-
- class iterator {
- public:
- iterator(DebuggerScope* node)
- : m_node(node)
- {
- }
-
- DebuggerScope* get() { return m_node; }
- iterator& operator++() { m_node = m_node->next(); return *this; }
- // postfix ++ intentionally omitted
-
- bool operator==(const iterator& other) const { return m_node == other.m_node; }
- bool operator!=(const iterator& other) const { return m_node != other.m_node; }
-
- private:
- DebuggerScope* m_node;
- };
-
- iterator begin();
- iterator end();
- DebuggerScope* next();
-
- void invalidateChain();
- bool isValid() const { return !!m_scope; }
-
- bool isCatchScope() const;
- bool isFunctionNameScope() const;
- bool isWithScope() const;
- bool isGlobalScope() const;
- bool isClosureScope() const;
- bool isGlobalLexicalEnvironment() const;
- bool isNestedLexicalScope() const;
-
- JSValue caughtValue(ExecState*) const;
-
-private:
- JS_EXPORT_PRIVATE DebuggerScope(VM&, JSScope*);
- JS_EXPORT_PRIVATE void finishCreation(VM&);
-
- JSScope* jsScope() const { return m_scope.get(); }
-
- WriteBarrier<JSScope> m_scope;
- WriteBarrier<DebuggerScope> m_next;
-
- friend class DebuggerCallFrame;
-};
-
-inline DebuggerScope::iterator DebuggerScope::begin()
-{
- return iterator(this);
-}
-
-inline DebuggerScope::iterator DebuggerScope::end()
-{
- return iterator(0);
-}
-
-} // namespace JSC
-
-#endif // DebuggerScope_h
diff --git a/Source/JavaScriptCore/debugger/ScriptProfilingScope.h b/Source/JavaScriptCore/debugger/ScriptProfilingScope.h
deleted file mode 100644
index ba6bdfc51..000000000
--- a/Source/JavaScriptCore/debugger/ScriptProfilingScope.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ScriptProfilingScope_h
-#define ScriptProfilingScope_h
-
-#include "Debugger.h"
-#include "JSGlobalObject.h"
-#include <wtf/Optional.h>
-
-namespace JSC {
-
-class ScriptProfilingScope {
-public:
- ScriptProfilingScope(JSGlobalObject* globalObject, ProfilingReason reason)
- : m_globalObject(globalObject)
- , m_reason(reason)
- {
- if (shouldStartProfile())
- m_startTime = m_globalObject->debugger()->willEvaluateScript();
- }
-
- ~ScriptProfilingScope()
- {
- if (shouldEndProfile())
- m_globalObject->debugger()->didEvaluateScript(m_startTime.value(), m_reason);
- }
-
-private:
- bool shouldStartProfile() const
- {
- if (!m_globalObject)
- return false;
-
- if (!m_globalObject->hasDebugger())
- return false;
-
- if (!m_globalObject->debugger()->hasProfilingClient())
- return false;
-
- if (m_globalObject->debugger()->isAlreadyProfiling())
- return false;
-
- return true;
- }
-
- bool shouldEndProfile() const
- {
- // Did not start a profile.
- if (!m_startTime)
- return false;
-
- // Debugger may have been removed.
- if (!m_globalObject->hasDebugger())
- return false;
-
- // Profiling Client may have been removed.
- if (!m_globalObject->debugger()->hasProfilingClient())
- return false;
-
- return true;
- }
-
- JSGlobalObject* m_globalObject { nullptr };
- Optional<double> m_startTime;
- ProfilingReason m_reason;
-};
-
-}
-
-#endif // ScriptProfilingScope_h