Rearrange some stuff. This way more js::Debug methods can be private, without making anything new public; all the event dispatch code is in one place; and we avoid having JSCompartment methods in jsdbg.cpp.

This commit is contained in:
Jason Orendorff 2011-04-21 14:44:53 -05:00
parent 9583e05f3c
commit d48b27e096
6 changed files with 76 additions and 45 deletions

View File

@ -601,6 +601,19 @@ JSCompartment::incBackEdgeCount(jsbytecode *pc)
}
bool
JSCompartment::isAboutToBeCollected(JSGCInvocationKind gckind) {
JSCompartment::isAboutToBeCollected(JSGCInvocationKind gckind)
{
return !hold && (arenaListsAreEmpty() || gckind == GC_LAST_CONTEXT);
}
void
JSCompartment::removeDebug(Debug *dbg)
{
for (Debug **p = debuggers.begin(); p != debuggers.end(); p++) {
if (*p == dbg) {
debuggers.erase(p);
return;
}
}
JS_NOT_REACHED("JSCompartment::removeDebug");
}

View File

@ -506,9 +506,6 @@ struct JS_FRIEND_API(JSCompartment) {
DebugVector debuggers;
// Implemented in jsdbg.cpp
JSTrapStatus dispatchDebuggerStatement(JSContext *cx, js::Value *vp);
JSCompartment *thisForCtor() { return this; }
public:
js::MathCache *getMathCache(JSContext *cx) {
@ -520,10 +517,6 @@ struct JS_FRIEND_API(JSCompartment) {
const DebugVector &getDebuggers() const { return debuggers; }
JSTrapStatus onDebuggerStatement(JSContext *cx, js::Value *vp) {
return debuggers.empty() ? JSTRAP_CONTINUE : dispatchDebuggerStatement(cx, vp);
}
bool addDebug(js::Debug *dbg) { return debuggers.append(dbg); }
void removeDebug(js::Debug *dbg);
};

View File

@ -206,11 +206,9 @@ CallMethodIfPresent(JSContext *cx, JSObject *obj, const char *name, int argc, Va
}
JSTrapStatus
Debug::onDebuggerStatement(JSContext *cx, Value *vp)
Debug::handleDebuggerStatement(JSContext *cx, Value *vp)
{
if (!hasDebuggerHandler)
return JSTRAP_CONTINUE;
JS_ASSERT(hasDebuggerHandler);
AutoCompartment ac(cx, hooksObject);
if (!ac.enter())
return JSTRAP_ERROR;
@ -222,7 +220,7 @@ Debug::onDebuggerStatement(JSContext *cx, Value *vp)
}
JSTrapStatus
JSCompartment::dispatchDebuggerStatement(JSContext *cx, js::Value *vp)
Debug::dispatchDebuggerStatement(JSContext *cx, js::Value *vp)
{
// Determine which debuggers will receive this event, and in what order.
// Make a copy of the list, since the original is mutable and we will be
@ -230,6 +228,8 @@ JSCompartment::dispatchDebuggerStatement(JSContext *cx, js::Value *vp)
// Note: In the general case, 'triggered' contains references to objects in
// different compartments--every compartment *except* this one.
AutoValueVector triggered(cx);
JSCompartment *compartment = cx->compartment;
const JSCompartment::DebugVector &debuggers = compartment->getDebuggers();
for (Debug **p = debuggers.begin(); p != debuggers.end(); p++) {
Debug *dbg = *p;
if (dbg->observesDebuggerStatement()) {
@ -242,7 +242,7 @@ JSCompartment::dispatchDebuggerStatement(JSContext *cx, js::Value *vp)
// should still be delivered.
for (Value *p = triggered.begin(); p != triggered.end(); p++) {
Debug *dbg = Debug::fromJSObject(&p->toObject());
if (dbg->observesCompartment(this) && dbg->observesDebuggerStatement()) {
if (dbg->observesCompartment(compartment) && dbg->observesDebuggerStatement()) {
JSTrapStatus st = dbg->onDebuggerStatement(cx, vp);
if (st != JSTRAP_CONTINUE)
return st;
@ -301,18 +301,6 @@ Debug::trace(JSTracer *trc, JSObject *obj)
}
}
void
JSCompartment::removeDebug(Debug *dbg)
{
for (Debug **p = debuggers.begin(); p != debuggers.end(); p++) {
if (*p == dbg) {
debuggers.erase(p);
return;
}
}
JS_NOT_REACHED("JSCompartment::removeDebug");
}
void
Debug::finalize(JSContext *cx, JSObject *obj)
{
@ -458,7 +446,7 @@ JSPropertySpec Debug::properties[] = {
Debug::setUncaughtExceptionHook, 0),
JS_PS_END
};
extern JS_PUBLIC_API(JSBool)
JS_DefineDebugObject(JSContext *cx, JSObject *obj)

View File

@ -43,6 +43,7 @@
#define jsdbg_h__
#include "jsapi.h"
#include "jscompartment.h"
#include "jsgc.h"
#include "jswrapper.h"
#include "jsvalue.h"
@ -80,7 +81,11 @@ class Debug {
static JSBool construct(JSContext *cx, uintN argc, Value *vp);
static JSPropertySpec properties[];
bool hasAnyLiveHooks() const { return observesDebuggerStatement(); }
inline bool hasAnyLiveHooks() const;
inline bool observesDebuggerStatement() const;
static JSTrapStatus dispatchDebuggerStatement(JSContext *cx, Value *vp);
JSTrapStatus handleDebuggerStatement(JSContext *cx, Value *vp);
public:
Debug(JSObject *dbg, JSObject *hooks, JSCompartment *compartment);
@ -101,25 +106,55 @@ class Debug {
//
static bool mark(GCMarker *trc, JSCompartment *compartment, JSGCInvocationKind gckind);
JSObject *toJSObject() const {
JS_ASSERT(object);
return object;
}
inline JSObject *toJSObject() const;
static inline Debug *fromJSObject(JSObject *obj);
static Debug *fromJSObject(JSObject *obj) {
JS_ASSERT(obj->getClass() == &jsclass);
return (Debug *) obj->getPrivate();
}
inline bool observesCompartment(JSCompartment *c) const;
bool observesCompartment(JSCompartment *c) const {
JS_ASSERT(c);
return debuggeeCompartment == c;
}
bool observesDebuggerStatement() const { return enabled && hasDebuggerHandler; }
JSTrapStatus onDebuggerStatement(JSContext *cx, Value *vp);
static inline JSTrapStatus onDebuggerStatement(JSContext *cx, js::Value *vp);
};
bool
Debug::hasAnyLiveHooks() const
{
return observesDebuggerStatement();
}
bool
Debug::observesCompartment(JSCompartment *c) const
{
JS_ASSERT(c);
return debuggeeCompartment == c;
}
JSObject *
Debug::toJSObject() const
{
JS_ASSERT(object);
return object;
}
Debug *
Debug::fromJSObject(JSObject *obj)
{
JS_ASSERT(obj->getClass() == &jsclass);
return (Debug *) obj->getPrivate();
}
bool
Debug::observesDebuggerStatement() const
{
return enabled && hasDebuggerHandler;
}
JSTrapStatus
Debug::onDebuggerStatement(JSContext *cx, js::Value *vp)
{
return cx->compartment->getDebuggers().empty()
? JSTRAP_CONTINUE
: dispatchDebuggerStatement(cx, vp);
}
}
#endif /* jsdbg_h__ */

View File

@ -56,6 +56,7 @@
#include "jscntxt.h"
#include "jsdate.h"
#include "jsversion.h"
#include "jsdbg.h"
#include "jsdbgapi.h"
#include "jsfun.h"
#include "jsgc.h"
@ -6173,7 +6174,7 @@ BEGIN_CASE(JSOP_DEBUGGER)
if (JSDebuggerHandler handler = cx->debugHooks->debuggerHandler)
st = handler(cx, script, regs.pc, Jsvalify(&rval), cx->debugHooks->debuggerHandlerData);
if (st == JSTRAP_CONTINUE)
st = cx->compartment->onDebuggerStatement(cx, &rval);
st = Debug::onDebuggerStatement(cx, &rval);
switch (st) {
case JSTRAP_ERROR:
goto error;

View File

@ -42,6 +42,7 @@
#include "jsscope.h"
#include "jsobj.h"
#include "jslibmath.h"
#include "jsdbg.h"
#include "jsiter.h"
#include "jsnum.h"
#include "jsxml.h"
@ -1175,7 +1176,7 @@ stubs::Debugger(VMFrame &f, jsbytecode *pc)
f.cx->debugHooks->debuggerHandlerData);
}
if (st == JSTRAP_CONTINUE)
st = f.cx->compartment->onDebuggerStatement(f.cx, &rval);
st = Debug::onDebuggerStatement(f.cx, &rval);
switch (st) {
case JSTRAP_THROW: