author | Eddy Bruel <ejpbruel@mozilla.com> |
Wed, 20 Jul 2016 13:50:04 +0200 | |
changeset 306055 | ae502e2271f2464d92ef398d7c8c43f835865bd6 |
parent 306054 | 0a0f2f8db1e6faa3a56fa69aa280bfbae507c4d3 |
child 306056 | 1de4835bc1414570182a83e94a9eb1b644cb7c43 |
push id | 30474 |
push user | cbook@mozilla.com |
push date | Thu, 21 Jul 2016 14:25:10 +0000 |
treeherder | mozilla-central@6b180266ac16 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | fitzgen |
bugs | 1271650 |
milestone | 50.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
js/src/vm/Debugger.cpp | file | annotate | diff | comparison | revisions | |
js/src/vm/Debugger.h | file | annotate | diff | comparison | revisions |
--- a/js/src/vm/Debugger.cpp +++ b/js/src/vm/Debugger.cpp @@ -7073,31 +7073,35 @@ DebuggerFrame::create(JSContext* cx, Han return &frame; } /* static */ bool DebuggerFrame::getCallee(JSContext* cx, Handle<DebuggerFrame*> frame, MutableHandle<DebuggerObject*> result) { + MOZ_ASSERT(frame->isLive()); + AbstractFramePtr referent = DebuggerFrame::getReferent(frame); if (!referent.isFunctionFrame()) { result.set(nullptr); return true; } Debugger* dbg = frame->owner(); RootedObject callee(cx, referent.callee()); return dbg->wrapDebuggeeObject(cx, callee, result); } /* static */ bool DebuggerFrame::getIsConstructing(JSContext* cx, Handle<DebuggerFrame*> frame, bool& result) { + MOZ_ASSERT(frame->isLive()); + Maybe<ScriptFrameIter> maybeIter; if (!DebuggerFrame::getScriptFrameIter(cx, frame, maybeIter)) return false; ScriptFrameIter& iter = *maybeIter; result = iter.isFunctionFrame() && iter.isConstructing(); return true; } @@ -7138,16 +7142,18 @@ UpdateFrameIterPc(FrameIter& iter) iter.updatePcQuadratic(); } /* static */ bool DebuggerFrame::getEnvironment(JSContext* cx, Handle<DebuggerFrame*> frame, MutableHandle<DebuggerEnvironment*> result) { + MOZ_ASSERT(frame->isLive()); + Debugger* dbg = frame->owner(); Maybe<ScriptFrameIter> maybeIter; if (!DebuggerFrame::getScriptFrameIter(cx, frame, maybeIter)) return false; ScriptFrameIter& iter = *maybeIter; Rooted<Env*> env(cx); @@ -7163,16 +7169,34 @@ DebuggerFrame::getEnvironment(JSContext* } /* static */ bool DebuggerFrame::getIsGenerator(Handle<DebuggerFrame*> frame) { 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 DebuggerFrame::getReferent(Handle<DebuggerFrame*> frame) { AbstractFramePtr referent = AbstractFramePtr::FromRaw(frame->getPrivate()); if (referent.isScriptFrameIterData()) { ScriptFrameIter iter(*(ScriptFrameIter::Data*)(referent.raw())); referent = iter.abstractFramePtr(); } @@ -7230,37 +7254,36 @@ DebuggerFrame::checkThis(JSContext* cx, if (!thisobj) return nullptr; if (thisobj->getClass() != &DebuggerFrame::class_) { JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO, "Debugger.Frame", fnname, thisobj->getClass()->name); return nullptr; } - DebuggerFrame* nthisobj = &thisobj->as<DebuggerFrame>(); + Rooted<DebuggerFrame*> frame(cx, &thisobj->as<DebuggerFrame>()); /* * Forbid Debugger.Frame.prototype, which is of class DebuggerFrame::class_ * but isn't really a working Debugger.Frame object. The prototype object * is distinguished by having a nullptr private value. Also, forbid popped * frames. */ - if (!nthisobj->getPrivate()) { - if (nthisobj->getReservedSlot(JSSLOT_DEBUGFRAME_OWNER).isUndefined()) { - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO, - "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 (!frame->getPrivate() && + frame->getReservedSlot(JSSLOT_DEBUGFRAME_OWNER).isUndefined()) + { + JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO, + "Debugger.Frame", fnname, "prototype object"); + return nullptr; + } + + if (checkLive && !DebuggerFrame::requireLive(cx, frame)) + return nullptr; + + return frame; } /* * To make frequently fired hooks like onEnterFrame more performant, * Debugger.Frame methods should not create a ScriptFrameIter unless it * absolutely needs to. That is, unless the method has to call a method on * ScriptFrameIter that's otherwise not available on AbstractFramePtr. * @@ -7607,25 +7630,25 @@ DebuggerFrame_getOffset(JSContext* cx, u JSScript* script = iter.script(); UpdateFrameIterPc(iter); jsbytecode* pc = iter.pc(); size_t offset = script->pcToOffset(pc); args.rval().setNumber(double(offset)); return true; } -static bool -DebuggerFrame_getLive(JSContext* cx, unsigned argc, Value* vp) +/* static */ bool +DebuggerFrame::liveGetter(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); - NativeObject* thisobj = DebuggerFrame::checkThis(cx, args, "get live", false); - if (!thisobj) - return false; - bool hasFrame = !!thisobj->getPrivate(); - args.rval().setBoolean(hasFrame); + Rooted<DebuggerFrame*> frame(cx, DebuggerFrame::checkThis(cx, args, "get live", false)); + if (!frame) + return false; + + args.rval().setBoolean(frame->isLive()); return true; } static bool IsValidHook(const Value& v) { return v.isUndefined() || (v.isObject() && v.toObject().isCallable()); } @@ -7925,17 +7948,17 @@ DebuggerFrame::construct(JSContext* cx, } const JSPropertySpec DebuggerFrame::properties_[] = { JS_PSG("arguments", DebuggerFrame_getArguments, 0), JS_PSG("callee", DebuggerFrame::calleeGetter, 0), JS_PSG("constructing", DebuggerFrame::constructingGetter, 0), JS_PSG("environment", DebuggerFrame::environmentGetter, 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("older", DebuggerFrame_getOlder, 0), JS_PSG("script", DebuggerFrame_getScript, 0), JS_PSG("this", DebuggerFrame_getThis, 0), JS_PSG("type", DebuggerFrame_getType, 0), JS_PSG("implementation", DebuggerFrame_getImplementation, 0), JS_PSGS("onStep", DebuggerFrame_getOnStep, DebuggerFrame_setOnStep, 0), JS_PSGS("onPop", DebuggerFrame_getOnPop, DebuggerFrame_setOnPop, 0),
--- a/js/src/vm/Debugger.h +++ b/js/src/vm/Debugger.h @@ -1150,32 +1150,36 @@ class DebuggerFrame : public NativeObjec static MOZ_MUST_USE bool getCallee(JSContext* cx, Handle<DebuggerFrame*> frame, MutableHandle<DebuggerObject*> result); static MOZ_MUST_USE bool getIsConstructing(JSContext* cx, Handle<DebuggerFrame*> frame, bool& result); static MOZ_MUST_USE bool getEnvironment(JSContext* cx, Handle<DebuggerFrame*> frame, MutableHandle<DebuggerEnvironment*> result); static bool getIsGenerator(Handle<DebuggerFrame*> frame); + bool isLive() const; + private: static const ClassOps classOps_; static const JSPropertySpec properties_[]; static const JSFunctionSpec methods_[]; + static MOZ_MUST_USE bool requireLive(JSContext* cx, Handle<DebuggerFrame*> frame); static AbstractFramePtr getReferent(Handle<DebuggerFrame*> frame); static MOZ_MUST_USE bool getScriptFrameIter(JSContext* cx, Handle<DebuggerFrame*> frame, mozilla::Maybe<ScriptFrameIter>& result); static MOZ_MUST_USE bool construct(JSContext* cx, unsigned argc, Value* vp); static MOZ_MUST_USE bool calleeGetter(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 generatorGetter(JSContext* cx, unsigned argc, Value* vp); + static MOZ_MUST_USE bool liveGetter(JSContext* cx, unsigned argc, Value* vp); Debugger* owner() const; }; class DebuggerObject : public NativeObject { public: static const Class class_;