Bug 1564167 - Use CallData structure instead of macros to handle calls to debugger APIs, r=jimb.

Differential Revision: https://phabricator.services.mozilla.com/D44590

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Brian Hackett 2019-09-09 21:47:17 +00:00
Родитель c2bb091273
Коммит d980ac2d9f
14 изменённых файлов: 998 добавлений и 1558 удалений

Просмотреть файл

@ -4003,13 +4003,77 @@ static Debugger* Debugger_fromThisValue(JSContext* cx, const CallArgs& args,
return dbg;
}
#define THIS_DEBUGGER(cx, argc, vp, fnname, args, dbg) \
CallArgs args = CallArgsFromVp(argc, vp); \
Debugger* dbg = Debugger_fromThisValue(cx, args, fnname); \
if (!dbg) return false
struct MOZ_STACK_CLASS Debugger::CallData {
JSContext* cx;
const CallArgs& args;
Debugger* dbg;
CallData(JSContext* cx, const CallArgs& args, Debugger* dbg)
: cx(cx), args(args), dbg(dbg) {}
bool getOnDebuggerStatement();
bool setOnDebuggerStatement();
bool getOnExceptionUnwind();
bool setOnExceptionUnwind();
bool getOnNewScript();
bool setOnNewScript();
bool getOnEnterFrame();
bool setOnEnterFrame();
bool getOnNativeCall();
bool setOnNativeCall();
bool getOnNewGlobalObject();
bool setOnNewGlobalObject();
bool getOnNewPromise();
bool setOnNewPromise();
bool getOnPromiseSettled();
bool setOnPromiseSettled();
bool getUncaughtExceptionHook();
bool setUncaughtExceptionHook();
bool getAllowUnobservedAsmJS();
bool setAllowUnobservedAsmJS();
bool getCollectCoverageInfo();
bool setCollectCoverageInfo();
bool getMemory();
bool addDebuggee();
bool addAllGlobalsAsDebuggees();
bool removeDebuggee();
bool removeAllDebuggees();
bool hasDebuggee();
bool getDebuggees();
bool getNewestFrame();
bool clearAllBreakpoints();
bool findScripts();
bool findSources();
bool findObjects();
bool findAllGlobals();
bool findSourceURLs();
bool makeGlobalObjectReference();
bool adoptDebuggeeValue();
bool adoptSource();
using Method = bool (CallData::*)();
template <Method MyMethod>
static bool ToNative(JSContext* cx, unsigned argc, Value* vp);
};
template <Debugger::CallData::Method MyMethod>
/* static */
bool Debugger::CallData::ToNative(JSContext* cx, unsigned argc, Value* vp) {
CallArgs args = CallArgsFromVp(argc, vp);
Debugger* dbg = Debugger_fromThisValue(cx, args, "method");
if (!dbg) {
return false;
}
CallData data(cx, args, dbg);
return (data.*MyMethod)();
}
/* static */
bool Debugger::getHookImpl(JSContext* cx, CallArgs& args, Debugger& dbg,
bool Debugger::getHookImpl(JSContext* cx, const CallArgs& args, Debugger& dbg,
Hook which) {
MOZ_ASSERT(which >= 0 && which < HookCount);
args.rval().set(dbg.object->getReservedSlot(JSSLOT_DEBUG_HOOK_START + which));
@ -4017,7 +4081,7 @@ bool Debugger::getHookImpl(JSContext* cx, CallArgs& args, Debugger& dbg,
}
/* static */
bool Debugger::setHookImpl(JSContext* cx, CallArgs& args, Debugger& dbg,
bool Debugger::setHookImpl(JSContext* cx, const CallArgs& args, Debugger& dbg,
Hook which) {
MOZ_ASSERT(which >= 0 && which < HookCount);
if (!args.requireAtLeast(cx, "Debugger.setHook", 1)) {
@ -4046,99 +4110,67 @@ bool Debugger::setHookImpl(JSContext* cx, CallArgs& args, Debugger& dbg,
return true;
}
/* static */
bool Debugger::getOnDebuggerStatement(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "(get onDebuggerStatement)", args, dbg);
bool Debugger::CallData::getOnDebuggerStatement() {
return getHookImpl(cx, args, *dbg, OnDebuggerStatement);
}
/* static */
bool Debugger::setOnDebuggerStatement(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "(set onDebuggerStatement)", args, dbg);
bool Debugger::CallData::setOnDebuggerStatement() {
return setHookImpl(cx, args, *dbg, OnDebuggerStatement);
}
/* static */
bool Debugger::getOnExceptionUnwind(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "(get onExceptionUnwind)", args, dbg);
bool Debugger::CallData::getOnExceptionUnwind() {
return getHookImpl(cx, args, *dbg, OnExceptionUnwind);
}
/* static */
bool Debugger::setOnExceptionUnwind(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "(set onExceptionUnwind)", args, dbg);
bool Debugger::CallData::setOnExceptionUnwind() {
return setHookImpl(cx, args, *dbg, OnExceptionUnwind);
}
/* static */
bool Debugger::getOnNewScript(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "(get onNewScript)", args, dbg);
bool Debugger::CallData::getOnNewScript() {
return getHookImpl(cx, args, *dbg, OnNewScript);
}
/* static */
bool Debugger::setOnNewScript(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "(set onNewScript)", args, dbg);
bool Debugger::CallData::setOnNewScript() {
return setHookImpl(cx, args, *dbg, OnNewScript);
}
/* static */
bool Debugger::getOnNewPromise(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "(get onNewPromise)", args, dbg);
bool Debugger::CallData::getOnNewPromise() {
return getHookImpl(cx, args, *dbg, OnNewPromise);
}
/* static */
bool Debugger::setOnNewPromise(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "(set onNewPromise)", args, dbg);
bool Debugger::CallData::setOnNewPromise() {
return setHookImpl(cx, args, *dbg, OnNewPromise);
}
/* static */
bool Debugger::getOnPromiseSettled(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "(get onPromiseSettled)", args, dbg);
bool Debugger::CallData::getOnPromiseSettled() {
return getHookImpl(cx, args, *dbg, OnPromiseSettled);
}
/* static */
bool Debugger::setOnPromiseSettled(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "(set onPromiseSettled)", args, dbg);
bool Debugger::CallData::setOnPromiseSettled() {
return setHookImpl(cx, args, *dbg, OnPromiseSettled);
}
/* static */
bool Debugger::getOnEnterFrame(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "(get onEnterFrame)", args, dbg);
bool Debugger::CallData::getOnEnterFrame() {
return getHookImpl(cx, args, *dbg, OnEnterFrame);
}
/* static */
bool Debugger::setOnEnterFrame(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "(set onEnterFrame)", args, dbg);
bool Debugger::CallData::setOnEnterFrame() {
return setHookImpl(cx, args, *dbg, OnEnterFrame);
}
/* static */
bool Debugger::getOnNativeCall(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "(get onNativeCall)", args, dbg);
bool Debugger::CallData::getOnNativeCall() {
return getHookImpl(cx, args, *dbg, OnNativeCall);
}
/* static */
bool Debugger::setOnNativeCall(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "(set onNativeCall)", args, dbg);
bool Debugger::CallData::setOnNativeCall() {
return setHookImpl(cx, args, *dbg, OnNativeCall);
}
/* static */
bool Debugger::getOnNewGlobalObject(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "(get onNewGlobalObject)", args, dbg);
bool Debugger::CallData::getOnNewGlobalObject() {
return getHookImpl(cx, args, *dbg, OnNewGlobalObject);
}
/* static */
bool Debugger::setOnNewGlobalObject(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "setOnNewGlobalObject", args, dbg);
bool Debugger::CallData::setOnNewGlobalObject() {
RootedObject oldHook(cx, dbg->getHook(OnNewGlobalObject));
if (!setHookImpl(cx, args, *dbg, OnNewGlobalObject)) {
@ -4157,18 +4189,12 @@ bool Debugger::setOnNewGlobalObject(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
/* static */
bool Debugger::getUncaughtExceptionHook(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "get uncaughtExceptionHook", args, dbg);
bool Debugger::CallData::getUncaughtExceptionHook() {
args.rval().setObjectOrNull(dbg->uncaughtExceptionHook);
return true;
}
/* static */
bool Debugger::setUncaughtExceptionHook(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "set uncaughtExceptionHook", args, dbg);
bool Debugger::CallData::setUncaughtExceptionHook() {
if (!args.requireAtLeast(cx, "Debugger.set uncaughtExceptionHook", 1)) {
return false;
}
@ -4184,18 +4210,12 @@ bool Debugger::setUncaughtExceptionHook(JSContext* cx, unsigned argc,
return true;
}
/* static */
bool Debugger::getAllowUnobservedAsmJS(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "get allowUnobservedAsmJS", args, dbg);
bool Debugger::CallData::getAllowUnobservedAsmJS() {
args.rval().setBoolean(dbg->allowUnobservedAsmJS);
return true;
}
/* static */
bool Debugger::setAllowUnobservedAsmJS(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "set allowUnobservedAsmJS", args, dbg);
bool Debugger::CallData::setAllowUnobservedAsmJS() {
if (!args.requireAtLeast(cx, "Debugger.set allowUnobservedAsmJS", 1)) {
return false;
}
@ -4212,16 +4232,12 @@ bool Debugger::setAllowUnobservedAsmJS(JSContext* cx, unsigned argc,
return true;
}
/* static */
bool Debugger::getCollectCoverageInfo(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "get collectCoverageInfo", args, dbg);
bool Debugger::CallData::getCollectCoverageInfo() {
args.rval().setBoolean(dbg->collectCoverageInfo);
return true;
}
/* static */
bool Debugger::setCollectCoverageInfo(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "set collectCoverageInfo", args, dbg);
bool Debugger::CallData::setCollectCoverageInfo() {
if (!args.requireAtLeast(cx, "Debugger.set collectCoverageInfo", 1)) {
return false;
}
@ -4236,9 +4252,7 @@ bool Debugger::setCollectCoverageInfo(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
/* static */
bool Debugger::getMemory(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "get memory", args, dbg);
bool Debugger::CallData::getMemory() {
Value memoryValue =
dbg->object->getReservedSlot(JSSLOT_DEBUG_MEMORY_INSTANCE);
@ -4303,9 +4317,7 @@ GlobalObject* Debugger::unwrapDebuggeeArgument(JSContext* cx, const Value& v) {
return &obj->as<GlobalObject>();
}
/* static */
bool Debugger::addDebuggee(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "addDebuggee", args, dbg);
bool Debugger::CallData::addDebuggee() {
if (!args.requireAtLeast(cx, "Debugger.addDebuggee", 1)) {
return false;
}
@ -4326,10 +4338,7 @@ bool Debugger::addDebuggee(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
/* static */
bool Debugger::addAllGlobalsAsDebuggees(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "addAllGlobalsAsDebuggees", args, dbg);
bool Debugger::CallData::addAllGlobalsAsDebuggees() {
for (CompartmentsIter comp(cx->runtime()); !comp.done(); comp.next()) {
if (comp == dbg->object->compartment()) {
continue;
@ -4353,10 +4362,7 @@ bool Debugger::addAllGlobalsAsDebuggees(JSContext* cx, unsigned argc,
return true;
}
/* static */
bool Debugger::removeDebuggee(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "removeDebuggee", args, dbg);
bool Debugger::CallData::removeDebuggee() {
if (!args.requireAtLeast(cx, "Debugger.removeDebuggee", 1)) {
return false;
}
@ -4386,10 +4392,7 @@ bool Debugger::removeDebuggee(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
/* static */
bool Debugger::removeAllDebuggees(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "removeAllDebuggees", args, dbg);
bool Debugger::CallData::removeAllDebuggees() {
ExecutionObservableRealms obs(cx);
for (WeakGlobalObjectSet::Enum e(dbg->debuggees); !e.empty(); e.popFront()) {
@ -4411,9 +4414,7 @@ bool Debugger::removeAllDebuggees(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
/* static */
bool Debugger::hasDebuggee(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "hasDebuggee", args, dbg);
bool Debugger::CallData::hasDebuggee() {
if (!args.requireAtLeast(cx, "Debugger.hasDebuggee", 1)) {
return false;
}
@ -4425,10 +4426,7 @@ bool Debugger::hasDebuggee(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
/* static */
bool Debugger::getDebuggees(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "getDebuggees", args, dbg);
bool Debugger::CallData::getDebuggees() {
// Obtain the list of debuggees before wrapping each debuggee, as a GC could
// update the debuggees set while we are iterating it.
unsigned count = dbg->debuggees.count();
@ -4462,10 +4460,7 @@ bool Debugger::getDebuggees(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
/* static */
bool Debugger::getNewestFrame(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "getNewestFrame", args, dbg);
bool Debugger::CallData::getNewestFrame() {
// Since there may be multiple contexts, use AllFramesIter.
for (AllFramesIter i(cx); !i.done(); ++i) {
if (dbg->observesFrame(i)) {
@ -4487,9 +4482,7 @@ bool Debugger::getNewestFrame(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
/* static */
bool Debugger::clearAllBreakpoints(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "clearAllBreakpoints", args, dbg);
bool Debugger::CallData::clearAllBreakpoints() {
for (WeakGlobalObjectSet::Range r = dbg->debuggees.all(); !r.empty();
r.popFront()) {
DebugScript::clearBreakpointsIn(cx->runtime()->defaultFreeOp(),
@ -5387,10 +5380,7 @@ class MOZ_STACK_CLASS Debugger::ScriptQuery : public Debugger::QueryBase {
}
};
/* static */
bool Debugger::findScripts(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "findScripts", args, dbg);
bool Debugger::CallData::findScripts() {
ScriptQuery query(cx, dbg);
if (args.length() >= 1) {
@ -5574,10 +5564,7 @@ static inline DebuggerSourceReferent AsSourceReferent(JSObject* obj) {
return AsVariant(&obj->as<WasmInstanceObject>());
}
/* static */
bool Debugger::findSources(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "findSources", args, dbg);
bool Debugger::CallData::findSources() {
SourceQuery query(cx, dbg);
if (!query.findSources()) {
return false;
@ -5790,9 +5777,7 @@ class MOZ_STACK_CLASS Debugger::ObjectQuery {
}
};
bool Debugger::findObjects(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "findObjects", args, dbg);
bool Debugger::CallData::findObjects() {
ObjectQuery query(cx, dbg);
if (args.length() >= 1) {
@ -5828,10 +5813,7 @@ bool Debugger::findObjects(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
/* static */
bool Debugger::findAllGlobals(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "findAllGlobals", args, dbg);
bool Debugger::CallData::findAllGlobals() {
RootedObjectVector globals(cx);
{
@ -5889,10 +5871,7 @@ bool Debugger::findAllGlobals(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
/* static */
bool Debugger::findSourceURLs(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "findSourceURLs", args, dbg);
bool Debugger::CallData::findSourceURLs() {
RootedObject result(cx, NewDenseEmptyArray(cx));
if (!result) {
return false;
@ -5922,10 +5901,7 @@ bool Debugger::findSourceURLs(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
/* static */
bool Debugger::makeGlobalObjectReference(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "makeGlobalObjectReference", args, dbg);
bool Debugger::CallData::makeGlobalObjectReference() {
if (!args.requireAtLeast(cx, "Debugger.makeGlobalObjectReference", 1)) {
return false;
}
@ -6030,8 +6006,7 @@ bool Debugger::recordReplayProcessKind(JSContext* cx, unsigned argc,
return true;
}
bool Debugger::adoptDebuggeeValue(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "adoptDebuggeeValue", args, dbg);
bool Debugger::CallData::adoptDebuggeeValue() {
if (!args.requireAtLeast(cx, "Debugger.adoptDebuggeeValue", 1)) {
return false;
}
@ -6084,8 +6059,7 @@ class DebuggerAdoptSourceMatcher {
}
};
bool Debugger::adoptSource(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER(cx, argc, vp, "adoptSource", args, dbg);
bool Debugger::CallData::adoptSource() {
if (!args.requireAtLeast(cx, "Debugger.adoptSource", 1)) {
return false;
}
@ -6120,49 +6094,43 @@ bool Debugger::adoptSource(JSContext* cx, unsigned argc, Value* vp) {
}
const JSPropertySpec Debugger::properties[] = {
JS_PSGS("onDebuggerStatement", Debugger::getOnDebuggerStatement,
Debugger::setOnDebuggerStatement, 0),
JS_PSGS("onExceptionUnwind", Debugger::getOnExceptionUnwind,
Debugger::setOnExceptionUnwind, 0),
JS_PSGS("onNewScript", Debugger::getOnNewScript, Debugger::setOnNewScript,
0),
JS_PSGS("onNewPromise", Debugger::getOnNewPromise,
Debugger::setOnNewPromise, 0),
JS_PSGS("onPromiseSettled", Debugger::getOnPromiseSettled,
Debugger::setOnPromiseSettled, 0),
JS_PSGS("onEnterFrame", Debugger::getOnEnterFrame,
Debugger::setOnEnterFrame, 0),
JS_PSGS("onNativeCall", Debugger::getOnNativeCall,
Debugger::setOnNativeCall, 0),
JS_PSGS("onNewGlobalObject", Debugger::getOnNewGlobalObject,
Debugger::setOnNewGlobalObject, 0),
JS_PSGS("uncaughtExceptionHook", Debugger::getUncaughtExceptionHook,
Debugger::setUncaughtExceptionHook, 0),
JS_PSGS("allowUnobservedAsmJS", Debugger::getAllowUnobservedAsmJS,
Debugger::setAllowUnobservedAsmJS, 0),
JS_PSGS("collectCoverageInfo", Debugger::getCollectCoverageInfo,
Debugger::setCollectCoverageInfo, 0),
JS_PSG("memory", Debugger::getMemory, 0),
JS_DEBUG_PSGS("onDebuggerStatement", getOnDebuggerStatement,
setOnDebuggerStatement),
JS_DEBUG_PSGS("onExceptionUnwind", getOnExceptionUnwind,
setOnExceptionUnwind),
JS_DEBUG_PSGS("onNewScript", getOnNewScript, setOnNewScript),
JS_DEBUG_PSGS("onNewPromise", getOnNewPromise, setOnNewPromise),
JS_DEBUG_PSGS("onPromiseSettled", getOnPromiseSettled, setOnPromiseSettled),
JS_DEBUG_PSGS("onEnterFrame", getOnEnterFrame, setOnEnterFrame),
JS_DEBUG_PSGS("onNativeCall", getOnNativeCall, setOnNativeCall),
JS_DEBUG_PSGS("onNewGlobalObject", getOnNewGlobalObject,
setOnNewGlobalObject),
JS_DEBUG_PSGS("uncaughtExceptionHook", getUncaughtExceptionHook,
setUncaughtExceptionHook),
JS_DEBUG_PSGS("allowUnobservedAsmJS", getAllowUnobservedAsmJS,
setAllowUnobservedAsmJS),
JS_DEBUG_PSGS("collectCoverageInfo", getCollectCoverageInfo,
setCollectCoverageInfo),
JS_DEBUG_PSG("memory", getMemory),
JS_PS_END};
const JSFunctionSpec Debugger::methods[] = {
JS_FN("addDebuggee", Debugger::addDebuggee, 1, 0),
JS_FN("addAllGlobalsAsDebuggees", Debugger::addAllGlobalsAsDebuggees, 0, 0),
JS_FN("removeDebuggee", Debugger::removeDebuggee, 1, 0),
JS_FN("removeAllDebuggees", Debugger::removeAllDebuggees, 0, 0),
JS_FN("hasDebuggee", Debugger::hasDebuggee, 1, 0),
JS_FN("getDebuggees", Debugger::getDebuggees, 0, 0),
JS_FN("getNewestFrame", Debugger::getNewestFrame, 0, 0),
JS_FN("clearAllBreakpoints", Debugger::clearAllBreakpoints, 0, 0),
JS_FN("findScripts", Debugger::findScripts, 1, 0),
JS_FN("findSources", Debugger::findSources, 1, 0),
JS_FN("findObjects", Debugger::findObjects, 1, 0),
JS_FN("findAllGlobals", Debugger::findAllGlobals, 0, 0),
JS_FN("findSourceURLs", Debugger::findSourceURLs, 0, 0),
JS_FN("makeGlobalObjectReference", Debugger::makeGlobalObjectReference, 1,
0),
JS_FN("adoptDebuggeeValue", Debugger::adoptDebuggeeValue, 1, 0),
JS_FN("adoptSource", Debugger::adoptSource, 1, 0),
JS_DEBUG_FN("addDebuggee", addDebuggee, 1),
JS_DEBUG_FN("addAllGlobalsAsDebuggees", addAllGlobalsAsDebuggees, 0),
JS_DEBUG_FN("removeDebuggee", removeDebuggee, 1),
JS_DEBUG_FN("removeAllDebuggees", removeAllDebuggees, 0),
JS_DEBUG_FN("hasDebuggee", hasDebuggee, 1),
JS_DEBUG_FN("getDebuggees", getDebuggees, 0),
JS_DEBUG_FN("getNewestFrame", getNewestFrame, 0),
JS_DEBUG_FN("clearAllBreakpoints", clearAllBreakpoints, 0),
JS_DEBUG_FN("findScripts", findScripts, 1),
JS_DEBUG_FN("findSources", findSources, 1),
JS_DEBUG_FN("findObjects", findObjects, 1),
JS_DEBUG_FN("findAllGlobals", findAllGlobals, 0),
JS_DEBUG_FN("findSourceURLs", findSourceURLs, 0),
JS_DEBUG_FN("makeGlobalObjectReference", makeGlobalObjectReference, 1),
JS_DEBUG_FN("adoptDebuggeeValue", adoptDebuggeeValue, 1),
JS_DEBUG_FN("adoptSource", adoptSource, 1),
JS_FS_END};
const JSFunctionSpec Debugger::static_methods[]{

Просмотреть файл

@ -839,64 +839,17 @@ class Debugger : private mozilla::LinkedListElement<Debugger> {
template <typename F>
void forEachWeakMap(const F& f);
static MOZ_MUST_USE bool getHookImpl(JSContext* cx, CallArgs& args,
static MOZ_MUST_USE bool getHookImpl(JSContext* cx, const CallArgs& args,
Debugger& dbg, Hook which);
static MOZ_MUST_USE bool setHookImpl(JSContext* cx, CallArgs& args,
static MOZ_MUST_USE bool setHookImpl(JSContext* cx, const CallArgs& args,
Debugger& dbg, Hook which);
static bool getOnDebuggerStatement(JSContext* cx, unsigned argc, Value* vp);
static bool setOnDebuggerStatement(JSContext* cx, unsigned argc, Value* vp);
static bool getOnExceptionUnwind(JSContext* cx, unsigned argc, Value* vp);
static bool setOnExceptionUnwind(JSContext* cx, unsigned argc, Value* vp);
static bool getOnNewScript(JSContext* cx, unsigned argc, Value* vp);
static bool setOnNewScript(JSContext* cx, unsigned argc, Value* vp);
static bool getOnEnterFrame(JSContext* cx, unsigned argc, Value* vp);
static bool setOnEnterFrame(JSContext* cx, unsigned argc, Value* vp);
static bool getOnNativeCall(JSContext* cx, unsigned argc, Value* vp);
static bool setOnNativeCall(JSContext* cx, unsigned argc, Value* vp);
static bool getOnNewGlobalObject(JSContext* cx, unsigned argc, Value* vp);
static bool setOnNewGlobalObject(JSContext* cx, unsigned argc, Value* vp);
static bool getOnNewPromise(JSContext* cx, unsigned argc, Value* vp);
static bool setOnNewPromise(JSContext* cx, unsigned argc, Value* vp);
static bool getOnPromiseSettled(JSContext* cx, unsigned argc, Value* vp);
static bool setOnPromiseSettled(JSContext* cx, unsigned argc, Value* vp);
static bool getUncaughtExceptionHook(JSContext* cx, unsigned argc, Value* vp);
static bool setUncaughtExceptionHook(JSContext* cx, unsigned argc, Value* vp);
static bool getAllowUnobservedAsmJS(JSContext* cx, unsigned argc, Value* vp);
static bool setAllowUnobservedAsmJS(JSContext* cx, unsigned argc, Value* vp);
static bool getCollectCoverageInfo(JSContext* cx, unsigned argc, Value* vp);
static bool setCollectCoverageInfo(JSContext* cx, unsigned argc, Value* vp);
static bool getMemory(JSContext* cx, unsigned argc, Value* vp);
static bool addDebuggee(JSContext* cx, unsigned argc, Value* vp);
static bool addAllGlobalsAsDebuggees(JSContext* cx, unsigned argc, Value* vp);
static bool removeDebuggee(JSContext* cx, unsigned argc, Value* vp);
static bool removeAllDebuggees(JSContext* cx, unsigned argc, Value* vp);
static bool hasDebuggee(JSContext* cx, unsigned argc, Value* vp);
static bool getDebuggees(JSContext* cx, unsigned argc, Value* vp);
static bool getNewestFrame(JSContext* cx, unsigned argc, Value* vp);
static bool clearAllBreakpoints(JSContext* cx, unsigned argc, Value* vp);
static bool findScripts(JSContext* cx, unsigned argc, Value* vp);
static bool findSources(JSContext* cx, unsigned argc, Value* vp);
static bool findObjects(JSContext* cx, unsigned argc, Value* vp);
static bool findAllGlobals(JSContext* cx, unsigned argc, Value* vp);
static bool findSourceURLs(JSContext* cx, unsigned argc, Value* vp);
static bool makeGlobalObjectReference(JSContext* cx, unsigned argc,
Value* vp);
static bool setupTraceLoggerScriptCalls(JSContext* cx, unsigned argc,
Value* vp);
static bool drainTraceLoggerScriptCalls(JSContext* cx, unsigned argc,
Value* vp);
static bool startTraceLogger(JSContext* cx, unsigned argc, Value* vp);
static bool endTraceLogger(JSContext* cx, unsigned argc, Value* vp);
static bool isCompilableUnit(JSContext* cx, unsigned argc, Value* vp);
static bool recordReplayProcessKind(JSContext* cx, unsigned argc, Value* vp);
#ifdef NIGHTLY_BUILD
static bool setupTraceLogger(JSContext* cx, unsigned argc, Value* vp);
static bool drainTraceLogger(JSContext* cx, unsigned argc, Value* vp);
#endif
static bool adoptDebuggeeValue(JSContext* cx, unsigned argc, Value* vp);
static bool adoptSource(JSContext* cx, unsigned argc, Value* vp);
static bool construct(JSContext* cx, unsigned argc, Value* vp);
struct CallData;
static const JSPropertySpec properties[];
static const JSFunctionSpec methods[];
static const JSFunctionSpec static_methods[];
@ -1459,6 +1412,16 @@ Result<Completion> DebuggerGenericEval(
bool ParseResumptionValue(JSContext* cx, HandleValue rval,
ResumeMode& resumeMode, MutableHandleValue vp);
#define JS_DEBUG_PSG(Name, Getter) \
JS_PSG(Name, CallData::ToNative<&CallData::Getter>, 0)
#define JS_DEBUG_PSGS(Name, Getter, Setter) \
JS_PSGS(Name, CallData::ToNative<&CallData::Getter>, \
CallData::ToNative<&CallData::Setter>, 0)
#define JS_DEBUG_FN(Name, Method, NumArgs) \
JS_FN(Name, CallData::ToNative<&CallData::Method>, NumArgs, 0)
} /* namespace js */
namespace JS {

Просмотреть файл

@ -69,8 +69,7 @@ bool DebuggerMemory::construct(JSContext* cx, unsigned argc, Value* vp) {
"Memory", JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(JSSLOT_COUNT)};
/* static */
DebuggerMemory* DebuggerMemory::checkThis(JSContext* cx, CallArgs& args,
const char* fnName) {
DebuggerMemory* DebuggerMemory::checkThis(JSContext* cx, CallArgs& args) {
const Value& thisValue = args.thisv();
if (!thisValue.isObject()) {
@ -83,7 +82,7 @@ DebuggerMemory* DebuggerMemory::checkThis(JSContext* cx, CallArgs& args,
JSObject& thisObject = thisValue.toObject();
if (!thisObject.is<DebuggerMemory>()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_INCOMPATIBLE_PROTO, class_.name, fnName,
JSMSG_INCOMPATIBLE_PROTO, class_.name, "method",
thisObject.getClass()->name);
return nullptr;
}
@ -96,7 +95,7 @@ DebuggerMemory* DebuggerMemory::checkThis(JSContext* cx, CallArgs& args,
.getReservedSlot(JSSLOT_DEBUGGER)
.isUndefined()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_INCOMPATIBLE_PROTO, class_.name, fnName,
JSMSG_INCOMPATIBLE_PROTO, class_.name, "method",
"prototype object");
return nullptr;
}
@ -104,34 +103,58 @@ DebuggerMemory* DebuggerMemory::checkThis(JSContext* cx, CallArgs& args,
return &thisObject.as<DebuggerMemory>();
}
/**
* Get the |DebuggerMemory*| from the current this value and handle any errors
* that might occur therein.
*
* These parameters must already exist when calling this macro:
* - JSContext* cx
* - unsigned argc
* - Value* vp
* - const char* fnName
* These parameters will be defined after calling this macro:
* - CallArgs args
* - DebuggerMemory* memory (will be non-null)
*/
#define THIS_DEBUGGER_MEMORY(cx, argc, vp, fnName, args, memory) \
CallArgs args = CallArgsFromVp(argc, vp); \
Rooted<DebuggerMemory*> memory(cx, checkThis(cx, args, fnName)); \
if (!memory) return false
struct MOZ_STACK_CLASS DebuggerMemory::CallData {
JSContext* cx;
const CallArgs& args;
static bool undefined(CallArgs& args) {
Handle<DebuggerMemory*> memory;
CallData(JSContext* cx, const CallArgs& args, Handle<DebuggerMemory*> memory)
: cx(cx), args(args), memory(memory) {}
// Accessor properties of Debugger.Memory.prototype.
bool setTrackingAllocationSites();
bool getTrackingAllocationSites();
bool setMaxAllocationsLogLength();
bool getMaxAllocationsLogLength();
bool setAllocationSamplingProbability();
bool getAllocationSamplingProbability();
bool getAllocationsLogOverflowed();
bool getOnGarbageCollection();
bool setOnGarbageCollection();
// Function properties of Debugger.Memory.prototype.
bool takeCensus();
bool drainAllocationsLog();
using Method = bool (CallData::*)();
template <Method MyMethod>
static bool ToNative(JSContext* cx, unsigned argc, Value* vp);
};
template <DebuggerMemory::CallData::Method MyMethod>
/* static */
bool DebuggerMemory::CallData::ToNative(JSContext* cx, unsigned argc, Value* vp) {
CallArgs args = CallArgsFromVp(argc, vp);
Rooted<DebuggerMemory*> memory(cx, DebuggerMemory::checkThis(cx, args));
if (!memory) {
return false;
}
CallData data(cx, args, memory);
return (data.*MyMethod)();
}
static bool undefined(const CallArgs& args) {
args.rval().setUndefined();
return true;
}
/* static */
bool DebuggerMemory::setTrackingAllocationSites(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGGER_MEMORY(cx, argc, vp, "(set trackingAllocationSites)", args,
memory);
bool DebuggerMemory::CallData::setTrackingAllocationSites() {
if (!args.requireAtLeast(cx, "(set trackingAllocationSites)", 1)) {
return false;
}
@ -157,19 +180,12 @@ bool DebuggerMemory::setTrackingAllocationSites(JSContext* cx, unsigned argc,
return undefined(args);
}
/* static */
bool DebuggerMemory::getTrackingAllocationSites(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGGER_MEMORY(cx, argc, vp, "(get trackingAllocationSites)", args,
memory);
bool DebuggerMemory::CallData::getTrackingAllocationSites() {
args.rval().setBoolean(memory->getDebugger()->trackingAllocationSites);
return true;
}
/* static */
bool DebuggerMemory::drainAllocationsLog(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGGER_MEMORY(cx, argc, vp, "drainAllocationsLog", args, memory);
bool DebuggerMemory::CallData::drainAllocationsLog() {
Debugger* dbg = memory->getDebugger();
if (!dbg->trackingAllocationSites) {
@ -252,20 +268,12 @@ bool DebuggerMemory::drainAllocationsLog(JSContext* cx, unsigned argc,
return true;
}
/* static */
bool DebuggerMemory::getMaxAllocationsLogLength(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGGER_MEMORY(cx, argc, vp, "(get maxAllocationsLogLength)", args,
memory);
bool DebuggerMemory::CallData::getMaxAllocationsLogLength() {
args.rval().setInt32(memory->getDebugger()->maxAllocationsLogLength);
return true;
}
/* static */
bool DebuggerMemory::setMaxAllocationsLogLength(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGGER_MEMORY(cx, argc, vp, "(set maxAllocationsLogLength)", args,
memory);
bool DebuggerMemory::CallData::setMaxAllocationsLogLength() {
if (!args.requireAtLeast(cx, "(set maxAllocationsLogLength)", 1)) {
return false;
}
@ -293,22 +301,12 @@ bool DebuggerMemory::setMaxAllocationsLogLength(JSContext* cx, unsigned argc,
return true;
}
/* static */
bool DebuggerMemory::getAllocationSamplingProbability(JSContext* cx,
unsigned argc,
Value* vp) {
THIS_DEBUGGER_MEMORY(cx, argc, vp, "(get allocationSamplingProbability)",
args, memory);
bool DebuggerMemory::CallData::getAllocationSamplingProbability() {
args.rval().setDouble(memory->getDebugger()->allocationSamplingProbability);
return true;
}
/* static */
bool DebuggerMemory::setAllocationSamplingProbability(JSContext* cx,
unsigned argc,
Value* vp) {
THIS_DEBUGGER_MEMORY(cx, argc, vp, "(set allocationSamplingProbability)",
args, memory);
bool DebuggerMemory::CallData::setAllocationSamplingProbability() {
if (!args.requireAtLeast(cx, "(set allocationSamplingProbability)", 1)) {
return false;
}
@ -344,27 +342,17 @@ bool DebuggerMemory::setAllocationSamplingProbability(JSContext* cx,
return true;
}
/* static */
bool DebuggerMemory::getAllocationsLogOverflowed(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGGER_MEMORY(cx, argc, vp, "(get allocationsLogOverflowed)", args,
memory);
bool DebuggerMemory::CallData::getAllocationsLogOverflowed() {
args.rval().setBoolean(memory->getDebugger()->allocationsLogOverflowed);
return true;
}
/* static */
bool DebuggerMemory::getOnGarbageCollection(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGGER_MEMORY(cx, argc, vp, "(get onGarbageCollection)", args, memory);
bool DebuggerMemory::CallData::getOnGarbageCollection() {
return Debugger::getHookImpl(cx, args, *memory->getDebugger(),
Debugger::OnGarbageCollection);
}
/* static */
bool DebuggerMemory::setOnGarbageCollection(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGGER_MEMORY(cx, argc, vp, "(set onGarbageCollection)", args, memory);
bool DebuggerMemory::CallData::setOnGarbageCollection() {
return Debugger::setHookImpl(cx, args, *memory->getDebugger(),
Debugger::OnGarbageCollection);
}
@ -396,10 +384,7 @@ using JS::ubi::CountTypePtr;
//
// 3) We walk the tree of counts and produce JavaScript objects reporting the
// accumulated results.
bool DebuggerMemory::takeCensus(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER_MEMORY(cx, argc, vp, "Debugger.Memory.prototype.census", args,
memory);
bool DebuggerMemory::CallData::takeCensus() {
Census census(cx);
CountTypePtr rootType;
@ -454,18 +439,18 @@ bool DebuggerMemory::takeCensus(JSContext* cx, unsigned argc, Value* vp) {
/* Debugger.Memory property and method tables. */
/* static */ const JSPropertySpec DebuggerMemory::properties[] = {
JS_PSGS("trackingAllocationSites", getTrackingAllocationSites,
setTrackingAllocationSites, 0),
JS_PSGS("maxAllocationsLogLength", getMaxAllocationsLogLength,
setMaxAllocationsLogLength, 0),
JS_PSGS("allocationSamplingProbability", getAllocationSamplingProbability,
setAllocationSamplingProbability, 0),
JS_PSG("allocationsLogOverflowed", getAllocationsLogOverflowed, 0),
JS_PSGS("onGarbageCollection", getOnGarbageCollection,
setOnGarbageCollection, 0),
JS_DEBUG_PSGS("trackingAllocationSites", getTrackingAllocationSites,
setTrackingAllocationSites),
JS_DEBUG_PSGS("maxAllocationsLogLength", getMaxAllocationsLogLength,
setMaxAllocationsLogLength),
JS_DEBUG_PSGS("allocationSamplingProbability",
getAllocationSamplingProbability,
setAllocationSamplingProbability),
JS_DEBUG_PSG("allocationsLogOverflowed", getAllocationsLogOverflowed),
JS_DEBUG_PSGS("onGarbageCollection", getOnGarbageCollection,
setOnGarbageCollection),
JS_PS_END};
/* static */ const JSFunctionSpec DebuggerMemory::methods[] = {
JS_FN("drainAllocationsLog", DebuggerMemory::drainAllocationsLog, 0, 0),
JS_FN("takeCensus", takeCensus, 0, 0), JS_FS_END};
JS_DEBUG_FN("drainAllocationsLog", drainAllocationsLog, 0),
JS_DEBUG_FN("takeCensus", takeCensus, 0), JS_FS_END};

Просмотреть файл

@ -19,8 +19,7 @@ namespace js {
class DebuggerMemory : public NativeObject {
friend class Debugger;
static DebuggerMemory* checkThis(JSContext* cx, CallArgs& args,
const char* fnName);
static DebuggerMemory* checkThis(JSContext* cx, CallArgs& args);
Debugger* getDebugger();
@ -34,30 +33,7 @@ class DebuggerMemory : public NativeObject {
static const JSPropertySpec properties[];
static const JSFunctionSpec methods[];
// Accessor properties of Debugger.Memory.prototype.
static bool setTrackingAllocationSites(JSContext* cx, unsigned argc,
Value* vp);
static bool getTrackingAllocationSites(JSContext* cx, unsigned argc,
Value* vp);
static bool setMaxAllocationsLogLength(JSContext* cx, unsigned argc,
Value* vp);
static bool getMaxAllocationsLogLength(JSContext* cx, unsigned argc,
Value* vp);
static bool setAllocationSamplingProbability(JSContext* cx, unsigned argc,
Value* vp);
static bool getAllocationSamplingProbability(JSContext* cx, unsigned argc,
Value* vp);
static bool getAllocationsLogOverflowed(JSContext* cx, unsigned argc,
Value* vp);
static bool getOnGarbageCollection(JSContext* cx, unsigned argc, Value* vp);
static bool setOnGarbageCollection(JSContext* cx, unsigned argc, Value* vp);
// Function properties of Debugger.Memory.prototype.
static bool takeCensus(JSContext* cx, unsigned argc, Value* vp);
static bool drainAllocationsLog(JSContext* cx, unsigned argc, Value* vp);
struct CallData;
};
} /* namespace js */

Просмотреть файл

@ -83,8 +83,7 @@ void DebuggerEnvironment::trace(JSTracer* trc) {
}
static DebuggerEnvironment* DebuggerEnvironment_checkThis(
JSContext* cx, const CallArgs& args, const char* fnname,
bool requireDebuggee) {
JSContext* cx, const CallArgs& args) {
JSObject* thisobj = RequireObject(cx, args.thisv());
if (!thisobj) {
return nullptr;
@ -92,7 +91,7 @@ static DebuggerEnvironment* DebuggerEnvironment_checkThis(
if (thisobj->getClass() != &DebuggerEnvironment::class_) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_INCOMPATIBLE_PROTO, "Debugger.Environment",
fnname, thisobj->getClass()->name);
"method", thisobj->getClass()->name);
return nullptr;
}
@ -103,31 +102,55 @@ static DebuggerEnvironment* DebuggerEnvironment_checkThis(
if (!nthisobj->getPrivate()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_INCOMPATIBLE_PROTO, "Debugger.Environment",
fnname, "prototype object");
"method", "prototype object");
return nullptr;
}
// Forbid access to Debugger.Environment objects that are not debuggee
// environments.
if (requireDebuggee) {
Rooted<Env*> env(cx, static_cast<Env*>(nthisobj->getPrivate()));
if (!Debugger::fromChildJSObject(nthisobj)->observesGlobal(
&env->nonCCWGlobal())) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_DEBUG_NOT_DEBUGGEE,
"Debugger.Environment", "environment");
return nullptr;
}
}
return nthisobj;
}
#define THIS_DEBUGGER_ENVIRONMENT(cx, argc, vp, fnname, args, environment) \
CallArgs args = CallArgsFromVp(argc, vp); \
Rooted<DebuggerEnvironment*> environment( \
cx, DebuggerEnvironment_checkThis(cx, args, fnname, false)); \
if (!environment) return false;
struct MOZ_STACK_CLASS DebuggerEnvironment::CallData {
JSContext* cx;
const CallArgs& args;
HandleDebuggerEnvironment environment;
CallData(JSContext* cx, const CallArgs& args, HandleDebuggerEnvironment env)
: cx(cx), args(args), environment(env) {}
bool typeGetter();
bool scopeKindGetter();
bool parentGetter();
bool objectGetter();
bool calleeGetter();
bool inspectableGetter();
bool optimizedOutGetter();
bool namesMethod();
bool findMethod();
bool getVariableMethod();
bool setVariableMethod();
using Method = bool (CallData::*)();
template <Method MyMethod>
static bool ToNative(JSContext* cx, unsigned argc, Value* vp);
};
template <DebuggerEnvironment::CallData::Method MyMethod>
/* static */
bool DebuggerEnvironment::CallData::ToNative(JSContext* cx, unsigned argc, Value* vp) {
CallArgs args = CallArgsFromVp(argc, vp);
RootedDebuggerEnvironment environment(cx,
DebuggerEnvironment_checkThis(cx, args));
if (!environment) {
return false;
}
CallData data(cx, args, environment);
return (data.*MyMethod)();
}
/* static */
bool DebuggerEnvironment::construct(JSContext* cx, unsigned argc, Value* vp) {
@ -147,9 +170,7 @@ static bool IsDebugEnvironmentWrapper(Env* env) {
env->as<DebugEnvironmentProxy>().environment().is<T>();
}
bool DebuggerEnvironment::typeGetter(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER_ENVIRONMENT(cx, argc, vp, "get type", args, environment);
bool DebuggerEnvironment::CallData::typeGetter() {
if (!environment->requireDebuggee(cx)) {
return false;
}
@ -178,10 +199,7 @@ bool DebuggerEnvironment::typeGetter(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
bool DebuggerEnvironment::scopeKindGetter(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGGER_ENVIRONMENT(cx, argc, vp, "get scopeKind", args, environment);
bool DebuggerEnvironment::CallData::scopeKindGetter() {
if (!environment->requireDebuggee(cx)) {
return false;
}
@ -201,11 +219,7 @@ bool DebuggerEnvironment::scopeKindGetter(JSContext* cx, unsigned argc,
return true;
}
/* static */
bool DebuggerEnvironment::parentGetter(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGGER_ENVIRONMENT(cx, argc, vp, "get type", args, environment);
bool DebuggerEnvironment::CallData::parentGetter() {
if (!environment->requireDebuggee(cx)) {
return false;
}
@ -219,11 +233,7 @@ bool DebuggerEnvironment::parentGetter(JSContext* cx, unsigned argc,
return true;
}
/* static */
bool DebuggerEnvironment::objectGetter(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGGER_ENVIRONMENT(cx, argc, vp, "get type", args, environment);
bool DebuggerEnvironment::CallData::objectGetter() {
if (!environment->requireDebuggee(cx)) {
return false;
}
@ -243,11 +253,7 @@ bool DebuggerEnvironment::objectGetter(JSContext* cx, unsigned argc,
return true;
}
/* static */
bool DebuggerEnvironment::calleeGetter(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGGER_ENVIRONMENT(cx, argc, vp, "get callee", args, environment);
bool DebuggerEnvironment::CallData::calleeGetter() {
if (!environment->requireDebuggee(cx)) {
return false;
}
@ -261,29 +267,17 @@ bool DebuggerEnvironment::calleeGetter(JSContext* cx, unsigned argc,
return true;
}
/* static */
bool DebuggerEnvironment::inspectableGetter(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGGER_ENVIRONMENT(cx, argc, vp, "get inspectable", args, environment);
bool DebuggerEnvironment::CallData::inspectableGetter() {
args.rval().setBoolean(environment->isDebuggee());
return true;
}
/* static */
bool DebuggerEnvironment::optimizedOutGetter(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGGER_ENVIRONMENT(cx, argc, vp, "get optimizedOut", args,
environment);
bool DebuggerEnvironment::CallData::optimizedOutGetter() {
args.rval().setBoolean(environment->isOptimized());
return true;
}
/* static */
bool DebuggerEnvironment::namesMethod(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER_ENVIRONMENT(cx, argc, vp, "names", args, environment);
bool DebuggerEnvironment::CallData::namesMethod() {
if (!environment->requireDebuggee(cx)) {
return false;
}
@ -302,9 +296,7 @@ bool DebuggerEnvironment::namesMethod(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
/* static */
bool DebuggerEnvironment::findMethod(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER_ENVIRONMENT(cx, argc, vp, "find", args, environment);
bool DebuggerEnvironment::CallData::findMethod() {
if (!args.requireAtLeast(cx, "Debugger.Environment.find", 1)) {
return false;
}
@ -327,10 +319,7 @@ bool DebuggerEnvironment::findMethod(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
/* static */
bool DebuggerEnvironment::getVariableMethod(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGGER_ENVIRONMENT(cx, argc, vp, "getVariable", args, environment);
bool DebuggerEnvironment::CallData::getVariableMethod() {
if (!args.requireAtLeast(cx, "Debugger.Environment.getVariable", 1)) {
return false;
}
@ -347,10 +336,7 @@ bool DebuggerEnvironment::getVariableMethod(JSContext* cx, unsigned argc,
return DebuggerEnvironment::getVariable(cx, environment, id, args.rval());
}
/* static */
bool DebuggerEnvironment::setVariableMethod(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGGER_ENVIRONMENT(cx, argc, vp, "setVariable", args, environment);
bool DebuggerEnvironment::CallData::setVariableMethod() {
if (!args.requireAtLeast(cx, "Debugger.Environment.setVariable", 2)) {
return false;
}
@ -385,20 +371,20 @@ bool DebuggerEnvironment::requireDebuggee(JSContext* cx) const {
}
const JSPropertySpec DebuggerEnvironment::properties_[] = {
JS_PSG("type", DebuggerEnvironment::typeGetter, 0),
JS_PSG("scopeKind", DebuggerEnvironment::scopeKindGetter, 0),
JS_PSG("parent", DebuggerEnvironment::parentGetter, 0),
JS_PSG("object", DebuggerEnvironment::objectGetter, 0),
JS_PSG("callee", DebuggerEnvironment::calleeGetter, 0),
JS_PSG("inspectable", DebuggerEnvironment::inspectableGetter, 0),
JS_PSG("optimizedOut", DebuggerEnvironment::optimizedOutGetter, 0),
JS_DEBUG_PSG("type", typeGetter),
JS_DEBUG_PSG("scopeKind", scopeKindGetter),
JS_DEBUG_PSG("parent", parentGetter),
JS_DEBUG_PSG("object", objectGetter),
JS_DEBUG_PSG("callee", calleeGetter),
JS_DEBUG_PSG("inspectable", inspectableGetter),
JS_DEBUG_PSG("optimizedOut", optimizedOutGetter),
JS_PS_END};
const JSFunctionSpec DebuggerEnvironment::methods_[] = {
JS_FN("names", DebuggerEnvironment::namesMethod, 0, 0),
JS_FN("find", DebuggerEnvironment::findMethod, 1, 0),
JS_FN("getVariable", DebuggerEnvironment::getVariableMethod, 1, 0),
JS_FN("setVariable", DebuggerEnvironment::setVariableMethod, 2, 0),
JS_DEBUG_FN("names", namesMethod, 0),
JS_DEBUG_FN("find", findMethod, 1),
JS_DEBUG_FN("getVariable", getVariableMethod, 1),
JS_DEBUG_FN("setVariable", setVariableMethod, 2),
JS_FS_END};
/* static */

Просмотреть файл

@ -88,26 +88,7 @@ class DebuggerEnvironment : public NativeObject {
static MOZ_MUST_USE bool construct(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool typeGetter(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool scopeKindGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool parentGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool objectGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool calleeGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool inspectableGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool optimizedOutGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool namesMethod(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool findMethod(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool getVariableMethod(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool setVariableMethod(JSContext* cx, unsigned argc,
Value* vp);
struct CallData;
};
} /* namespace js */

Просмотреть файл

@ -1096,16 +1096,16 @@ void DebuggerFrame::trace(JSTracer* trc) {
}
/* static */
DebuggerFrame* DebuggerFrame::checkThis(JSContext* cx, const CallArgs& args,
const char* fnname, bool checkLive) {
JSObject* thisobj = RequireObject(cx, args.thisv());
DebuggerFrame* DebuggerFrame::check(JSContext* cx, HandleValue thisv,
bool checkLive) {
JSObject* thisobj = RequireObject(cx, thisv);
if (!thisobj) {
return nullptr;
}
if (thisobj->getClass() != &class_) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_INCOMPATIBLE_PROTO, "Debugger.Frame",
fnname, thisobj->getClass()->name);
"method", thisobj->getClass()->name);
return nullptr;
}
@ -1119,7 +1119,7 @@ DebuggerFrame* DebuggerFrame::checkThis(JSContext* cx, const CallArgs& args,
frame->getReservedSlot(OWNER_SLOT).isUndefined()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_INCOMPATIBLE_PROTO, "Debugger.Frame",
fnname, "prototype object");
"method", "prototype object");
return nullptr;
}
@ -1132,27 +1132,60 @@ DebuggerFrame* DebuggerFrame::checkThis(JSContext* cx, const CallArgs& args,
return frame;
}
/*
* Methods can use THIS_DEBUGGER_FRAME to check that `this` is a Debugger.Frame
* object and get it in a local Rooted.
*
* Methods that need the AbstractFramePtr should use THIS_FRAME.
*/
#define THIS_DEBUGGER_FRAME(cx, argc, vp, fnname, args, frame) \
CallArgs args = CallArgsFromVp(argc, vp); \
RootedDebuggerFrame frame(cx, \
DebuggerFrame::checkThis(cx, args, fnname, true)); \
if (!frame) return false;
struct MOZ_STACK_CLASS DebuggerFrame::CallData {
JSContext* cx;
const CallArgs& args;
#define THIS_FRAME(cx, argc, vp, fnname, args, thisobj, iter, frame) \
THIS_DEBUGGER_FRAME(cx, argc, vp, fnname, args, thisobj); \
FrameIter iter(*thisobj->frameIterData()); \
AbstractFramePtr frame = iter.abstractFramePtr()
HandleDebuggerFrame frame;
CallData(JSContext* cx, const CallArgs& args, HandleDebuggerFrame frame)
: cx(cx), args(args), frame(frame) {}
bool argumentsGetter();
bool calleeGetter();
bool constructingGetter();
bool environmentGetter();
bool generatorGetter();
bool liveGetter();
bool offsetGetter();
bool olderGetter();
bool getScript();
bool thisGetter();
bool typeGetter();
bool implementationGetter();
bool onStepGetter();
bool onStepSetter();
bool onPopGetter();
bool onPopSetter();
bool evalMethod();
bool evalWithBindingsMethod();
using Method = bool (CallData::*)();
template <Method MyMethod>
static bool ToNative(JSContext* cx, unsigned argc, Value* vp);
};
template <DebuggerFrame::CallData::Method MyMethod>
/* static */
bool DebuggerFrame::typeGetter(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER_FRAME(cx, argc, vp, "get type", args, frame);
bool DebuggerFrame::CallData::ToNative(JSContext* cx, unsigned argc,
Value* vp) {
CallArgs args = CallArgsFromVp(argc, vp);
// All accessors/methods require a live frame, except for the live getter.
bool checkLive = MyMethod != &CallData::liveGetter;
RootedDebuggerFrame frame(cx, DebuggerFrame::check(cx, args.thisv(),
checkLive));
if (!frame) {
return false;
}
CallData data(cx, args, frame);
return (data.*MyMethod)();
}
bool DebuggerFrame::CallData::typeGetter() {
DebuggerFrameType type = DebuggerFrame::getType(frame);
JSString* str;
@ -1180,11 +1213,7 @@ bool DebuggerFrame::typeGetter(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
/* static */
bool DebuggerFrame::implementationGetter(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGGER_FRAME(cx, argc, vp, "get implementation", args, frame);
bool DebuggerFrame::CallData::implementationGetter() {
DebuggerFrameImplementation implementation =
DebuggerFrame::getImplementation(frame);
@ -1215,10 +1244,7 @@ bool DebuggerFrame::implementationGetter(JSContext* cx, unsigned argc,
return true;
}
/* static */
bool DebuggerFrame::environmentGetter(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER_FRAME(cx, argc, vp, "get environment", args, frame);
bool DebuggerFrame::CallData::environmentGetter() {
RootedDebuggerEnvironment result(cx);
if (!DebuggerFrame::getEnvironment(cx, frame, &result)) {
return false;
@ -1228,10 +1254,7 @@ bool DebuggerFrame::environmentGetter(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
/* static */
bool DebuggerFrame::calleeGetter(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER_FRAME(cx, argc, vp, "get callee", args, frame);
bool DebuggerFrame::CallData::calleeGetter() {
RootedDebuggerObject result(cx);
if (!DebuggerFrame::getCallee(cx, frame, &result)) {
return false;
@ -1241,19 +1264,12 @@ bool DebuggerFrame::calleeGetter(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
/* static */
bool DebuggerFrame::generatorGetter(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER_FRAME(cx, argc, vp, "get callee", args, frame);
bool DebuggerFrame::CallData::generatorGetter() {
args.rval().setBoolean(DebuggerFrame::getIsGenerator(frame));
return true;
}
/* static */
bool DebuggerFrame::constructingGetter(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGGER_FRAME(cx, argc, vp, "get callee", args, frame);
bool DebuggerFrame::CallData::constructingGetter() {
bool result;
if (!DebuggerFrame::getIsConstructing(cx, frame, result)) {
return false;
@ -1263,17 +1279,11 @@ bool DebuggerFrame::constructingGetter(JSContext* cx, unsigned argc,
return true;
}
/* static */
bool DebuggerFrame::thisGetter(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER_FRAME(cx, argc, vp, "get this", args, frame);
bool DebuggerFrame::CallData::thisGetter() {
return DebuggerFrame::getThis(cx, frame, args.rval());
}
/* static */
bool DebuggerFrame::olderGetter(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER_FRAME(cx, argc, vp, "get older", args, frame);
bool DebuggerFrame::CallData::olderGetter() {
RootedDebuggerFrame result(cx);
if (!DebuggerFrame::getOlder(cx, frame, &result)) {
return false;
@ -1301,11 +1311,15 @@ static bool DebuggerArguments_getArg(JSContext* cx, unsigned argc, Value* vp) {
return false;
}
// Put the Debugger.Frame into the this-value slot, then use THIS_FRAME
// to check that it is still live and get the fp.
args.setThis(
RootedValue framev(cx,
argsobj->as<NativeObject>().getReservedSlot(JSSLOT_DEBUGARGUMENTS_FRAME));
THIS_FRAME(cx, argc, vp, "get argument", ca2, thisobj, frameIter, frame);
RootedDebuggerFrame thisobj(cx, DebuggerFrame::check(cx, framev, true));
if (!thisobj) {
return false;
}
FrameIter frameIter(*thisobj->frameIterData());
AbstractFramePtr frame = frameIter.abstractFramePtr();
// TODO handle wasm frame arguments -- they are not yet reflectable.
MOZ_ASSERT(!frame.isWasmDebugFrame(), "a wasm frame args");
@ -1392,10 +1406,7 @@ DebuggerArguments* DebuggerArguments::create(JSContext* cx, HandleObject proto,
return obj;
}
/* static */
bool DebuggerFrame::argumentsGetter(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER_FRAME(cx, argc, vp, "get arguments", args, frame);
bool DebuggerFrame::CallData::argumentsGetter() {
RootedDebuggerArguments result(cx);
if (!DebuggerFrame::getArguments(cx, frame, &result)) {
return false;
@ -1405,20 +1416,20 @@ bool DebuggerFrame::argumentsGetter(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
/* static */
bool DebuggerFrame::getScript(JSContext* cx, unsigned argc, Value* vp) {
THIS_FRAME(cx, argc, vp, "get script", args, thisobj, frameIter, frame);
Debugger* debug = Debugger::fromChildJSObject(thisobj);
bool DebuggerFrame::CallData::getScript() {
FrameIter iter(*frame->frameIterData());
AbstractFramePtr framePtr = iter.abstractFramePtr();
Debugger* debug = Debugger::fromChildJSObject(frame);
RootedDebuggerScript scriptObject(cx);
if (frame.isWasmDebugFrame()) {
RootedWasmInstanceObject instance(cx, frame.wasmInstance()->object());
if (framePtr.isWasmDebugFrame()) {
RootedWasmInstanceObject instance(cx, framePtr.wasmInstance()->object());
scriptObject = debug->wrapWasmScript(cx, instance);
if (!scriptObject) {
return false;
}
} else {
RootedScript script(cx, frame.script());
RootedScript script(cx, framePtr.script());
scriptObject = debug->wrapScript(cx, script);
if (!scriptObject) {
return false;
@ -1430,10 +1441,7 @@ bool DebuggerFrame::getScript(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
/* static */
bool DebuggerFrame::offsetGetter(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER_FRAME(cx, argc, vp, "get offset", args, frame);
bool DebuggerFrame::CallData::offsetGetter() {
size_t result;
if (!DebuggerFrame::getOffset(cx, frame, result)) {
return false;
@ -1443,14 +1451,7 @@ bool DebuggerFrame::offsetGetter(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
/* static */
bool DebuggerFrame::liveGetter(JSContext* cx, unsigned argc, Value* vp) {
CallArgs args = CallArgsFromVp(argc, vp);
RootedDebuggerFrame frame(cx, checkThis(cx, args, "get live", false));
if (!frame) {
return false;
}
bool DebuggerFrame::CallData::liveGetter() {
args.rval().setBoolean(frame->isLive());
return true;
}
@ -1459,10 +1460,7 @@ static bool IsValidHook(const Value& v) {
return v.isUndefined() || (v.isObject() && v.toObject().isCallable());
}
/* static */
bool DebuggerFrame::onStepGetter(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER_FRAME(cx, argc, vp, "get onStep", args, frame);
bool DebuggerFrame::CallData::onStepGetter() {
OnStepHandler* handler = frame->onStepHandler();
RootedValue value(
cx, handler ? ObjectOrNullValue(handler->object()) : UndefinedValue());
@ -1471,9 +1469,7 @@ bool DebuggerFrame::onStepGetter(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
/* static */
bool DebuggerFrame::onStepSetter(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER_FRAME(cx, argc, vp, "set onStep", args, frame);
bool DebuggerFrame::CallData::onStepSetter() {
if (!args.requireAtLeast(cx, "Debugger.Frame.set onStep", 1)) {
return false;
}
@ -1502,10 +1498,7 @@ bool DebuggerFrame::onStepSetter(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
/* static */
bool DebuggerFrame::onPopGetter(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER_FRAME(cx, argc, vp, "get onPop", args, frame);
bool DebuggerFrame::CallData::onPopGetter() {
OnPopHandler* handler = frame->onPopHandler();
RootedValue value(
cx, handler ? ObjectValue(*handler->object()) : UndefinedValue());
@ -1514,9 +1507,7 @@ bool DebuggerFrame::onPopGetter(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
/* static */
bool DebuggerFrame::onPopSetter(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER_FRAME(cx, argc, vp, "set onPop", args, frame);
bool DebuggerFrame::CallData::onPopSetter() {
if (!args.requireAtLeast(cx, "Debugger.Frame.set onPop", 1)) {
return false;
}
@ -1540,9 +1531,7 @@ bool DebuggerFrame::onPopSetter(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
/* static */
bool DebuggerFrame::evalMethod(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGGER_FRAME(cx, argc, vp, "eval", args, frame);
bool DebuggerFrame::CallData::evalMethod() {
if (!args.requireAtLeast(cx, "Debugger.Frame.prototype.eval", 1)) {
return false;
}
@ -1565,10 +1554,7 @@ bool DebuggerFrame::evalMethod(JSContext* cx, unsigned argc, Value* vp) {
return comp.get().buildCompletionValue(cx, frame->owner(), args.rval());
}
/* static */
bool DebuggerFrame::evalWithBindingsMethod(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGGER_FRAME(cx, argc, vp, "evalWithBindings", args, frame);
bool DebuggerFrame::CallData::evalWithBindingsMethod() {
if (!args.requireAtLeast(cx, "Debugger.Frame.prototype.evalWithBindings",
2)) {
return false;
@ -1605,26 +1591,25 @@ bool DebuggerFrame::construct(JSContext* cx, unsigned argc, Value* vp) {
}
const JSPropertySpec DebuggerFrame::properties_[] = {
JS_PSG("arguments", DebuggerFrame::argumentsGetter, 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::liveGetter, 0),
JS_PSG("offset", DebuggerFrame::offsetGetter, 0),
JS_PSG("older", DebuggerFrame::olderGetter, 0),
JS_PSG("script", DebuggerFrame::getScript, 0),
JS_PSG("this", DebuggerFrame::thisGetter, 0),
JS_PSG("type", DebuggerFrame::typeGetter, 0),
JS_PSG("implementation", DebuggerFrame::implementationGetter, 0),
JS_PSGS("onStep", DebuggerFrame::onStepGetter, DebuggerFrame::onStepSetter,
0),
JS_PSGS("onPop", DebuggerFrame::onPopGetter, DebuggerFrame::onPopSetter, 0),
JS_DEBUG_PSG("arguments", argumentsGetter),
JS_DEBUG_PSG("callee", calleeGetter),
JS_DEBUG_PSG("constructing", constructingGetter),
JS_DEBUG_PSG("environment", environmentGetter),
JS_DEBUG_PSG("generator", generatorGetter),
JS_DEBUG_PSG("live", liveGetter),
JS_DEBUG_PSG("offset", offsetGetter),
JS_DEBUG_PSG("older", olderGetter),
JS_DEBUG_PSG("script", getScript),
JS_DEBUG_PSG("this", thisGetter),
JS_DEBUG_PSG("type", typeGetter),
JS_DEBUG_PSG("implementation", implementationGetter),
JS_DEBUG_PSGS("onStep", onStepGetter, onStepSetter),
JS_DEBUG_PSGS("onPop", onPopGetter, onPopSetter),
JS_PS_END};
const JSFunctionSpec DebuggerFrame::methods_[] = {
JS_FN("eval", DebuggerFrame::evalMethod, 1, 0),
JS_FN("evalWithBindings", DebuggerFrame::evalWithBindingsMethod, 1, 0),
JS_DEBUG_FN("eval", evalMethod, 1),
JS_DEBUG_FN("evalWithBindings", evalWithBindingsMethod, 1),
JS_FS_END};
JSObject* js::IdVectorToArray(JSContext* cx, Handle<IdVector> ids) {

Просмотреть файл

@ -149,7 +149,6 @@ class DebuggerFrame : public NativeObject {
const FrameIter& iter,
HandleNativeObject debugger);
static MOZ_MUST_USE bool getScript(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool getArguments(JSContext* cx,
HandleDebuggerFrame frame,
MutableHandleDebuggerArguments result);
@ -181,10 +180,8 @@ class DebuggerFrame : public NativeObject {
const EvalOptions& options);
MOZ_MUST_USE bool requireLive(JSContext* cx);
static MOZ_MUST_USE DebuggerFrame* checkThis(JSContext* cx,
const CallArgs& args,
const char* fnname,
bool checkLive);
static MOZ_MUST_USE DebuggerFrame* check(JSContext* cx, HandleValue thisv,
bool checkLive);
bool isLive() const;
OnStepHandler* onStepHandler() const;
@ -266,34 +263,7 @@ class DebuggerFrame : public NativeObject {
static MOZ_MUST_USE bool construct(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool argumentsGetter(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);
static MOZ_MUST_USE bool offsetGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool olderGetter(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool thisGetter(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool typeGetter(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool implementationGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool onStepGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool onStepSetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool onPopGetter(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool onPopSetter(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool evalMethod(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool evalWithBindingsMethod(JSContext* cx, unsigned argc,
Value* vp);
struct CallData;
Debugger* owner() const;

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -199,135 +199,8 @@ class DebuggerObject : public NativeObject {
HandleDebuggerObject object);
static MOZ_MUST_USE bool construct(JSContext* cx, unsigned argc, Value* vp);
// JSNative properties
static MOZ_MUST_USE bool callableGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool isBoundFunctionGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool isArrowFunctionGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool isAsyncFunctionGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool isGeneratorFunctionGetter(JSContext* cx,
unsigned argc, Value* vp);
static MOZ_MUST_USE bool protoGetter(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool classGetter(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool nameGetter(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool displayNameGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool parameterNamesGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool scriptGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool environmentGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool boundTargetFunctionGetter(JSContext* cx,
unsigned argc, Value* vp);
static MOZ_MUST_USE bool boundThisGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool boundArgumentsGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool allocationSiteGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool errorMessageNameGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool errorNotesGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool errorLineNumberGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool errorColumnNumberGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool isProxyGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool proxyTargetGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool proxyHandlerGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool isPromiseGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool promiseStateGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool promiseValueGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool promiseReasonGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool promiseLifetimeGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool promiseTimeToResolutionGetter(JSContext* cx,
unsigned argc,
Value* vp);
static MOZ_MUST_USE bool promiseAllocationSiteGetter(JSContext* cx,
unsigned argc,
Value* vp);
static MOZ_MUST_USE bool promiseResolutionSiteGetter(JSContext* cx,
unsigned argc,
Value* vp);
static MOZ_MUST_USE bool promiseIDGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool promiseDependentPromisesGetter(JSContext* cx,
unsigned argc,
Value* vp);
struct CallData;
// JSNative methods
static MOZ_MUST_USE bool isExtensibleMethod(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool isSealedMethod(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool isFrozenMethod(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool getPropertyMethod(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool setPropertyMethod(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool getOwnPropertyNamesMethod(JSContext* cx,
unsigned argc, Value* vp);
static MOZ_MUST_USE bool getOwnPropertySymbolsMethod(JSContext* cx,
unsigned argc,
Value* vp);
static MOZ_MUST_USE bool getOwnPropertyDescriptorMethod(JSContext* cx,
unsigned argc,
Value* vp);
static MOZ_MUST_USE bool preventExtensionsMethod(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool sealMethod(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool freezeMethod(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool definePropertyMethod(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool definePropertiesMethod(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool deletePropertyMethod(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool callMethod(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool applyMethod(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool asEnvironmentMethod(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool forceLexicalInitializationByNameMethod(JSContext* cx,
unsigned argc,
Value* vp);
static MOZ_MUST_USE bool executeInGlobalMethod(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool executeInGlobalWithBindingsMethod(JSContext* cx,
unsigned argc,
Value* vp);
static MOZ_MUST_USE bool createSource(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool makeDebuggeeValueMethod(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool makeDebuggeeNativeFunctionMethod(JSContext* cx,
unsigned argc,
Value* vp);
static MOZ_MUST_USE bool isSameNativeMethod(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool unsafeDereferenceMethod(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool unwrapMethod(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool setInstrumentationMethod(JSContext* cx,
unsigned argc, Value* vp);
static MOZ_MUST_USE bool setInstrumentationActiveMethod(JSContext* cx,
unsigned argc,
Value* vp);
static MOZ_MUST_USE bool getErrorReport(JSContext* cx,
HandleObject maybeError,
JSErrorReport*& report);

Просмотреть файл

@ -178,8 +178,7 @@ static JSScript* DelazifyScript(JSContext* cx, Handle<LazyScript*> lazyScript) {
}
/* static */
DebuggerScript* DebuggerScript::check(JSContext* cx, HandleValue v,
const char* fnname) {
DebuggerScript* DebuggerScript::check(JSContext* cx, HandleValue v) {
JSObject* thisobj = RequireObject(cx, v);
if (!thisobj) {
return nullptr;
@ -187,7 +186,7 @@ DebuggerScript* DebuggerScript::check(JSContext* cx, HandleValue v,
if (!thisobj->is<DebuggerScript>()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_INCOMPATIBLE_PROTO, "Debugger.Script",
fnname, thisobj->getClass()->name);
"method", thisobj->getClass()->name);
return nullptr;
}
@ -198,55 +197,104 @@ DebuggerScript* DebuggerScript::check(JSContext* cx, HandleValue v,
if (!scriptObj.getReferentCell()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_INCOMPATIBLE_PROTO, "Debugger.Script",
fnname, "prototype object");
"method", "prototype object");
return nullptr;
}
return &scriptObj;
}
struct MOZ_STACK_CLASS DebuggerScript::CallData {
JSContext* cx;
const CallArgs& args;
HandleDebuggerScript obj;
Rooted<DebuggerScriptReferent> referent;
RootedScript script;
CallData(JSContext* cx, const CallArgs& args, HandleDebuggerScript obj)
: cx(cx), args(args), obj(obj), referent(cx, obj->getReferent()),
script(cx) {}
MOZ_MUST_USE bool ensureScriptMaybeLazy() {
if (!referent.is<JSScript*>() && !referent.is<LazyScript*>()) {
ReportValueError(cx, JSMSG_DEBUG_BAD_REFERENT, JSDVG_SEARCH_STACK,
args.thisv(), nullptr, "a JS script");
return false;
}
return true;
}
MOZ_MUST_USE bool ensureScript() {
if (!ensureScriptMaybeLazy()) {
return false;
}
if (referent.is<JSScript*>()) {
script = referent.as<JSScript*>();
} else {
Rooted<LazyScript*> lazyScript(cx, referent.as<LazyScript*>());
script = DelazifyScript(cx, lazyScript);
if (!script) {
return false;
}
}
return true;
}
bool getIsGeneratorFunction();
bool getIsAsyncFunction();
bool getIsFunction();
bool getIsModule();
bool getDisplayName();
bool getUrl();
bool getStartLine();
bool getStartColumn();
bool getLineCount();
bool getSource();
bool getSourceStart();
bool getSourceLength();
bool getMainOffset();
bool getGlobal();
bool getFormat();
bool getChildScripts();
bool getPossibleBreakpoints();
bool getPossibleBreakpointOffsets();
bool getOffsetMetadata();
bool getOffsetLocation();
template <bool Successor>
bool getSuccessorOrPredecessorOffsets();
bool getEffectfulOffsets();
bool getAllOffsets();
bool getAllColumnOffsets();
bool getLineOffsets();
bool setBreakpoint();
bool getBreakpoints();
bool clearBreakpoint();
bool clearAllBreakpoints();
bool isInCatchScope();
bool getOffsetsCoverage();
bool setInstrumentationId();
using Method = bool (CallData::*)();
template <Method MyMethod>
static bool ToNative(JSContext* cx, unsigned argc, Value* vp);
};
template <DebuggerScript::CallData::Method MyMethod>
/* static */
DebuggerScript* DebuggerScript::checkThis(JSContext* cx, const CallArgs& args,
const char* fnname) {
DebuggerScript* thisobj = DebuggerScript::check(cx, args.thisv(), fnname);
if (!thisobj) {
return nullptr;
bool DebuggerScript::CallData::ToNative(JSContext* cx, unsigned argc, Value* vp) {
CallArgs args = CallArgsFromVp(argc, vp);
RootedDebuggerScript obj(cx, DebuggerScript::check(cx, args.thisv()));
if (!obj) {
return false;
}
if (!thisobj->getReferent().is<JSScript*>() &&
!thisobj->getReferent().is<LazyScript*>()) {
ReportValueError(cx, JSMSG_DEBUG_BAD_REFERENT, JSDVG_SEARCH_STACK,
args.thisv(), nullptr, "a JS script");
return nullptr;
}
return thisobj;
CallData data(cx, args, obj);
return (data.*MyMethod)();
}
#define THIS_DEBUGSCRIPT_REFERENT(cx, argc, vp, fnname, args, obj, referent) \
CallArgs args = CallArgsFromVp(argc, vp); \
RootedDebuggerScript obj(cx, \
DebuggerScript::check(cx, args.thisv(), fnname)); \
if (!obj) return false; \
Rooted<DebuggerScriptReferent> referent(cx, obj->getReferent())
#define THIS_DEBUGSCRIPT_SCRIPT_MAYBE_LAZY(cx, argc, vp, fnname, args, obj) \
CallArgs args = CallArgsFromVp(argc, vp); \
RootedDebuggerScript obj(cx, DebuggerScript::checkThis(cx, args, fnname)); \
if (!obj) return false;
#define THIS_DEBUGSCRIPT_SCRIPT_DELAZIFY(cx, argc, vp, fnname, args, obj, \
script) \
THIS_DEBUGSCRIPT_SCRIPT_MAYBE_LAZY(cx, argc, vp, fnname, args, obj); \
RootedScript script(cx); \
if (obj->getReferent().is<JSScript*>()) { \
script = obj->getReferent().as<JSScript*>(); \
} else { \
Rooted<LazyScript*> lazyScript(cx, obj->getReferent().as<LazyScript*>()); \
script = DelazifyScript(cx, lazyScript); \
if (!script) return false; \
}
template <typename Result>
Result CallScriptMethod(HandleDebuggerScript obj,
Result (JSScript::*ifJSScript)() const,
@ -261,29 +309,26 @@ Result CallScriptMethod(HandleDebuggerScript obj,
return (lazyScript->*ifLazyScript)();
}
/* static */
bool DebuggerScript::getIsGeneratorFunction(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGSCRIPT_SCRIPT_MAYBE_LAZY(cx, argc, vp, "(get isGeneratorFunction)",
args, obj);
bool DebuggerScript::CallData::getIsGeneratorFunction() {
if (!ensureScriptMaybeLazy()) {
return false;
}
args.rval().setBoolean(obj->getReferentScript()->isGenerator());
return true;
}
/* static */
bool DebuggerScript::getIsAsyncFunction(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGSCRIPT_SCRIPT_MAYBE_LAZY(cx, argc, vp, "(get isAsyncFunction)",
args, obj);
bool DebuggerScript::CallData::getIsAsyncFunction() {
if (!ensureScriptMaybeLazy()) {
return false;
}
args.rval().setBoolean(obj->getReferentScript()->isAsync());
return true;
}
/* static */
bool DebuggerScript::getIsFunction(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGSCRIPT_SCRIPT_MAYBE_LAZY(cx, argc, vp, "(get isFunction)",
args, obj);
DebuggerScriptReferent referent = obj->getReferent();
bool DebuggerScript::CallData::getIsFunction() {
if (!ensureScriptMaybeLazy()) {
return false;
}
// Note: LazyScripts always have functions.
args.rval().setBoolean(!referent.is<JSScript*>() ||
@ -291,19 +336,19 @@ bool DebuggerScript::getIsFunction(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
/* static */
bool DebuggerScript::getIsModule(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGSCRIPT_SCRIPT_MAYBE_LAZY(cx, argc, vp, "(get isModule)", args, obj);
DebuggerScriptReferent referent = obj->getReferent();
bool DebuggerScript::CallData::getIsModule() {
if (!ensureScriptMaybeLazy()) {
return false;
}
args.rval().setBoolean(referent.is<JSScript*>() &&
referent.as<JSScript*>()->isModule());
return true;
}
/* static */
bool DebuggerScript::getDisplayName(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGSCRIPT_SCRIPT_MAYBE_LAZY(cx, argc, vp, "(get displayName)", args,
obj);
bool DebuggerScript::CallData::getDisplayName() {
if (!ensureScriptMaybeLazy()) {
return false;
}
JSFunction* func = CallScriptMethod(obj, &JSScript::functionNonDelazifying,
&LazyScript::functionNonDelazifying);
Debugger* dbg = Debugger::fromChildJSObject(obj);
@ -324,7 +369,7 @@ bool DebuggerScript::getDisplayName(JSContext* cx, unsigned argc, Value* vp) {
template <typename T>
/* static */
bool DebuggerScript::getUrlImpl(JSContext* cx, CallArgs& args,
bool DebuggerScript::getUrlImpl(JSContext* cx, const CallArgs& args,
Handle<T*> script) {
if (script->filename()) {
JSString* str;
@ -344,15 +389,17 @@ bool DebuggerScript::getUrlImpl(JSContext* cx, CallArgs& args,
return true;
}
/* static */
bool DebuggerScript::getUrl(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGSCRIPT_SCRIPT_MAYBE_LAZY(cx, argc, vp, "(get url)", args, obj);
if (obj->getReferent().is<JSScript*>()) {
RootedScript script(cx, obj->getReferent().as<JSScript*>());
bool DebuggerScript::CallData::getUrl() {
if (!ensureScriptMaybeLazy()) {
return false;
}
if (referent.is<JSScript*>()) {
RootedScript script(cx, referent.as<JSScript*>());
return getUrlImpl<JSScript>(cx, args, script);
}
Rooted<LazyScript*> lazyScript(cx, obj->getReferent().as<LazyScript*>());
Rooted<LazyScript*> lazyScript(cx, referent.as<LazyScript*>());
return getUrlImpl<LazyScript>(cx, args, lazyScript);
}
@ -366,10 +413,7 @@ struct DebuggerScript::GetStartLineMatcher {
ReturnType match(Handle<WasmInstanceObject*> wasmInstance) { return 1; }
};
/* static */
bool DebuggerScript::getStartLine(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGSCRIPT_REFERENT(cx, argc, vp, "(get startLine)", args, obj,
referent);
bool DebuggerScript::CallData::getStartLine() {
GetStartLineMatcher matcher;
args.rval().setNumber(referent.match(matcher));
return true;
@ -385,10 +429,7 @@ struct DebuggerScript::GetStartColumnMatcher {
ReturnType match(Handle<WasmInstanceObject*> wasmInstance) { return 0; }
};
/* static */
bool DebuggerScript::getStartColumn(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGSCRIPT_REFERENT(cx, argc, vp, "(get startColumn)", args, obj,
referent);
bool DebuggerScript::CallData::getStartColumn() {
GetStartColumnMatcher matcher;
args.rval().setNumber(referent.match(matcher));
return true;
@ -423,10 +464,7 @@ struct DebuggerScript::GetLineCountMatcher {
}
};
/* static */
bool DebuggerScript::getLineCount(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGSCRIPT_REFERENT(cx, argc, vp, "(get lineCount)", args, obj,
referent);
bool DebuggerScript::CallData::getLineCount() {
GetLineCountMatcher matcher(cx);
if (!referent.match(matcher)) {
return false;
@ -463,9 +501,7 @@ class DebuggerScript::GetSourceMatcher {
}
};
/* static */
bool DebuggerScript::getSource(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGSCRIPT_REFERENT(cx, argc, vp, "(get source)", args, obj, referent);
bool DebuggerScript::CallData::getSource() {
Debugger* dbg = Debugger::fromChildJSObject(obj);
GetSourceMatcher matcher(cx, dbg);
@ -478,34 +514,34 @@ bool DebuggerScript::getSource(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
/* static */
bool DebuggerScript::getSourceStart(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGSCRIPT_SCRIPT_MAYBE_LAZY(cx, argc, vp, "(get sourceStart)", args,
obj);
bool DebuggerScript::CallData::getSourceStart() {
if (!ensureScriptMaybeLazy()) {
return false;
}
args.rval().setNumber(uint32_t(obj->getReferentScript()->sourceStart()));
return true;
}
/* static */
bool DebuggerScript::getSourceLength(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGSCRIPT_SCRIPT_MAYBE_LAZY(cx, argc, vp, "(get sourceEnd)", args,
obj);
bool DebuggerScript::CallData::getSourceLength() {
if (!ensureScriptMaybeLazy()) {
return false;
}
args.rval().setNumber(uint32_t(obj->getReferentScript()->sourceLength()));
return true;
}
/* static */
bool DebuggerScript::getMainOffset(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGSCRIPT_SCRIPT_DELAZIFY(cx, argc, vp, "(get mainOffset)", args, obj,
script);
bool DebuggerScript::CallData::getMainOffset() {
if (!ensureScript()) {
return false;
}
args.rval().setNumber(uint32_t(script->mainOffset()));
return true;
}
/* static */
bool DebuggerScript::getGlobal(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGSCRIPT_SCRIPT_DELAZIFY(cx, argc, vp, "(get global)", args, obj,
script);
bool DebuggerScript::CallData::getGlobal() {
if (!ensureScript()) {
return false;
}
Debugger* dbg = Debugger::fromChildJSObject(obj);
RootedValue v(cx, ObjectValue(script->global()));
@ -529,9 +565,7 @@ class DebuggerScript::GetFormatMatcher {
}
};
/* static */
bool DebuggerScript::getFormat(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGSCRIPT_REFERENT(cx, argc, vp, "(get format)", args, obj, referent);
bool DebuggerScript::CallData::getFormat() {
GetFormatMatcher matcher(cx->names());
args.rval().setString(referent.match(matcher));
return true;
@ -557,10 +591,10 @@ static bool PushFunctionScript(JSContext* cx, Debugger* dbg, HandleFunction fun,
return wrapped && NewbornArrayPush(cx, array, ObjectValue(*wrapped));
}
/* static */
bool DebuggerScript::getChildScripts(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGSCRIPT_SCRIPT_MAYBE_LAZY(cx, argc, vp, "getChildScripts", args,
obj);
bool DebuggerScript::CallData::getChildScripts() {
if (!ensureScriptMaybeLazy()) {
return false;
}
Debugger* dbg = Debugger::fromChildJSObject(obj);
RootedObject result(cx, NewDenseEmptyArray(cx));
@ -937,12 +971,7 @@ class DebuggerScript::GetPossibleBreakpointsMatcher {
}
};
/* static */
bool DebuggerScript::getPossibleBreakpoints(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGSCRIPT_REFERENT(cx, argc, vp, "getPossibleBreakpoints", args, obj,
referent);
bool DebuggerScript::CallData::getPossibleBreakpoints() {
RootedObject result(cx);
GetPossibleBreakpointsMatcher<false> matcher(cx, &result);
if (args.length() >= 1 && !args[0].isUndefined()) {
@ -959,12 +988,7 @@ bool DebuggerScript::getPossibleBreakpoints(JSContext* cx, unsigned argc,
return true;
}
/* static */
bool DebuggerScript::getPossibleBreakpointOffsets(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGSCRIPT_REFERENT(cx, argc, vp, "getPossibleBreakpointOffsets", args,
obj, referent);
bool DebuggerScript::CallData::getPossibleBreakpointOffsets() {
RootedObject result(cx);
GetPossibleBreakpointsMatcher<true> matcher(cx, &result);
if (args.length() >= 1 && !args[0].isUndefined()) {
@ -1080,11 +1104,7 @@ class DebuggerScript::GetOffsetMetadataMatcher {
}
};
/* static */
bool DebuggerScript::getOffsetMetadata(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGSCRIPT_REFERENT(cx, argc, vp, "getOffsetMetadata", args, obj,
referent);
bool DebuggerScript::CallData::getOffsetMetadata() {
if (!args.requireAtLeast(cx, "Debugger.Script.getOffsetMetadata", 1)) {
return false;
}
@ -1393,11 +1413,7 @@ class DebuggerScript::GetOffsetLocationMatcher {
}
};
/* static */
bool DebuggerScript::getOffsetLocation(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGSCRIPT_REFERENT(cx, argc, vp, "getOffsetLocation", args, obj,
referent);
bool DebuggerScript::CallData::getOffsetLocation() {
if (!args.requireAtLeast(cx, "Debugger.Script.getOffsetLocation", 1)) {
return false;
}
@ -1477,14 +1493,9 @@ class DebuggerScript::GetSuccessorOrPredecessorOffsetsMatcher {
}
};
/* static */
bool DebuggerScript::getSuccessorOrPredecessorOffsets(JSContext* cx,
unsigned argc, Value* vp,
const char* name,
bool successor) {
THIS_DEBUGSCRIPT_REFERENT(cx, argc, vp, name, args, obj, referent);
if (!args.requireAtLeast(cx, name, 1)) {
template <bool Successor>
bool DebuggerScript::CallData::getSuccessorOrPredecessorOffsets() {
if (!args.requireAtLeast(cx, "successorOrPredecessorOffsets", 1)) {
return false;
}
size_t offset;
@ -1493,7 +1504,7 @@ bool DebuggerScript::getSuccessorOrPredecessorOffsets(JSContext* cx,
}
RootedObject result(cx);
GetSuccessorOrPredecessorOffsetsMatcher matcher(cx, offset, successor,
GetSuccessorOrPredecessorOffsetsMatcher matcher(cx, offset, Successor,
&result);
if (!referent.match(matcher)) {
return false;
@ -1503,20 +1514,6 @@ bool DebuggerScript::getSuccessorOrPredecessorOffsets(JSContext* cx,
return true;
}
/* static */
bool DebuggerScript::getSuccessorOffsets(JSContext* cx, unsigned argc,
Value* vp) {
return DebuggerScript::getSuccessorOrPredecessorOffsets(
cx, argc, vp, "getSuccessorOffsets", true);
}
/* static */
bool DebuggerScript::getPredecessorOffsets(JSContext* cx, unsigned argc,
Value* vp) {
return DebuggerScript::getSuccessorOrPredecessorOffsets(
cx, argc, vp, "getPredecessorOffsets", false);
}
// Return whether an opcode is considered effectful: it can have direct side
// effects that can be observed outside of the current frame. Opcodes are not
// effectful if they only modify the current frame's state, modify objects
@ -1777,11 +1774,10 @@ static bool BytecodeIsEffectful(JSOp op) {
return false;
}
/* static */
bool DebuggerScript::getEffectfulOffsets(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGSCRIPT_SCRIPT_DELAZIFY(cx, argc, vp, "getEffectfulOffsets", args,
obj, script);
bool DebuggerScript::CallData::getEffectfulOffsets() {
if (!ensureScript()) {
return false;
}
RootedObject result(cx, NewDenseEmptyArray(cx));
if (!result) {
@ -1799,10 +1795,10 @@ bool DebuggerScript::getEffectfulOffsets(JSContext* cx, unsigned argc,
return true;
}
/* static */
bool DebuggerScript::getAllOffsets(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGSCRIPT_SCRIPT_DELAZIFY(cx, argc, vp, "getAllOffsets", args, obj,
script);
bool DebuggerScript::CallData::getAllOffsets() {
if (!ensureScript()) {
return false;
}
// First pass: determine which offsets in this script are jump targets and
// which line numbers jump to them.
@ -1968,12 +1964,7 @@ class DebuggerScript::GetAllColumnOffsetsMatcher {
}
};
/* static */
bool DebuggerScript::getAllColumnOffsets(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGSCRIPT_REFERENT(cx, argc, vp, "getAllColumnOffsets", args, obj,
referent);
bool DebuggerScript::CallData::getAllColumnOffsets() {
RootedObject result(cx);
GetAllColumnOffsetsMatcher matcher(cx, &result);
if (!referent.match(matcher)) {
@ -2056,10 +2047,7 @@ class DebuggerScript::GetLineOffsetsMatcher {
}
};
/* static */
bool DebuggerScript::getLineOffsets(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGSCRIPT_REFERENT(cx, argc, vp, "getLineOffsets", args, obj,
referent);
bool DebuggerScript::CallData::getLineOffsets() {
if (!args.requireAtLeast(cx, "Debugger.Script.getLineOffsets", 1)) {
return false;
}
@ -2169,9 +2157,7 @@ struct DebuggerScript::SetBreakpointMatcher {
}
};
/* static */
bool DebuggerScript::setBreakpoint(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGSCRIPT_REFERENT(cx, argc, vp, "setBreakpoint", args, obj, referent);
bool DebuggerScript::CallData::setBreakpoint() {
if (!args.requireAtLeast(cx, "Debugger.Script.setBreakpoint", 2)) {
return false;
}
@ -2195,10 +2181,10 @@ bool DebuggerScript::setBreakpoint(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
/* static */
bool DebuggerScript::getBreakpoints(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGSCRIPT_SCRIPT_DELAZIFY(cx, argc, vp, "getBreakpoints", args, obj,
script);
bool DebuggerScript::CallData::getBreakpoints() {
if (!ensureScript()) {
return false;
}
Debugger* dbg = Debugger::fromChildJSObject(obj);
jsbytecode* pc;
@ -2272,10 +2258,7 @@ class DebuggerScript::ClearBreakpointMatcher {
}
};
/* static */
bool DebuggerScript::clearBreakpoint(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGSCRIPT_REFERENT(cx, argc, vp, "clearBreakpoint", args, obj,
referent);
bool DebuggerScript::CallData::clearBreakpoint() {
if (!args.requireAtLeast(cx, "Debugger.Script.clearBreakpoint", 1)) {
return false;
}
@ -2295,11 +2278,7 @@ bool DebuggerScript::clearBreakpoint(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
/* static */
bool DebuggerScript::clearAllBreakpoints(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGSCRIPT_REFERENT(cx, argc, vp, "clearAllBreakpoints", args, obj,
referent);
bool DebuggerScript::CallData::clearAllBreakpoints() {
Debugger* dbg = Debugger::fromChildJSObject(obj);
ClearBreakpointMatcher matcher(cx, dbg, nullptr);
if (!referent.match(matcher)) {
@ -2350,10 +2329,7 @@ class DebuggerScript::IsInCatchScopeMatcher {
}
};
/* static */
bool DebuggerScript::isInCatchScope(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGSCRIPT_REFERENT(cx, argc, vp, "isInCatchScope", args, obj,
referent);
bool DebuggerScript::CallData::isInCatchScope() {
if (!args.requireAtLeast(cx, "Debugger.Script.isInCatchScope", 1)) {
return false;
}
@ -2371,11 +2347,10 @@ bool DebuggerScript::isInCatchScope(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
/* static */
bool DebuggerScript::getOffsetsCoverage(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGSCRIPT_SCRIPT_DELAZIFY(cx, argc, vp, "getOffsetsCoverage", args,
obj, script);
bool DebuggerScript::CallData::getOffsetsCoverage() {
if (!ensureScript()) {
return false;
}
// If the script has no coverage information, then skip this and return null
// instead.
@ -2456,11 +2431,10 @@ bool DebuggerScript::getOffsetsCoverage(JSContext* cx, unsigned argc,
return true;
}
/* static */
bool DebuggerScript::setInstrumentationId(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGSCRIPT_SCRIPT_MAYBE_LAZY(cx, argc, vp, "setInstrumentationId", args,
obj);
bool DebuggerScript::CallData::setInstrumentationId() {
if (!ensureScriptMaybeLazy()) {
return false;
}
if (!obj->getInstrumentationId().isUndefined()) {
JS_ReportErrorASCII(cx, "Script instrumentation ID is already set");
@ -2486,43 +2460,45 @@ bool DebuggerScript::construct(JSContext* cx, unsigned argc, Value* vp) {
}
const JSPropertySpec DebuggerScript::properties_[] = {
JS_PSG("isGeneratorFunction", getIsGeneratorFunction, 0),
JS_PSG("isAsyncFunction", getIsAsyncFunction, 0),
JS_PSG("isFunction", getIsFunction, 0),
JS_PSG("isModule", getIsModule, 0),
JS_PSG("displayName", getDisplayName, 0),
JS_PSG("url", getUrl, 0),
JS_PSG("startLine", getStartLine, 0),
JS_PSG("startColumn", getStartColumn, 0),
JS_PSG("lineCount", getLineCount, 0),
JS_PSG("source", getSource, 0),
JS_PSG("sourceStart", getSourceStart, 0),
JS_PSG("sourceLength", getSourceLength, 0),
JS_PSG("mainOffset", getMainOffset, 0),
JS_PSG("global", getGlobal, 0),
JS_PSG("format", getFormat, 0),
JS_DEBUG_PSG("isGeneratorFunction", getIsGeneratorFunction),
JS_DEBUG_PSG("isAsyncFunction", getIsAsyncFunction),
JS_DEBUG_PSG("isFunction", getIsFunction),
JS_DEBUG_PSG("isModule", getIsModule),
JS_DEBUG_PSG("displayName", getDisplayName),
JS_DEBUG_PSG("url", getUrl),
JS_DEBUG_PSG("startLine", getStartLine),
JS_DEBUG_PSG("startColumn", getStartColumn),
JS_DEBUG_PSG("lineCount", getLineCount),
JS_DEBUG_PSG("source", getSource),
JS_DEBUG_PSG("sourceStart", getSourceStart),
JS_DEBUG_PSG("sourceLength", getSourceLength),
JS_DEBUG_PSG("mainOffset", getMainOffset),
JS_DEBUG_PSG("global", getGlobal),
JS_DEBUG_PSG("format", getFormat),
JS_PS_END};
const JSFunctionSpec DebuggerScript::methods_[] = {
JS_FN("getChildScripts", getChildScripts, 0, 0),
JS_FN("getPossibleBreakpoints", getPossibleBreakpoints, 0, 0),
JS_FN("getPossibleBreakpointOffsets", getPossibleBreakpointOffsets, 0, 0),
JS_FN("setBreakpoint", setBreakpoint, 2, 0),
JS_FN("getBreakpoints", getBreakpoints, 1, 0),
JS_FN("clearBreakpoint", clearBreakpoint, 1, 0),
JS_FN("clearAllBreakpoints", clearAllBreakpoints, 0, 0),
JS_FN("isInCatchScope", isInCatchScope, 1, 0),
JS_FN("getOffsetMetadata", getOffsetMetadata, 1, 0),
JS_FN("getOffsetsCoverage", getOffsetsCoverage, 0, 0),
JS_FN("getSuccessorOffsets", getSuccessorOffsets, 1, 0),
JS_FN("getPredecessorOffsets", getPredecessorOffsets, 1, 0),
JS_FN("getEffectfulOffsets", getEffectfulOffsets, 1, 0),
JS_FN("setInstrumentationId", setInstrumentationId, 1, 0),
JS_DEBUG_FN("getChildScripts", getChildScripts, 0),
JS_DEBUG_FN("getPossibleBreakpoints", getPossibleBreakpoints, 0),
JS_DEBUG_FN("getPossibleBreakpointOffsets", getPossibleBreakpointOffsets, 0),
JS_DEBUG_FN("setBreakpoint", setBreakpoint, 2),
JS_DEBUG_FN("getBreakpoints", getBreakpoints, 1),
JS_DEBUG_FN("clearBreakpoint", clearBreakpoint, 1),
JS_DEBUG_FN("clearAllBreakpoints", clearAllBreakpoints, 0),
JS_DEBUG_FN("isInCatchScope", isInCatchScope, 1),
JS_DEBUG_FN("getOffsetMetadata", getOffsetMetadata, 1),
JS_DEBUG_FN("getOffsetsCoverage", getOffsetsCoverage, 0),
JS_DEBUG_FN("getSuccessorOffsets",
getSuccessorOrPredecessorOffsets<true>, 1),
JS_DEBUG_FN("getPredecessorOffsets",
getSuccessorOrPredecessorOffsets<false>, 1),
JS_DEBUG_FN("getEffectfulOffsets", getEffectfulOffsets, 1),
JS_DEBUG_FN("setInstrumentationId", setInstrumentationId, 1),
// The following APIs are deprecated due to their reliance on the
// under-defined 'entrypoint' concept. Make use of getPossibleBreakpoints,
// getPossibleBreakpointOffsets, or getOffsetMetadata instead.
JS_FN("getAllOffsets", getAllOffsets, 0, 0),
JS_FN("getAllColumnOffsets", getAllColumnOffsets, 0, 0),
JS_FN("getLineOffsets", getLineOffsets, 1, 0),
JS_FN("getOffsetLocation", getOffsetLocation, 0, 0), JS_FS_END};
JS_DEBUG_FN("getAllOffsets", getAllOffsets, 0),
JS_DEBUG_FN("getAllColumnOffsets", getAllColumnOffsets, 0),
JS_DEBUG_FN("getLineOffsets", getLineOffsets, 1),
JS_DEBUG_FN("getOffsetLocation", getOffsetLocation, 0), JS_FS_END};

Просмотреть файл

@ -52,50 +52,15 @@ class DebuggerScript : public NativeObject {
inline js::BaseScript* getReferentScript() const;
inline DebuggerScriptReferent getReferent() const;
static DebuggerScript* check(JSContext* cx, HandleValue v,
const char* fnname);
static DebuggerScript* checkThis(JSContext* cx, const CallArgs& args,
const char* fnname);
static DebuggerScript* check(JSContext* cx, HandleValue v);
// JS methods
static bool getIsGeneratorFunction(JSContext* cx, unsigned argc, Value* vp);
static bool getIsAsyncFunction(JSContext* cx, unsigned argc, Value* vp);
static bool getIsFunction(JSContext* cx, unsigned argc, Value* vp);
static bool getIsModule(JSContext* cx, unsigned argc, Value* vp);
static bool getDisplayName(JSContext* cx, unsigned argc, Value* vp);
static bool getUrl(JSContext* cx, unsigned argc, Value* vp);
static bool getStartLine(JSContext* cx, unsigned argc, Value* vp);
static bool getStartColumn(JSContext* cx, unsigned argc, Value* vp);
static bool getLineCount(JSContext* cx, unsigned argc, Value* vp);
static bool getSource(JSContext* cx, unsigned argc, Value* vp);
static bool getSourceStart(JSContext* cx, unsigned argc, Value* vp);
static bool getSourceLength(JSContext* cx, unsigned argc, Value* vp);
static bool getMainOffset(JSContext* cx, unsigned argc, Value* vp);
static bool getGlobal(JSContext* cx, unsigned argc, Value* vp);
static bool getFormat(JSContext* cx, unsigned argc, Value* vp);
static bool getChildScripts(JSContext* cx, unsigned argc, Value* vp);
static bool getPossibleBreakpoints(JSContext* cx, unsigned argc, Value* vp);
static bool getPossibleBreakpointOffsets(JSContext* cx, unsigned argc,
Value* vp);
static bool getOffsetMetadata(JSContext* cx, unsigned argc, Value* vp);
static bool getOffsetLocation(JSContext* cx, unsigned argc, Value* vp);
static bool getSuccessorOffsets(JSContext* cx, unsigned argc, Value* vp);
static bool getPredecessorOffsets(JSContext* cx, unsigned argc, Value* vp);
static bool getEffectfulOffsets(JSContext* cx, unsigned argc, Value* vp);
static bool getAllOffsets(JSContext* cx, unsigned argc, Value* vp);
static bool getAllColumnOffsets(JSContext* cx, unsigned argc, Value* vp);
static bool getLineOffsets(JSContext* cx, unsigned argc, Value* vp);
static bool setBreakpoint(JSContext* cx, unsigned argc, Value* vp);
static bool getBreakpoints(JSContext* cx, unsigned argc, Value* vp);
static bool clearBreakpoint(JSContext* cx, unsigned argc, Value* vp);
static bool clearAllBreakpoints(JSContext* cx, unsigned argc, Value* vp);
static bool isInCatchScope(JSContext* cx, unsigned argc, Value* vp);
static bool getOffsetsCoverage(JSContext* cx, unsigned argc, Value* vp);
static bool setInstrumentationId(JSContext* cx, unsigned argc, Value* vp);
static bool construct(JSContext* cx, unsigned argc, Value* vp);
struct CallData;
template <typename T>
static bool getUrlImpl(JSContext* cx, CallArgs& args, Handle<T*> script);
static bool getUrlImpl(JSContext* cx, const CallArgs& args,
Handle<T*> script);
static bool getSuccessorOrPredecessorOffsets(JSContext* cx, unsigned argc,
Value* vp, const char* name,

Просмотреть файл

@ -127,8 +127,7 @@ bool DebuggerSource::construct(JSContext* cx, unsigned argc, Value* vp) {
}
/* static */
DebuggerSource* DebuggerSource::check(JSContext* cx, HandleValue thisv,
const char* fnname) {
DebuggerSource* DebuggerSource::check(JSContext* cx, HandleValue thisv) {
JSObject* thisobj = RequireObject(cx, thisv);
if (!thisobj) {
return nullptr;
@ -136,7 +135,7 @@ DebuggerSource* DebuggerSource::check(JSContext* cx, HandleValue thisv,
if (!thisobj->is<DebuggerSource>()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_INCOMPATIBLE_PROTO, "Debugger.Source",
fnname, thisobj->getClass()->name);
"method", thisobj->getClass()->name);
return nullptr;
}
@ -145,47 +144,58 @@ DebuggerSource* DebuggerSource::check(JSContext* cx, HandleValue thisv,
if (!thisSourceObj->getReferentRawObject()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_INCOMPATIBLE_PROTO, "Debugger.Source",
fnname, "prototype object");
"method", "prototype object");
return nullptr;
}
return thisSourceObj;
}
template <typename ReferentT>
struct MOZ_STACK_CLASS DebuggerSource::CallData {
JSContext* cx;
const CallArgs& args;
HandleDebuggerSource obj;
Rooted<DebuggerSourceReferent> referent;
CallData(JSContext* cx, const CallArgs& args, HandleDebuggerSource obj)
: cx(cx), args(args), obj(obj), referent(cx, obj->getReferent()) {}
bool getText();
bool getBinary();
bool getURL();
bool getStartLine();
bool getId();
bool getDisplayURL();
bool getElement();
bool getElementProperty();
bool getIntroductionScript();
bool getIntroductionOffset();
bool getIntroductionType();
bool setSourceMapURL();
bool getSourceMapURL();
bool reparse();
using Method = bool (CallData::*)();
template <Method MyMethod>
static bool ToNative(JSContext* cx, unsigned argc, Value* vp);
};
template <DebuggerSource::CallData::Method MyMethod>
/* static */
DebuggerSource* DebuggerSource::checkThis(JSContext* cx, const CallArgs& args,
const char* fnname,
const char* refname) {
DebuggerSource* thisobj = check(cx, args.thisv(), fnname);
if (!thisobj) {
return nullptr;
bool DebuggerSource::CallData::ToNative(JSContext* cx, unsigned argc, Value* vp) {
CallArgs args = CallArgsFromVp(argc, vp);
RootedDebuggerSource obj(cx, DebuggerSource::check(cx, args.thisv()));
if (!obj) {
return false;
}
if (!thisobj->getReferent().is<ReferentT>()) {
ReportValueError(cx, JSMSG_DEBUG_BAD_REFERENT, JSDVG_SEARCH_STACK,
args.thisv(), nullptr, refname);
return nullptr;
}
return thisobj;
CallData data(cx, args, obj);
return (data.*MyMethod)();
}
#define THIS_DEBUGSOURCE_REFERENT(cx, argc, vp, fnname, args, obj, referent) \
CallArgs args = CallArgsFromVp(argc, vp); \
RootedDebuggerSource obj(cx, \
DebuggerSource::check(cx, args.thisv(), fnname)); \
if (!obj) return false; \
Rooted<DebuggerSourceReferent> referent(cx, obj->getReferent())
#define THIS_DEBUGSOURCE_SOURCE(cx, argc, vp, fnname, args, obj, sourceObject) \
CallArgs args = CallArgsFromVp(argc, vp); \
RootedDebuggerSource obj(cx, DebuggerSource::checkThis<ScriptSourceObject*>( \
cx, args, fnname, "a JS source")); \
if (!obj) return false; \
RootedScriptSourceObject sourceObject( \
cx, obj->getReferent().as<ScriptSourceObject*>())
class DebuggerSourceGetTextMatcher {
JSContext* cx_;
@ -223,9 +233,7 @@ class DebuggerSourceGetTextMatcher {
}
};
/* static */
bool DebuggerSource::getText(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGSOURCE_REFERENT(cx, argc, vp, "(get text)", args, obj, referent);
bool DebuggerSource::CallData::getText() {
Value textv = obj->getReservedSlot(TEXT_SLOT);
if (!textv.isUndefined()) {
MOZ_ASSERT(textv.isString());
@ -244,10 +252,7 @@ bool DebuggerSource::getText(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
/* static */
bool DebuggerSource::getBinary(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGSOURCE_REFERENT(cx, argc, vp, "(get binary)", args, obj, referent);
bool DebuggerSource::CallData::getBinary() {
if (!referent.is<WasmInstanceObject*>()) {
ReportValueError(cx, JSMSG_DEBUG_BAD_REFERENT, JSDVG_SEARCH_STACK,
args.thisv(), nullptr, "a wasm source");
@ -298,10 +303,7 @@ class DebuggerSourceGetURLMatcher {
}
};
/* static */
bool DebuggerSource::getURL(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGSOURCE_REFERENT(cx, argc, vp, "(get url)", args, obj, referent);
bool DebuggerSource::CallData::getURL() {
DebuggerSourceGetURLMatcher matcher(cx);
Maybe<JSString*> str = referent.match(matcher);
if (str.isSome()) {
@ -326,11 +328,7 @@ class DebuggerSourceGetStartLineMatcher {
ReturnType match(Handle<WasmInstanceObject*> instanceObj) { return 0; }
};
/* static */
bool DebuggerSource::getStartLine(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGSOURCE_REFERENT(cx, argc, vp, "(get startLine)", args, obj,
referent);
bool DebuggerSource::CallData::getStartLine() {
DebuggerSourceGetStartLineMatcher matcher;
uint32_t line = referent.match(matcher);
args.rval().setNumber(line);
@ -348,10 +346,7 @@ class DebuggerSourceGetIdMatcher {
ReturnType match(Handle<WasmInstanceObject*> instanceObj) { return 0; }
};
/* static */
bool DebuggerSource::getId(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGSOURCE_REFERENT(cx, argc, vp, "(get id)", args, obj, referent);
bool DebuggerSource::CallData::getId() {
DebuggerSourceGetIdMatcher matcher;
uint32_t id = referent.match(matcher);
args.rval().setNumber(id);
@ -370,10 +365,7 @@ struct DebuggerSourceGetDisplayURLMatcher {
}
};
/* static */
bool DebuggerSource::getDisplayURL(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGSOURCE_REFERENT(cx, argc, vp, "(get url)", args, obj, referent);
bool DebuggerSource::CallData::getDisplayURL() {
DebuggerSourceGetDisplayURLMatcher matcher;
if (const char16_t* displayURL = referent.match(matcher)) {
JSString* str = JS_NewUCStringCopyZ(cx, displayURL);
@ -395,10 +387,7 @@ struct DebuggerSourceGetElementMatcher {
ReturnType match(Handle<WasmInstanceObject*> wasmInstance) { return nullptr; }
};
/* static */
bool DebuggerSource::getElement(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGSOURCE_REFERENT(cx, argc, vp, "(get element)", args, obj, referent);
bool DebuggerSource::CallData::getElement() {
DebuggerSourceGetElementMatcher matcher;
if (JSObject* element = referent.match(matcher)) {
args.rval().setObjectOrNull(element);
@ -421,11 +410,7 @@ struct DebuggerSourceGetElementPropertyMatcher {
}
};
/* static */
bool DebuggerSource::getElementProperty(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGSOURCE_REFERENT(cx, argc, vp, "(get elementAttributeName)", args,
obj, referent);
bool DebuggerSource::CallData::getElementProperty() {
DebuggerSourceGetElementPropertyMatcher matcher;
args.rval().set(referent.match(matcher));
return Debugger::fromChildJSObject(obj)->wrapDebuggeeValue(cx, args.rval());
@ -467,11 +452,7 @@ class DebuggerSourceGetIntroductionScriptMatcher {
}
};
/* static */
bool DebuggerSource::getIntroductionScript(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGSOURCE_REFERENT(cx, argc, vp, "(get introductionScript)", args, obj,
referent);
bool DebuggerSource::CallData::getIntroductionScript() {
Debugger* dbg = Debugger::fromChildJSObject(obj);
DebuggerSourceGetIntroductionScriptMatcher matcher(cx, dbg, args.rval());
return referent.match(matcher);
@ -495,11 +476,7 @@ struct DebuggerGetIntroductionOffsetMatcher {
}
};
/* static */
bool DebuggerSource::getIntroductionOffset(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGSOURCE_REFERENT(cx, argc, vp, "(get introductionOffset)", args, obj,
referent);
bool DebuggerSource::CallData::getIntroductionOffset() {
DebuggerGetIntroductionOffsetMatcher matcher;
args.rval().set(referent.match(matcher));
return true;
@ -515,12 +492,7 @@ struct DebuggerSourceGetIntroductionTypeMatcher {
ReturnType match(Handle<WasmInstanceObject*> wasmInstance) { return "wasm"; }
};
/* static */
bool DebuggerSource::getIntroductionType(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGSOURCE_REFERENT(cx, argc, vp, "(get introductionType)", args, obj,
referent);
bool DebuggerSource::CallData::getIntroductionType() {
DebuggerSourceGetIntroductionTypeMatcher matcher;
if (const char* introductionType = referent.match(matcher)) {
JSString* str = NewStringCopyZ<CanGC>(cx, introductionType);
@ -535,12 +507,25 @@ bool DebuggerSource::getIntroductionType(JSContext* cx, unsigned argc,
return true;
}
/* static */
bool DebuggerSource::setSourceMapURL(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGSOURCE_SOURCE(cx, argc, vp, "set sourceMapURL", args, obj,
sourceObject);
ScriptSourceObject* EnsureSourceObject(JSContext* cx,
HandleDebuggerSource obj) {
if (!obj->getReferent().is<ScriptSourceObject*>()) {
RootedValue v(cx, ObjectValue(*obj));
ReportValueError(cx, JSMSG_DEBUG_BAD_REFERENT, JSDVG_SEARCH_STACK,
v, nullptr, "a JS source");
return nullptr;
}
return obj->getReferent().as<ScriptSourceObject*>();
}
bool DebuggerSource::CallData::setSourceMapURL() {
RootedScriptSourceObject sourceObject(cx, EnsureSourceObject(cx, obj));
if (!sourceObject) {
return false;
}
ScriptSource* ss = sourceObject->source();
MOZ_ASSERT(ss);
if (!args.requireAtLeast(cx, "set sourceMapURL", 1)) {
return false;
}
@ -604,11 +589,7 @@ class DebuggerSourceGetSourceMapURLMatcher {
}
};
/* static */
bool DebuggerSource::getSourceMapURL(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGSOURCE_REFERENT(cx, argc, vp, "(get sourceMapURL)", args, obj,
referent);
bool DebuggerSource::CallData::getSourceMapURL() {
RootedString result(cx);
DebuggerSourceGetSourceMapURLMatcher matcher(cx, &result);
if (!referent.match(matcher)) {
@ -647,27 +628,22 @@ static JSScript* ReparseSource(JSContext* cx, HandleScriptSourceObject sso) {
return JS::Compile(cx, options, srcBuf);
}
/* static */
bool DebuggerSource::reparse(JSContext* cx, unsigned argc, Value* vp) {
THIS_DEBUGSOURCE_REFERENT(cx, argc, vp, "reparse", args, obj,
referent);
if (!referent.is<ScriptSourceObject*>()) {
JS_ReportErrorASCII(cx, "Source object required");
bool DebuggerSource::CallData::reparse() {
RootedScriptSourceObject sourceObject(cx, EnsureSourceObject(cx, obj));
if (!sourceObject) {
return false;
}
RootedScriptSourceObject sso(cx, referent.as<ScriptSourceObject*>());
if (!sso->source()->hasSourceText()) {
if (!sourceObject->source()->hasSourceText()) {
JS_ReportErrorASCII(cx, "Source object missing text");
return false;
}
RootedScript script(cx);
if (sso->source()->hasSourceType<mozilla::Utf8Unit>()) {
script = ReparseSource<mozilla::Utf8Unit>(cx, sso);
if (sourceObject->source()->hasSourceType<mozilla::Utf8Unit>()) {
script = ReparseSource<mozilla::Utf8Unit>(cx, sourceObject);
} else {
script = ReparseSource<char16_t>(cx, sso);
script = ReparseSource<char16_t>(cx, sourceObject);
}
if (!script) {
@ -685,20 +661,20 @@ bool DebuggerSource::reparse(JSContext* cx, unsigned argc, Value* vp) {
}
const JSPropertySpec DebuggerSource::properties_[] = {
JS_PSG("text", getText, 0),
JS_PSG("binary", getBinary, 0),
JS_PSG("url", getURL, 0),
JS_PSG("startLine", getStartLine, 0),
JS_PSG("id", getId, 0),
JS_PSG("element", getElement, 0),
JS_PSG("displayURL", getDisplayURL, 0),
JS_PSG("introductionScript", getIntroductionScript, 0),
JS_PSG("introductionOffset", getIntroductionOffset, 0),
JS_PSG("introductionType", getIntroductionType, 0),
JS_PSG("elementAttributeName", getElementProperty, 0),
JS_PSGS("sourceMapURL", getSourceMapURL, setSourceMapURL, 0),
JS_DEBUG_PSG("text", getText),
JS_DEBUG_PSG("binary", getBinary),
JS_DEBUG_PSG("url", getURL),
JS_DEBUG_PSG("startLine", getStartLine),
JS_DEBUG_PSG("id", getId),
JS_DEBUG_PSG("element", getElement),
JS_DEBUG_PSG("displayURL", getDisplayURL),
JS_DEBUG_PSG("introductionScript", getIntroductionScript),
JS_DEBUG_PSG("introductionOffset", getIntroductionOffset),
JS_DEBUG_PSG("introductionType", getIntroductionType),
JS_DEBUG_PSG("elementAttributeName", getElementProperty),
JS_DEBUG_PSGS("sourceMapURL", getSourceMapURL, setSourceMapURL),
JS_PS_END};
const JSFunctionSpec DebuggerSource::methods_[] = {
JS_FN("reparse", reparse, 0, 0),
JS_DEBUG_FN("reparse", reparse, 0),
JS_FS_END};

Просмотреть файл

@ -43,28 +43,10 @@ class DebuggerSource : public NativeObject {
NativeObject* getReferentRawObject() const;
DebuggerSourceReferent getReferent() const;
static DebuggerSource* check(JSContext* cx, HandleValue v,
const char* fnname);
template <typename ReferentT>
static DebuggerSource* checkThis(JSContext* cx, const CallArgs& args,
const char* fnname, const char* refname);
// JS methods
static DebuggerSource* check(JSContext* cx, HandleValue v);
static bool construct(JSContext* cx, unsigned argc, Value* vp);
static bool getText(JSContext* cx, unsigned argc, Value* vp);
static bool getBinary(JSContext* cx, unsigned argc, Value* vp);
static bool getURL(JSContext* cx, unsigned argc, Value* vp);
static bool getStartLine(JSContext* cx, unsigned argc, Value* vp);
static bool getId(JSContext* cx, unsigned argc, Value* vp);
static bool getDisplayURL(JSContext* cx, unsigned argc, Value* vp);
static bool getElement(JSContext* cx, unsigned argc, Value* vp);
static bool getElementProperty(JSContext* cx, unsigned argc, Value* vp);
static bool getIntroductionScript(JSContext* cx, unsigned argc, Value* vp);
static bool getIntroductionOffset(JSContext* cx, unsigned argc, Value* vp);
static bool getIntroductionType(JSContext* cx, unsigned argc, Value* vp);
static bool setSourceMapURL(JSContext* cx, unsigned argc, Value* vp);
static bool getSourceMapURL(JSContext* cx, unsigned argc, Value* vp);
static bool reparse(JSContext* cx, unsigned argc, Value* vp);
struct CallData;
private:
static const JSClassOps classOps_;