summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/debugger
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2015-05-20 09:56:07 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2015-05-20 09:56:07 +0000
commit41386e9cb918eed93b3f13648cbef387e371e451 (patch)
treea97f9d7bd1d9d091833286085f72da9d83fd0606 /Source/JavaScriptCore/debugger
parente15dd966d523731101f70ccf768bba12435a0208 (diff)
downloadWebKitGtk-tarball-41386e9cb918eed93b3f13648cbef387e371e451.tar.gz
webkitgtk-2.4.9webkitgtk-2.4.9
Diffstat (limited to 'Source/JavaScriptCore/debugger')
-rw-r--r--Source/JavaScriptCore/debugger/Breakpoint.h34
-rw-r--r--Source/JavaScriptCore/debugger/Debugger.cpp181
-rw-r--r--Source/JavaScriptCore/debugger/Debugger.h54
-rw-r--r--Source/JavaScriptCore/debugger/DebuggerActivation.cpp98
-rw-r--r--Source/JavaScriptCore/debugger/DebuggerActivation.h (renamed from Source/JavaScriptCore/debugger/DebuggerScope.h)81
-rw-r--r--Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp93
-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.cpp208
10 files changed, 238 insertions, 602 deletions
diff --git a/Source/JavaScriptCore/debugger/Breakpoint.h b/Source/JavaScriptCore/debugger/Breakpoint.h
index 8518ce469..95b92881d 100644
--- a/Source/JavaScriptCore/debugger/Breakpoint.h
+++ b/Source/JavaScriptCore/debugger/Breakpoint.h
@@ -27,13 +27,11 @@
#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)
@@ -43,7 +41,7 @@ struct Breakpoint : public DoublyLinkedListNode<Breakpoint> {
{
}
- Breakpoint(SourceID sourceID, unsigned line, unsigned column, const String& condition, bool autoContinue)
+ Breakpoint(SourceID sourceID, unsigned line, unsigned column, String condition, bool autoContinue)
: id(noBreakpointID)
, sourceID(sourceID)
, line(line)
@@ -53,16 +51,6 @@ struct Breakpoint : public DoublyLinkedListNode<Breakpoint> {
{
}
- Breakpoint(const Breakpoint& other)
- : id(other.id)
- , sourceID(other.sourceID)
- , line(other.line)
- , column(other.column)
- , condition(other.condition)
- , autoContinue(other.autoContinue)
- {
- }
-
BreakpointID id;
SourceID sourceID;
unsigned line;
@@ -71,24 +59,6 @@ struct Breakpoint : public DoublyLinkedListNode<Breakpoint> {
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 4d7871ff8..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"
@@ -43,14 +44,12 @@ class Recompiler : public MarkedBlock::VoidFunctor {
public:
Recompiler(JSC::Debugger*);
~Recompiler();
- IterationStatus operator()(JSCell*);
+ void operator()(JSCell*);
private:
typedef HashSet<FunctionExecutable*> FunctionExecutableSet;
typedef HashMap<SourceProvider*, ExecState*> SourceProviderMap;
- void visit(JSCell*);
-
JSC::Debugger* m_debugger;
FunctionExecutableSet m_functionExecutables;
SourceProviderMap m_sourceProviders;
@@ -70,7 +69,7 @@ inline Recompiler::~Recompiler()
m_debugger->sourceParsed(iter->value, iter->key, -1, String());
}
-inline void Recompiler::visit(JSCell* cell)
+inline void Recompiler::operator()(JSCell* cell)
{
if (!cell->inherits(JSFunction::info()))
return;
@@ -87,25 +86,19 @@ inline void Recompiler::visit(JSCell* cell)
return;
ExecState* exec = function->scope()->globalObject()->JSGlobalObject::globalExec();
- executable->clearCode();
- executable->clearUnlinkedCodeForRecompilation();
+ executable->clearCodeIfNotCompiling();
+ executable->clearUnlinkedCodeForRecompilationIfNotCompiling();
if (m_debugger == function->scope()->globalObject()->debugger())
m_sourceProviders.add(executable->source().provider(), exec);
}
-inline IterationStatus Recompiler::operator()(JSCell* cell)
-{
- visit(cell);
- return IterationStatus::Continue;
-}
-
} // namespace
namespace JSC {
-class DebuggerPausedScope {
+class DebuggerCallFrameScope {
public:
- DebuggerPausedScope(Debugger& debugger)
+ DebuggerCallFrameScope(Debugger& debugger)
: m_debugger(debugger)
{
ASSERT(!m_debugger.m_currentDebuggerCallFrame);
@@ -113,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;
}
}
@@ -145,13 +138,6 @@ private:
Debugger& m_debugger;
};
-template<typename Functor>
-void Debugger::forEachCodeBlock(Functor& functor)
-{
- m_vm->prepareToDeleteCode();
- m_vm->heap.forEachCodeBlock(functor);
-}
-
Debugger::Debugger(bool isInWorkerThread)
: m_vm(nullptr)
, m_pauseOnExceptionsState(DontPauseOnExceptions)
@@ -167,7 +153,6 @@ Debugger::Debugger(bool isInWorkerThread)
, m_lastExecutedLine(UINT_MAX)
, m_lastExecutedSourceID(noSourceID)
, m_topBreakpointID(noBreakpointID)
- , m_pausingBreakpointID(noBreakpointID)
{
}
@@ -214,11 +199,6 @@ void Debugger::detach(JSGlobalObject* globalObject, ReasonForDetach reason)
m_vm = nullptr;
}
-bool Debugger::isAttached(JSGlobalObject* globalObject)
-{
- return globalObject->debugger() == this;
-}
-
class Debugger::SetSteppingModeFunctor {
public:
SetSteppingModeFunctor(Debugger* debugger, SteppingMode mode)
@@ -245,22 +225,18 @@ private:
void Debugger::setSteppingMode(SteppingMode mode)
{
- if (mode == m_steppingMode || !m_vm)
+ if (mode == m_steppingMode)
return;
-
- m_vm->prepareToDeleteCode();
-
m_steppingMode = mode;
+
+ if (!m_vm)
+ return;
SetSteppingModeFunctor functor(this, mode);
m_vm->heap.forEachCodeBlock(functor);
}
void Debugger::registerCodeBlock(CodeBlock* codeBlock)
{
- // FIXME: We should never have to jettison a code block (due to pending breakpoints
- // or stepping mode) that is being registered. operationOptimize() should have
- // prevented the optimizing of such code blocks in the first place. Find a way to
- // express this with greater clarity in the code. See <https://webkit.org/b131771>.
applyBreakpoints(codeBlock);
if (isStepping())
codeBlock->setSteppingMode(CodeBlock::SteppingModeEnabled);
@@ -277,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();
@@ -340,7 +316,7 @@ void Debugger::toggleBreakpoint(Breakpoint& breakpoint, Debugger::BreakpointStat
if (!m_vm)
return;
ToggleBreakpointFunctor functor(this, breakpoint, enabledOrNot);
- forEachCodeBlock(functor);
+ m_vm->heap.forEachCodeBlock(functor);
}
void Debugger::recompileAllJSFunctions(VM* vm)
@@ -348,17 +324,11 @@ void Debugger::recompileAllJSFunctions(VM* vm)
// 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) {
- auto listener = [] (VM& vm, JSGlobalObject* globalObject)
- {
- if (Debugger* debugger = globalObject->debugger())
- debugger->recompileAllJSFunctions(&vm);
- };
-
- vm->entryScope->setEntryScopeDidPopListener(this, listener);
+ vm->entryScope->setRecompilationNeeded(true);
return;
}
- vm->prepareToDeleteCode();
+ vm->prepareToDiscardCode();
Recompiler recompiler(this);
HeapIterationScope iterationScope(vm->heap);
@@ -376,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);
@@ -396,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);
@@ -411,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
+ 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);
- m_breakpointIDToBreakpoint.remove(idIt);
- breakpoints.remove(breakpoint);
- delete breakpoint;
-
- 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;
+ }
}
}
@@ -460,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)
@@ -477,18 +443,17 @@ bool Debugger::hasBreakpoint(SourceID sourceID, const TextPosition& position, Br
return false;
if (hitBreakpoint)
- *hitBreakpoint = *breakpoint;
+ *hitBreakpoint = breakpoints[i];
- 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)
@@ -530,7 +495,7 @@ void Debugger::clearBreakpoints()
if (!m_vm)
return;
ClearCodeBlockDebuggerRequestsFunctor functor(this);
- forEachCodeBlock(functor);
+ m_vm->heap.forEachCodeBlock(functor);
}
class Debugger::ClearDebuggerRequestsFunctor {
@@ -555,7 +520,7 @@ void Debugger::clearDebuggerRequests(JSGlobalObject* globalObject)
{
ASSERT(m_vm);
ClearDebuggerRequestsFunctor functor(globalObject);
- forEachCodeBlock(functor);
+ m_vm->heap.forEachCodeBlock(functor);
}
void Debugger::setBreakpointsActivated(bool activated)
@@ -620,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();
}
@@ -657,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);
@@ -666,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);
@@ -673,20 +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);
}
- m_pausingBreakpointID = noBreakpointID;
+ handlePause(m_reasonForPause, vmEntryGlobalObject);
if (!m_pauseOnNextStatement && !m_pauseOnCallFrame) {
setSteppingMode(SteppingModeDisabled);
@@ -694,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);
}
@@ -743,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)
@@ -779,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)
@@ -793,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 d70f3b76f..f7b734f37 100644
--- a/Source/JavaScriptCore/debugger/Debugger.h
+++ b/Source/JavaScriptCore/debugger/Debugger.h
@@ -29,12 +29,11 @@
#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;
@@ -61,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);
@@ -84,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();
@@ -105,12 +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; }
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,15 +108,28 @@ public:
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;
@@ -185,8 +182,6 @@ private:
void clearDebuggerRequests(JSGlobalObject*);
- template<typename Functor> inline void forEachCodeBlock(Functor&);
-
VM* m_vm;
HashSet<JSGlobalObject*> m_globalObjects;
@@ -196,7 +191,7 @@ private:
bool m_breakpointsActivated : 1;
bool m_hasHandlerForExceptionCallback : 1;
bool m_isInWorkerThread : 1;
- unsigned m_steppingMode : 1; // SteppingMode
+ SteppingMode m_steppingMode : 1;
ReasonForPause m_reasonForPause;
JSValue m_currentException;
@@ -206,13 +201,12 @@ private:
SourceID m_lastExecutedSourceID;
BreakpointID m_topBreakpointID;
- BreakpointID m_pausingBreakpointID;
BreakpointIDToBreakpointMap m_breakpointIDToBreakpoint;
SourceIDToBreakpointsMap m_sourceIDToBreakpoints;
RefPtr<JSC::DebuggerCallFrame> m_currentDebuggerCallFrame;
- 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/DebuggerScope.h b/Source/JavaScriptCore/debugger/DebuggerActivation.h
index e1edb9248..e90383eaa 100644
--- a/Source/JavaScriptCore/debugger/DebuggerScope.h
+++ b/Source/JavaScriptCore/debugger/DebuggerActivation.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2009, 2014 Apple Inc. All rights reserved.
+ * 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
@@ -23,26 +23,22 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef DebuggerScope_h
-#define DebuggerScope_h
+#ifndef DebuggerActivation_h
+#define DebuggerActivation_h
#include "JSObject.h"
namespace JSC {
-class DebuggerCallFrame;
-class JSScope;
-
-class DebuggerScope : public JSNonFinalObject {
+class DebuggerActivation : public JSNonFinalObject {
public:
typedef JSNonFinalObject Base;
- static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames;
- static DebuggerScope* create(VM& vm, JSScope* scope)
+ static DebuggerActivation* create(VM& vm, JSObject* object)
{
- DebuggerScope* debuggerScope = new (NotNull, allocateCell<DebuggerScope>(vm.heap)) DebuggerScope(vm, scope);
- debuggerScope->finishCreation(vm);
- return debuggerScope;
+ DebuggerActivation* activation = new (NotNull, allocateCell<DebuggerActivation>(vm.heap)) DebuggerActivation(vm);
+ activation->finishCreation(vm, object);
+ return activation;
}
static void visitChildren(JSCell*, SlotVisitor&);
@@ -55,66 +51,21 @@ public:
DECLARE_EXPORT_INFO;
- static Structure* createStructure(VM& vm, JSGlobalObject* globalObject)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(vm, globalObject, jsNull(), TypeInfo(ObjectType, StructureFlags), info());
+ return Structure::create(vm, globalObject, prototype, 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; }
+protected:
+ static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | JSObject::StructureFlags;
- bool isCatchScope() const;
- bool isFunctionNameScope() const;
- bool isWithScope() const;
- bool isGlobalScope() const;
- bool isFunctionOrEvalScope() const;
-
- JSValue caughtValue(ExecState*) const;
+ JS_EXPORT_PRIVATE void finishCreation(VM&, JSObject* activation);
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;
+ JS_EXPORT_PRIVATE DebuggerActivation(VM&);
+ WriteBarrier<JSActivation> m_activation;
};
-inline DebuggerScope::iterator DebuggerScope::begin()
-{
- return iterator(this);
-}
-
-inline DebuggerScope::iterator DebuggerScope::end()
-{
- return iterator(0);
-}
-
} // namespace JSC
-#endif // DebuggerScope_h
+#endif // DebuggerActivation_h
diff --git a/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp b/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp
index bf093e89b..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,33 +99,19 @@ String DebuggerCallFrame::functionName() const
ASSERT(isValid());
if (!isValid())
return String();
- JSFunction* function = jsDynamicCast<JSFunction*>(m_callFrame->callee());
+ 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
@@ -163,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;
@@ -176,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();
@@ -188,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, &variablesUnderTDZ);
+ EvalExecutable* eval = EvalExecutable::create(callFrame, makeSource(script), callFrame->codeBlock()->isStrictMode());
if (vm.exception()) {
exception = vm.exception();
vm.clearException();
@@ -204,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();
@@ -215,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();
}
}
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 c6eba4e93..000000000
--- a/Source/JavaScriptCore/debugger/DebuggerScope.cpp
+++ /dev/null
@@ -1,208 +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::isFunctionOrEvalScope() 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->isActivationObject() && !isCatchScope();
-}
-
-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());
- bool success = catchEnvironment->getOwnPropertySlot(catchEnvironment, exec, errorName, slot);
- RELEASE_ASSERT(success && slot.isValue());
- return slot.getValue(exec, errorName);
-}
-
-} // namespace JSC