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
#include "debugger/NoExecute.h"
8
9
#include "mozilla/Sprintf.h" // for SprintfLiteral
10
11
#include <stdio.h> // for fprintf, stdout
12
13
#include "jsapi.h" // for Handle
14
#include "jsfriendapi.h" // for DumpBacktrace, GetErrorMessage
15
16
#include "debugger/Debugger.h" // for Debugger
17
#include "gc/Barrier.h" // for GCPtrNativeObject
18
#include "js/Promise.h" // for AutoDebuggerJobQueueInterruption
19
#include "vm/JSContext.h" // for ProtectedDataContextArg, JSContext
20
#include "vm/JSScript.h" // for JSScript
21
#include "vm/Realm.h" // for AutoRealm, Realm
22
23
#include "vm/Realm-inl.h" // for AutoRealm::AutoRealm
24
25
using namespace js;
26
27
EnterDebuggeeNoExecute::EnterDebuggeeNoExecute(
28
JSContext* cx, Debugger& dbg,
29
const JS::AutoDebuggerJobQueueInterruption& adjqiProof)
30
: dbg_(dbg), unlocked_(nullptr), reported_(false) {
31
MOZ_ASSERT(adjqiProof.initialized());
32
stack_ = &cx->noExecuteDebuggerTop.ref();
33
prev_ = *stack_;
34
*stack_ = this;
35
}
36
37
#ifdef DEBUG
38
/* static */
39
bool EnterDebuggeeNoExecute::isLockedInStack(JSContext* cx, Debugger& dbg) {
40
for (EnterDebuggeeNoExecute* it = cx->noExecuteDebuggerTop; it;
41
it = it->prev_) {
42
if (&it->debugger() == &dbg) {
43
return !it->unlocked_;
44
}
45
}
46
return false;
47
}
48
#endif
49
50
/* static */
51
EnterDebuggeeNoExecute* EnterDebuggeeNoExecute::findInStack(JSContext* cx) {
52
Realm* debuggee = cx->realm();
53
for (EnterDebuggeeNoExecute* it = cx->noExecuteDebuggerTop; it;
54
it = it->prev_) {
55
Debugger& dbg = it->debugger();
56
if (!it->unlocked_ && dbg.observesGlobal(debuggee->maybeGlobal())) {
57
return it;
58
}
59
}
60
return nullptr;
61
}
62
63
/* static */
64
bool EnterDebuggeeNoExecute::reportIfFoundInStack(JSContext* cx,
65
HandleScript script) {
66
if (EnterDebuggeeNoExecute* nx = findInStack(cx)) {
67
bool warning = !cx->options().throwOnDebuggeeWouldRun();
68
if (!warning || !nx->reported_) {
69
AutoRealm ar(cx, nx->debugger().toJSObject());
70
nx->reported_ = true;
71
if (cx->options().dumpStackOnDebuggeeWouldRun()) {
72
fprintf(stdout, "Dumping stack for DebuggeeWouldRun:\n");
73
DumpBacktrace(cx);
74
}
75
const char* filename = script->filename() ? script->filename() : "(none)";
76
char linenoStr[15];
77
SprintfLiteral(linenoStr, "%u", script->lineno());
78
unsigned flags = warning ? JSREPORT_WARNING : JSREPORT_ERROR;
79
// FIXME: filename should be UTF-8 (bug 987069).
80
return JS_ReportErrorFlagsAndNumberLatin1(
81
cx, flags, GetErrorMessage, nullptr, JSMSG_DEBUGGEE_WOULD_RUN,
82
filename, linenoStr);
83
}
84
}
85
return true;
86
}