DebugAPI-inl.h (5966B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef debugger_DebugAPI_inl_h 8 #define debugger_DebugAPI_inl_h 9 10 #include "debugger/DebugAPI.h" 11 12 #include "gc/GC.h" 13 #include "vm/GeneratorObject.h" 14 #include "vm/PromiseObject.h" // js::PromiseObject 15 16 #include "vm/Stack-inl.h" 17 18 namespace js { 19 20 /* static */ 21 bool DebugAPI::stepModeEnabled(JSScript* script) { 22 return script->hasDebugScript() && stepModeEnabledSlow(script); 23 } 24 25 /* static */ 26 bool DebugAPI::hasBreakpointsAt(JSScript* script, jsbytecode* pc) { 27 return script->hasDebugScript() && hasBreakpointsAtSlow(script, pc); 28 } 29 30 /* static */ 31 bool DebugAPI::hasAnyBreakpointsOrStepMode(JSScript* script) { 32 return script->hasDebugScript(); 33 } 34 35 /* static */ 36 void DebugAPI::onNewGlobalObject(JSContext* cx, Handle<GlobalObject*> global) { 37 MOZ_ASSERT(!global->realm()->firedOnNewGlobalObject); 38 #ifdef DEBUG 39 global->realm()->firedOnNewGlobalObject = true; 40 #endif 41 if (!cx->runtime()->onNewGlobalObjectWatchers().isEmpty()) { 42 slowPathOnNewGlobalObject(cx, global); 43 } 44 } 45 46 /* static */ 47 void DebugAPI::notifyParticipatesInGC(GlobalObject* global, 48 uint64_t majorGCNumber) { 49 JS::AutoAssertNoGC nogc; 50 Realm::DebuggerVector& dbgs = global->getDebuggers(nogc); 51 if (!dbgs.empty()) { 52 slowPathNotifyParticipatesInGC(majorGCNumber, dbgs, nogc); 53 } 54 } 55 56 /* static */ 57 bool DebugAPI::onLogAllocationSite(JSContext* cx, JSObject* obj, 58 Handle<SavedFrame*> frame, 59 mozilla::TimeStamp when) { 60 // slowPathOnLogAllocationSite creates GC things so we must suppress GC here. 61 gc::AutoSuppressGC nogc(cx); 62 63 Realm::DebuggerVector& dbgs = cx->global()->getDebuggers(nogc); 64 if (dbgs.empty()) { 65 return true; 66 } 67 RootedObject hobj(cx, obj); 68 return slowPathOnLogAllocationSite(cx, hobj, frame, when, dbgs, nogc); 69 } 70 71 /* static */ 72 bool DebugAPI::onLeaveFrame(JSContext* cx, AbstractFramePtr frame, 73 const jsbytecode* pc, bool ok) { 74 MOZ_ASSERT_IF(frame.isInterpreterFrame(), 75 frame.asInterpreterFrame() == cx->interpreterFrame()); 76 MOZ_ASSERT_IF(frame.hasScript() && frame.script()->isDebuggee(), 77 frame.isDebuggee()); 78 /* Traps must be cleared from eval frames, see slowPathOnLeaveFrame. */ 79 mozilla::DebugOnly<bool> evalTraps = 80 frame.isEvalFrame() && frame.script()->hasDebugScript(); 81 MOZ_ASSERT_IF(evalTraps, frame.isDebuggee()); 82 if (frame.isDebuggee()) { 83 ok = slowPathOnLeaveFrame(cx, frame, pc, ok); 84 } 85 MOZ_ASSERT(!inFrameMaps(frame)); 86 return ok; 87 } 88 89 /* static */ 90 bool DebugAPI::onNewGenerator(JSContext* cx, AbstractFramePtr frame, 91 Handle<AbstractGeneratorObject*> genObj) { 92 if (frame.isDebuggee()) { 93 return slowPathOnNewGenerator(cx, frame, genObj); 94 } 95 return true; 96 } 97 98 /* static */ 99 void DebugAPI::onGeneratorClosed(JSContext* cx, 100 AbstractGeneratorObject* genObj) { 101 if (cx->realm()->isDebuggee()) { 102 slowPathOnGeneratorClosed(cx, genObj); 103 } 104 } 105 106 /* static */ 107 bool DebugAPI::checkNoExecute(JSContext* cx, HandleScript script) { 108 if (!cx->realm()->isDebuggee() || !cx->noExecuteDebuggerTop) { 109 return true; 110 } 111 return slowPathCheckNoExecute(cx, script); 112 } 113 114 /* static */ 115 bool DebugAPI::onEnterFrame(JSContext* cx, AbstractFramePtr frame) { 116 MOZ_ASSERT_IF(frame.hasScript() && frame.script()->isDebuggee(), 117 frame.isDebuggee()); 118 if (MOZ_UNLIKELY(frame.isDebuggee())) { 119 return slowPathOnEnterFrame(cx, frame); 120 } 121 return true; 122 } 123 124 /* static */ 125 bool DebugAPI::onResumeFrame(JSContext* cx, AbstractFramePtr frame) { 126 MOZ_ASSERT_IF(frame.hasScript() && frame.script()->isDebuggee(), 127 frame.isDebuggee()); 128 if (MOZ_UNLIKELY(frame.isDebuggee())) { 129 return slowPathOnResumeFrame(cx, frame); 130 } 131 return true; 132 } 133 134 /* static */ 135 NativeResumeMode DebugAPI::onNativeCall(JSContext* cx, const CallArgs& args, 136 CallReason reason) { 137 if (MOZ_UNLIKELY(cx->realm()->isDebuggee())) { 138 return slowPathOnNativeCall(cx, args, reason); 139 } 140 141 return NativeResumeMode::Continue; 142 } 143 144 /* static */ 145 bool DebugAPI::shouldAvoidSideEffects(JSContext* cx) { 146 if (MOZ_UNLIKELY(cx->realm()->isDebuggee())) { 147 return slowPathShouldAvoidSideEffects(cx); 148 } 149 150 return false; 151 } 152 153 /* static */ 154 bool DebugAPI::onDebuggerStatement(JSContext* cx, AbstractFramePtr frame) { 155 if (MOZ_UNLIKELY(cx->realm()->isDebuggee())) { 156 return slowPathOnDebuggerStatement(cx, frame); 157 } 158 159 return true; 160 } 161 162 /* static */ 163 bool DebugAPI::onExceptionUnwind(JSContext* cx, AbstractFramePtr frame) { 164 if (MOZ_UNLIKELY(cx->realm()->isDebuggee())) { 165 return slowPathOnExceptionUnwind(cx, frame); 166 } 167 return true; 168 } 169 170 /* static */ 171 void DebugAPI::onNewWasmInstance(JSContext* cx, 172 Handle<WasmInstanceObject*> wasmInstance) { 173 if (cx->realm()->isDebuggee()) { 174 slowPathOnNewWasmInstance(cx, wasmInstance); 175 } 176 } 177 178 /* static */ 179 void DebugAPI::onNewPromise(JSContext* cx, Handle<PromiseObject*> promise) { 180 if (MOZ_UNLIKELY(cx->realm()->isDebuggee())) { 181 slowPathOnNewPromise(cx, promise); 182 } 183 } 184 185 /* static */ 186 void DebugAPI::onPromiseSettled(JSContext* cx, Handle<PromiseObject*> promise) { 187 if (MOZ_UNLIKELY(promise->realm()->isDebuggee())) { 188 slowPathOnPromiseSettled(cx, promise); 189 } 190 } 191 192 /* static */ 193 void DebugAPI::traceGeneratorFrame(JSTracer* tracer, 194 AbstractGeneratorObject* generator) { 195 if (MOZ_UNLIKELY(generator->realm()->isDebuggee())) { 196 slowPathTraceGeneratorFrame(tracer, generator); 197 } 198 } 199 200 } // namespace js 201 202 #endif /* debugger_DebugAPI_inl_h */