Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/js/ipc/JavaScriptLogging.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2
 * vim: set ts=8 sw=4 et tw=80:
3
 *
4
 * This Source Code Form is subject to the terms of the Mozilla Public
5
 * License, v. 2.0. If a copy of the MPL was not distributed with this
6
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7
8
#ifndef mozilla_jsipc_JavaScriptLogging__
9
#define mozilla_jsipc_JavaScriptLogging__
10
11
#include "nsString.h"
12
#include "nsPrintfCString.h"
13
#include "jsfriendapi.h"
14
#include "js/Wrapper.h"
15
16
namespace mozilla {
17
namespace jsipc {
18
19
#define LOG(...)                           \
20
0
    PR_BEGIN_MACRO                                                             \
21
0
    if (LoggingEnabled()) {                                                    \
22
0
  Logging log(this, cx);                         \
23
0
  log.print(__VA_ARGS__);                        \
24
0
    }                                                                          \
25
0
    PR_END_MACRO
26
27
#define LOG_STACK()                                                  \
28
0
    PR_BEGIN_MACRO                                                             \
29
0
    if (StackLoggingEnabled()) {                                               \
30
0
        js::DumpBacktrace(cx);                                                 \
31
0
    }                                                                          \
32
0
    PR_END_MACRO
33
34
struct ReceiverObj
35
{
36
    ObjectId id;
37
0
    explicit ReceiverObj(ObjectId id) : id(id) {}
38
};
39
40
struct InVariant
41
{
42
    JSVariant variant;
43
0
    explicit InVariant(const JSVariant& variant) : variant(variant) {}
44
};
45
46
struct OutVariant
47
{
48
    JSVariant variant;
49
0
    explicit OutVariant(const JSVariant& variant) : variant(variant) {}
50
};
51
52
struct Identifier
53
{
54
    JSIDVariant variant;
55
0
    explicit Identifier(const JSIDVariant& variant) : variant(variant) {}
56
};
57
58
class Logging
59
{
60
  public:
61
0
    Logging(JavaScriptShared* shared, JSContext* cx) : shared(shared), cx(cx) {}
62
63
0
    void print(const nsCString& str) {
64
0
        const char* side = shared->isParent() ? "from child" : "from parent";
65
0
        printf("CPOW %s: %s\n", side, str.get());
66
0
    }
67
68
0
    void print(const char* str) {
69
0
        print(nsCString(str));
70
0
    }
71
    template<typename T1>
72
0
    void print(const char* fmt, const T1& a1) {
73
0
        nsAutoCString tmp1;
74
0
        format(a1, tmp1);
75
0
        print(nsPrintfCString(fmt, tmp1.get()));
76
0
    }
77
    template<typename T1, typename T2>
78
0
    void print(const char* fmt, const T1& a1, const T2& a2) {
79
0
        nsAutoCString tmp1;
80
0
        nsAutoCString tmp2;
81
0
        format(a1, tmp1);
82
0
        format(a2, tmp2);
83
0
        print(nsPrintfCString(fmt, tmp1.get(), tmp2.get()));
84
0
    }
Unexecuted instantiation: void mozilla::jsipc::Logging::print<mozilla::jsipc::ReceiverObj, mozilla::jsipc::Identifier>(char const*, mozilla::jsipc::ReceiverObj const&, mozilla::jsipc::Identifier const&)
Unexecuted instantiation: void mozilla::jsipc::Logging::print<mozilla::jsipc::ReceiverObj, mozilla::jsipc::InVariant>(char const*, mozilla::jsipc::ReceiverObj const&, mozilla::jsipc::InVariant const&)
85
    template<typename T1, typename T2, typename T3>
86
0
    void print(const char* fmt, const T1& a1, const T2& a2, const T3& a3) {
87
0
        nsAutoCString tmp1;
88
0
        nsAutoCString tmp2;
89
0
        nsAutoCString tmp3;
90
0
        format(a1, tmp1);
91
0
        format(a2, tmp2);
92
0
        format(a3, tmp3);
93
0
        print(nsPrintfCString(fmt, tmp1.get(), tmp2.get(), tmp3.get()));
94
0
    }
Unexecuted instantiation: void mozilla::jsipc::Logging::print<mozilla::jsipc::ReceiverObj, mozilla::jsipc::Identifier, mozilla::jsipc::OutVariant>(char const*, mozilla::jsipc::ReceiverObj const&, mozilla::jsipc::Identifier const&, mozilla::jsipc::OutVariant const&)
Unexecuted instantiation: void mozilla::jsipc::Logging::print<mozilla::jsipc::ReceiverObj, mozilla::jsipc::Identifier, mozilla::jsipc::InVariant>(char const*, mozilla::jsipc::ReceiverObj const&, mozilla::jsipc::Identifier const&, mozilla::jsipc::InVariant const&)
Unexecuted instantiation: void mozilla::jsipc::Logging::print<mozilla::jsipc::ReceiverObj, nsTArray<mozilla::jsipc::JSParam>, mozilla::jsipc::OutVariant>(char const*, mozilla::jsipc::ReceiverObj const&, nsTArray<mozilla::jsipc::JSParam> const&, mozilla::jsipc::OutVariant const&)
95
96
0
    void format(const nsString& str, nsCString& out) {
97
0
        out = NS_ConvertUTF16toUTF8(str);
98
0
    }
99
100
0
    void formatObject(bool incoming, bool local, ObjectId id, nsCString& out) {
101
0
        const char* side;
102
0
        const char* objDesc;
103
0
        void* ptr;
104
0
105
0
        if (local == incoming) {
106
0
            JS::RootedObject obj(cx);
107
0
            obj = shared->objects_.find(id);
108
0
            obj = js::UncheckedUnwrap(obj, true);
109
0
110
0
            JSAutoRealm ar(cx, obj);
111
0
            objDesc = js::ObjectClassName(cx, obj);
112
0
            side = shared->isParent() ? "parent" : "child";
113
0
            ptr = obj;
114
0
        } else {
115
0
            objDesc = "<cpow>";
116
0
            side = shared->isParent() ? "child" : "parent";
117
0
            ptr = nullptr;
118
0
        }
119
0
120
0
        out = nsPrintfCString("<%s %s:%" PRIu64 ":%p>", side, objDesc, id.serialNumber(), ptr);
121
0
    }
122
123
0
    void format(const ReceiverObj& obj, nsCString& out) {
124
0
        formatObject(true, true, obj.id, out);
125
0
    }
126
127
0
    void format(const nsTArray<JSParam>& values, nsCString& out) {
128
0
        nsAutoCString tmp;
129
0
        out.Truncate();
130
0
        for (size_t i = 0; i < values.Length(); i++) {
131
0
            if (i) {
132
0
                out.AppendLiteral(", ");
133
0
            }
134
0
            if (values[i].type() == JSParam::Tvoid_t) {
135
0
                out.AppendLiteral("<void>");
136
0
            } else {
137
0
                format(InVariant(values[i].get_JSVariant()), tmp);
138
0
                out += tmp;
139
0
            }
140
0
        }
141
0
    }
142
143
0
    void format(const InVariant& value, nsCString& out) {
144
0
        format(true, value.variant, out);
145
0
    }
146
147
0
    void format(const OutVariant& value, nsCString& out) {
148
0
        format(false, value.variant, out);
149
0
    }
150
151
0
    void format(bool incoming, const JSVariant& value, nsCString& out) {
152
0
        switch (value.type()) {
153
0
          case JSVariant::TUndefinedVariant: {
154
0
              out = "undefined";
155
0
              break;
156
0
          }
157
0
          case JSVariant::TNullVariant: {
158
0
              out = "null";
159
0
              break;
160
0
          }
161
0
          case JSVariant::TnsString: {
162
0
              nsAutoCString tmp;
163
0
              format(value.get_nsString(), tmp);
164
0
              out = nsPrintfCString("\"%s\"", tmp.get());
165
0
              break;
166
0
          }
167
0
          case JSVariant::TObjectVariant: {
168
0
              const ObjectVariant& ovar = value.get_ObjectVariant();
169
0
              if (ovar.type() == ObjectVariant::TLocalObject) {
170
0
                  Maybe<ObjectId> objId(ObjectId::deserialize(ovar.get_LocalObject().serializedId()));
171
0
                  MOZ_RELEASE_ASSERT(objId.isSome());
172
0
                  formatObject(incoming, true, objId.value(), out);
173
0
              } else {
174
0
                  Maybe<ObjectId> objId(ObjectId::deserialize(ovar.get_RemoteObject().serializedId()));
175
0
                  MOZ_RELEASE_ASSERT(objId.isSome());
176
0
                  formatObject(incoming, false, objId.value(), out);
177
0
              }
178
0
              break;
179
0
          }
180
0
          case JSVariant::TSymbolVariant: {
181
0
              out = "<Symbol>";
182
0
              break;
183
0
          }
184
0
          case JSVariant::Tdouble: {
185
0
              out = nsPrintfCString("%.0f", value.get_double());
186
0
              break;
187
0
          }
188
0
          case JSVariant::Tbool: {
189
0
              out = value.get_bool() ? "true" : "false";
190
0
              break;
191
0
          }
192
0
          case JSVariant::TJSIID: {
193
0
              out = "<JSIID>";
194
0
              break;
195
0
          }
196
0
          default: {
197
0
              out = "<JSIID>";
198
0
              break;
199
0
          }
200
0
        }
201
0
    }
202
203
    void format(const Identifier& id, nsCString& out) {
204
        switch (id.variant.type()) {
205
          case JSIDVariant::TSymbolVariant: {
206
              out = "<Symbol>";
207
              break;
208
          }
209
          case JSIDVariant::TnsString: {
210
              nsAutoCString tmp;
211
              format(id.variant.get_nsString(), tmp);
212
              out = nsPrintfCString("\"%s\"", tmp.get());
213
              break;
214
          }
215
          case JSIDVariant::Tint32_t: {
216
              out = nsPrintfCString("%d", id.variant.get_int32_t());
217
              break;
218
          }
219
          default: {
220
              out = "Unknown";
221
              break;
222
          }
223
      }
224
    }
225
226
  private:
227
    JavaScriptShared* shared;
228
    JSContext* cx;
229
};
230
231
} // namespace jsipc
232
} // namespace mozilla
233
234
#endif