Bug 1271650 - Implement a C++ interface for DebuggerFrame.isLive. r=fitzgen

This commit is contained in:
Eddy Bruel 2016-07-20 13:50:04 +02:00
parent c1ad689350
commit 807cc5dc91
2 changed files with 47 additions and 20 deletions

View File

@ -7078,6 +7078,8 @@ DebuggerFrame::create(JSContext* cx, HandleObject proto, AbstractFramePtr refere
DebuggerFrame::getCallee(JSContext* cx, Handle<DebuggerFrame*> frame, DebuggerFrame::getCallee(JSContext* cx, Handle<DebuggerFrame*> frame,
MutableHandle<DebuggerObject*> result) MutableHandle<DebuggerObject*> result)
{ {
MOZ_ASSERT(frame->isLive());
AbstractFramePtr referent = DebuggerFrame::getReferent(frame); AbstractFramePtr referent = DebuggerFrame::getReferent(frame);
if (!referent.isFunctionFrame()) { if (!referent.isFunctionFrame()) {
result.set(nullptr); result.set(nullptr);
@ -7093,6 +7095,8 @@ DebuggerFrame::getCallee(JSContext* cx, Handle<DebuggerFrame*> frame,
/* static */ bool /* static */ bool
DebuggerFrame::getIsConstructing(JSContext* cx, Handle<DebuggerFrame*> frame, bool& result) DebuggerFrame::getIsConstructing(JSContext* cx, Handle<DebuggerFrame*> frame, bool& result)
{ {
MOZ_ASSERT(frame->isLive());
Maybe<ScriptFrameIter> maybeIter; Maybe<ScriptFrameIter> maybeIter;
if (!DebuggerFrame::getScriptFrameIter(cx, frame, maybeIter)) if (!DebuggerFrame::getScriptFrameIter(cx, frame, maybeIter))
return false; return false;
@ -7143,6 +7147,8 @@ UpdateFrameIterPc(FrameIter& iter)
DebuggerFrame::getEnvironment(JSContext* cx, Handle<DebuggerFrame*> frame, DebuggerFrame::getEnvironment(JSContext* cx, Handle<DebuggerFrame*> frame,
MutableHandle<DebuggerEnvironment*> result) MutableHandle<DebuggerEnvironment*> result)
{ {
MOZ_ASSERT(frame->isLive());
Debugger* dbg = frame->owner(); Debugger* dbg = frame->owner();
Maybe<ScriptFrameIter> maybeIter; Maybe<ScriptFrameIter> maybeIter;
@ -7168,6 +7174,24 @@ DebuggerFrame::getIsGenerator(Handle<DebuggerFrame*> frame)
return DebuggerFrame::getReferent(frame).script()->isGenerator(); return DebuggerFrame::getReferent(frame).script()->isGenerator();
} }
/* statuc */ bool
DebuggerFrame::isLive() const
{
return !!getPrivate();
}
/* static */ bool
DebuggerFrame::requireLive(JSContext* cx, Handle<DebuggerFrame*> frame)
{
if (!frame->isLive()) {
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_DEBUG_NOT_LIVE,
"Debugger.Frame");
return false;
}
return true;
}
/* static */ AbstractFramePtr /* static */ AbstractFramePtr
DebuggerFrame::getReferent(Handle<DebuggerFrame*> frame) DebuggerFrame::getReferent(Handle<DebuggerFrame*> frame)
{ {
@ -7235,7 +7259,7 @@ DebuggerFrame::checkThis(JSContext* cx, const CallArgs& args, const char* fnname
return nullptr; return nullptr;
} }
DebuggerFrame* nthisobj = &thisobj->as<DebuggerFrame>(); Rooted<DebuggerFrame*> frame(cx, &thisobj->as<DebuggerFrame>());
/* /*
* Forbid Debugger.Frame.prototype, which is of class DebuggerFrame::class_ * Forbid Debugger.Frame.prototype, which is of class DebuggerFrame::class_
@ -7243,19 +7267,18 @@ DebuggerFrame::checkThis(JSContext* cx, const CallArgs& args, const char* fnname
* is distinguished by having a nullptr private value. Also, forbid popped * is distinguished by having a nullptr private value. Also, forbid popped
* frames. * frames.
*/ */
if (!nthisobj->getPrivate()) { if (!frame->getPrivate() &&
if (nthisobj->getReservedSlot(JSSLOT_DEBUGFRAME_OWNER).isUndefined()) { frame->getReservedSlot(JSSLOT_DEBUGFRAME_OWNER).isUndefined())
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO, {
"Debugger.Frame", fnname, "prototype object"); JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
return nullptr; "Debugger.Frame", fnname, "prototype object");
} return nullptr;
if (checkLive) {
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_DEBUG_NOT_LIVE,
"Debugger.Frame");
return nullptr;
}
} }
return nthisobj;
if (checkLive && !DebuggerFrame::requireLive(cx, frame))
return nullptr;
return frame;
} }
/* /*
@ -7612,15 +7635,15 @@ DebuggerFrame_getOffset(JSContext* cx, unsigned argc, Value* vp)
return true; return true;
} }
static bool /* static */ bool
DebuggerFrame_getLive(JSContext* cx, unsigned argc, Value* vp) DebuggerFrame::liveGetter(JSContext* cx, unsigned argc, Value* vp)
{ {
CallArgs args = CallArgsFromVp(argc, vp); CallArgs args = CallArgsFromVp(argc, vp);
NativeObject* thisobj = DebuggerFrame::checkThis(cx, args, "get live", false); Rooted<DebuggerFrame*> frame(cx, DebuggerFrame::checkThis(cx, args, "get live", false));
if (!thisobj) if (!frame)
return false; return false;
bool hasFrame = !!thisobj->getPrivate();
args.rval().setBoolean(hasFrame); args.rval().setBoolean(frame->isLive());
return true; return true;
} }
@ -7930,7 +7953,7 @@ const JSPropertySpec DebuggerFrame::properties_[] = {
JS_PSG("constructing", DebuggerFrame::constructingGetter, 0), JS_PSG("constructing", DebuggerFrame::constructingGetter, 0),
JS_PSG("environment", DebuggerFrame::environmentGetter, 0), JS_PSG("environment", DebuggerFrame::environmentGetter, 0),
JS_PSG("generator", DebuggerFrame::generatorGetter, 0), JS_PSG("generator", DebuggerFrame::generatorGetter, 0),
JS_PSG("live", DebuggerFrame_getLive, 0), JS_PSG("live", DebuggerFrame::liveGetter, 0),
JS_PSG("offset", DebuggerFrame_getOffset, 0), JS_PSG("offset", DebuggerFrame_getOffset, 0),
JS_PSG("older", DebuggerFrame_getOlder, 0), JS_PSG("older", DebuggerFrame_getOlder, 0),
JS_PSG("script", DebuggerFrame_getScript, 0), JS_PSG("script", DebuggerFrame_getScript, 0),

View File

@ -1155,12 +1155,15 @@ class DebuggerFrame : public NativeObject
MutableHandle<DebuggerEnvironment*> result); MutableHandle<DebuggerEnvironment*> result);
static bool getIsGenerator(Handle<DebuggerFrame*> frame); static bool getIsGenerator(Handle<DebuggerFrame*> frame);
bool isLive() const;
private: private:
static const ClassOps classOps_; static const ClassOps classOps_;
static const JSPropertySpec properties_[]; static const JSPropertySpec properties_[];
static const JSFunctionSpec methods_[]; static const JSFunctionSpec methods_[];
static MOZ_MUST_USE bool requireLive(JSContext* cx, Handle<DebuggerFrame*> frame);
static AbstractFramePtr getReferent(Handle<DebuggerFrame*> frame); static AbstractFramePtr getReferent(Handle<DebuggerFrame*> frame);
static MOZ_MUST_USE bool getScriptFrameIter(JSContext* cx, Handle<DebuggerFrame*> frame, static MOZ_MUST_USE bool getScriptFrameIter(JSContext* cx, Handle<DebuggerFrame*> frame,
mozilla::Maybe<ScriptFrameIter>& result); mozilla::Maybe<ScriptFrameIter>& result);
@ -1171,6 +1174,7 @@ class DebuggerFrame : public NativeObject
static MOZ_MUST_USE bool constructingGetter(JSContext* cx, unsigned argc, Value* vp); static MOZ_MUST_USE bool constructingGetter(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool environmentGetter(JSContext* cx, unsigned argc, Value* vp); static MOZ_MUST_USE bool environmentGetter(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool generatorGetter(JSContext* cx, unsigned argc, Value* vp); static MOZ_MUST_USE bool generatorGetter(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool liveGetter(JSContext* cx, unsigned argc, Value* vp);
Debugger* owner() const; Debugger* owner() const;
}; };