Source code

Revision control

Other Tools

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 "vm/GeneratorObject.h"
13
14
#include "vm/Stack-inl.h"
15
16
namespace js {
17
18
/* static */
19
bool DebugAPI::stepModeEnabled(JSScript* script) {
20
return script->hasDebugScript() && stepModeEnabledSlow(script);
21
}
22
23
/* static */
24
bool DebugAPI::hasBreakpointsAt(JSScript* script, jsbytecode* pc) {
25
return script->hasDebugScript() && hasBreakpointsAtSlow(script, pc);
26
}
27
28
/* static */
29
bool DebugAPI::hasAnyBreakpointsOrStepMode(JSScript* script) {
30
return script->hasDebugScript();
31
}
32
33
/* static */
34
void DebugAPI::onNewScript(JSContext* cx, HandleScript script) {
35
// We early return in slowPathOnNewScript for self-hosted scripts, so we can
36
// ignore those in our assertion here.
37
MOZ_ASSERT_IF(!script->realm()->creationOptions().invisibleToDebugger() &&
38
!script->selfHosted(),
39
script->realm()->firedOnNewGlobalObject);
40
41
// The script may not be ready to be interrogated by the debugger.
42
if (script->hideScriptFromDebugger()) {
43
return;
44
}
45
46
slowPathOnNewScript(cx, script);
47
}
48
49
/* static */
50
void DebugAPI::onNewGlobalObject(JSContext* cx, Handle<GlobalObject*> global) {
51
MOZ_ASSERT(!global->realm()->firedOnNewGlobalObject);
52
#ifdef DEBUG
53
global->realm()->firedOnNewGlobalObject = true;
54
#endif
55
if (!cx->runtime()->onNewGlobalObjectWatchers().isEmpty()) {
56
slowPathOnNewGlobalObject(cx, global);
57
}
58
}
59
60
/* static */
61
void DebugAPI::notifyParticipatesInGC(GlobalObject* global,
62
uint64_t majorGCNumber) {
63
Realm::DebuggerVector& dbgs = global->getDebuggers();
64
if (!dbgs.empty()) {
65
slowPathNotifyParticipatesInGC(majorGCNumber, dbgs);
66
}
67
}
68
69
/* static */
70
bool DebugAPI::onLogAllocationSite(JSContext* cx, JSObject* obj,
71
HandleSavedFrame frame,
72
mozilla::TimeStamp when) {
73
Realm::DebuggerVector& dbgs = cx->global()->getDebuggers();
74
if (dbgs.empty()) {
75
return true;
76
}
77
RootedObject hobj(cx, obj);
78
return slowPathOnLogAllocationSite(cx, hobj, frame, when, dbgs);
79
}
80
81
/* static */
82
bool DebugAPI::onLeaveFrame(JSContext* cx, AbstractFramePtr frame,
83
jsbytecode* pc, bool ok) {
84
MOZ_ASSERT_IF(frame.isInterpreterFrame(),
85
frame.asInterpreterFrame() == cx->interpreterFrame());
86
MOZ_ASSERT_IF(frame.hasScript() && frame.script()->isDebuggee(),
87
frame.isDebuggee());
88
/* Traps must be cleared from eval frames, see slowPathOnLeaveFrame. */
89
mozilla::DebugOnly<bool> evalTraps =
90
frame.isEvalFrame() && frame.script()->hasDebugScript();
91
MOZ_ASSERT_IF(evalTraps, frame.isDebuggee());
92
if (frame.isDebuggee()) {
93
ok = slowPathOnLeaveFrame(cx, frame, pc, ok);
94
}
95
MOZ_ASSERT(!inFrameMaps(frame));
96
return ok;
97
}
98
99
/* static */
100
bool DebugAPI::onNewGenerator(JSContext* cx, AbstractFramePtr frame,
101
Handle<AbstractGeneratorObject*> genObj) {
102
if (frame.isDebuggee()) {
103
return slowPathOnNewGenerator(cx, frame, genObj);
104
}
105
return true;
106
}
107
108
/* static */
109
bool DebugAPI::checkNoExecute(JSContext* cx, HandleScript script) {
110
if (!cx->realm()->isDebuggee() || !cx->noExecuteDebuggerTop) {
111
return true;
112
}
113
return slowPathCheckNoExecute(cx, script);
114
}
115
116
/* static */
117
ResumeMode DebugAPI::onEnterFrame(JSContext* cx, AbstractFramePtr frame) {
118
MOZ_ASSERT_IF(frame.hasScript() && frame.script()->isDebuggee(),
119
frame.isDebuggee());
120
if (!frame.isDebuggee()) {
121
return ResumeMode::Continue;
122
}
123
return slowPathOnEnterFrame(cx, frame);
124
}
125
126
/* static */
127
ResumeMode DebugAPI::onResumeFrame(JSContext* cx, AbstractFramePtr frame) {
128
MOZ_ASSERT_IF(frame.hasScript() && frame.script()->isDebuggee(),
129
frame.isDebuggee());
130
if (!frame.isDebuggee()) {
131
return ResumeMode::Continue;
132
}
133
return slowPathOnResumeFrame(cx, frame);
134
}
135
136
/* static */
137
ResumeMode DebugAPI::onNativeCall(JSContext* cx, const CallArgs& args,
138
CallReason reason) {
139
if (!cx->realm()->isDebuggee()) {
140
return ResumeMode::Continue;
141
}
142
return slowPathOnNativeCall(cx, args, reason);
143
}
144
145
/* static */
146
ResumeMode DebugAPI::onDebuggerStatement(JSContext* cx,
147
AbstractFramePtr frame) {
148
if (!cx->realm()->isDebuggee()) {
149
return ResumeMode::Continue;
150
}
151
return slowPathOnDebuggerStatement(cx, frame);
152
}
153
154
/* static */
155
ResumeMode DebugAPI::onExceptionUnwind(JSContext* cx, AbstractFramePtr frame) {
156
if (!cx->realm()->isDebuggee()) {
157
return ResumeMode::Continue;
158
}
159
return slowPathOnExceptionUnwind(cx, frame);
160
}
161
162
/* static */
163
void DebugAPI::onNewWasmInstance(JSContext* cx,
164
Handle<WasmInstanceObject*> wasmInstance) {
165
if (cx->realm()->isDebuggee()) {
166
slowPathOnNewWasmInstance(cx, wasmInstance);
167
}
168
}
169
170
/* static */
171
void DebugAPI::onNewPromise(JSContext* cx, Handle<PromiseObject*> promise) {
172
if (MOZ_UNLIKELY(cx->realm()->isDebuggee())) {
173
slowPathOnNewPromise(cx, promise);
174
}
175
}
176
177
/* static */
178
void DebugAPI::onPromiseSettled(JSContext* cx, Handle<PromiseObject*> promise) {
179
if (MOZ_UNLIKELY(promise->realm()->isDebuggee())) {
180
slowPathOnPromiseSettled(cx, promise);
181
}
182
}
183
184
/* static */
185
void DebugAPI::traceGeneratorFrame(JSTracer* tracer,
186
AbstractGeneratorObject* generator) {
187
if (MOZ_UNLIKELY(generator->realm()->isDebuggee())) {
188
slowPathTraceGeneratorFrame(tracer, generator);
189
}
190
}
191
192
} // namespace js
193
194
#endif /* debugger_DebugAPI_inl_h */