Bug 1521243 - Show a warning for invalid declarations and filter icon for overridden...
[gecko.git] / js / ipc / JavaScriptLogging.h
blob07cec89dd9740c882aca2332e5f00de20709eb59
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sw=2 et tw=80:
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/. */
8 #ifndef mozilla_jsipc_JavaScriptLogging__
9 #define mozilla_jsipc_JavaScriptLogging__
11 #include "nsString.h"
12 #include "nsPrintfCString.h"
13 #include "jsfriendapi.h"
14 #include "js/Wrapper.h"
16 namespace mozilla {
17 namespace jsipc {
19 #define LOG(...) \
20 PR_BEGIN_MACRO \
21 if (LoggingEnabled()) { \
22 Logging log(this, cx); \
23 log.print(__VA_ARGS__); \
24 } \
25 PR_END_MACRO
27 #define LOG_STACK() \
28 PR_BEGIN_MACRO \
29 if (StackLoggingEnabled()) { \
30 js::DumpBacktrace(cx); \
31 } \
32 PR_END_MACRO
34 struct ReceiverObj {
35 ObjectId id;
36 explicit ReceiverObj(ObjectId id) : id(id) {}
39 struct InVariant {
40 JSVariant variant;
41 explicit InVariant(const JSVariant& variant) : variant(variant) {}
44 struct OutVariant {
45 JSVariant variant;
46 explicit OutVariant(const JSVariant& variant) : variant(variant) {}
49 struct Identifier {
50 JSIDVariant variant;
51 explicit Identifier(const JSIDVariant& variant) : variant(variant) {}
54 class Logging {
55 public:
56 Logging(JavaScriptShared* shared, JSContext* cx) : shared(shared), cx(cx) {}
58 void print(const nsCString& str) {
59 const char* side = shared->isParent() ? "from child" : "from parent";
60 printf("CPOW %s: %s\n", side, str.get());
63 void print(const char* str) { print(nsCString(str)); }
64 template <typename T1>
65 void print(const char* fmt, const T1& a1) {
66 nsAutoCString tmp1;
67 format(a1, tmp1);
68 print(nsPrintfCString(fmt, tmp1.get()));
70 template <typename T1, typename T2>
71 void print(const char* fmt, const T1& a1, const T2& a2) {
72 nsAutoCString tmp1;
73 nsAutoCString tmp2;
74 format(a1, tmp1);
75 format(a2, tmp2);
76 print(nsPrintfCString(fmt, tmp1.get(), tmp2.get()));
78 template <typename T1, typename T2, typename T3>
79 void print(const char* fmt, const T1& a1, const T2& a2, const T3& a3) {
80 nsAutoCString tmp1;
81 nsAutoCString tmp2;
82 nsAutoCString tmp3;
83 format(a1, tmp1);
84 format(a2, tmp2);
85 format(a3, tmp3);
86 print(nsPrintfCString(fmt, tmp1.get(), tmp2.get(), tmp3.get()));
89 void format(const nsString& str, nsCString& out) {
90 out = NS_ConvertUTF16toUTF8(str);
93 void formatObject(bool incoming, bool local, ObjectId id, nsCString& out) {
94 const char* side;
95 const char* objDesc;
96 void* ptr;
98 if (local == incoming) {
99 JS::RootedObject obj(cx);
100 obj = shared->objects_.find(id);
101 obj = js::UncheckedUnwrap(obj, true);
103 JSAutoRealm ar(cx, obj);
104 objDesc = js::ObjectClassName(cx, obj);
105 side = shared->isParent() ? "parent" : "child";
106 ptr = obj;
107 } else {
108 objDesc = "<cpow>";
109 side = shared->isParent() ? "child" : "parent";
110 ptr = nullptr;
113 out = nsPrintfCString("<%s %s:%" PRIu64 ":%p>", side, objDesc,
114 id.serialNumber(), ptr);
117 void format(const ReceiverObj& obj, nsCString& out) {
118 formatObject(true, true, obj.id, out);
121 void format(const nsTArray<JSParam>& values, nsCString& out) {
122 nsAutoCString tmp;
123 out.Truncate();
124 for (size_t i = 0; i < values.Length(); i++) {
125 if (i) {
126 out.AppendLiteral(", ");
128 if (values[i].type() == JSParam::Tvoid_t) {
129 out.AppendLiteral("<void>");
130 } else {
131 format(InVariant(values[i].get_JSVariant()), tmp);
132 out += tmp;
137 void format(const InVariant& value, nsCString& out) {
138 format(true, value.variant, out);
141 void format(const OutVariant& value, nsCString& out) {
142 format(false, value.variant, out);
145 void format(bool incoming, const JSVariant& value, nsCString& out) {
146 switch (value.type()) {
147 case JSVariant::TUndefinedVariant: {
148 out = "undefined";
149 break;
151 case JSVariant::TNullVariant: {
152 out = "null";
153 break;
155 case JSVariant::TnsString: {
156 nsAutoCString tmp;
157 format(value.get_nsString(), tmp);
158 out = nsPrintfCString("\"%s\"", tmp.get());
159 break;
161 case JSVariant::TObjectVariant: {
162 const ObjectVariant& ovar = value.get_ObjectVariant();
163 if (ovar.type() == ObjectVariant::TLocalObject) {
164 Maybe<ObjectId> objId(
165 ObjectId::deserialize(ovar.get_LocalObject().serializedId()));
166 MOZ_RELEASE_ASSERT(objId.isSome());
167 formatObject(incoming, true, objId.value(), out);
168 } else {
169 Maybe<ObjectId> objId(
170 ObjectId::deserialize(ovar.get_RemoteObject().serializedId()));
171 MOZ_RELEASE_ASSERT(objId.isSome());
172 formatObject(incoming, false, objId.value(), out);
174 break;
176 case JSVariant::TSymbolVariant: {
177 out = "<Symbol>";
178 break;
180 case JSVariant::Tdouble: {
181 out = nsPrintfCString("%.0f", value.get_double());
182 break;
184 case JSVariant::Tbool: {
185 out = value.get_bool() ? "true" : "false";
186 break;
188 case JSVariant::TJSIID: {
189 out = "<JSIID>";
190 break;
192 default: {
193 out = "<JSIID>";
194 break;
199 void format(const Identifier& id, nsCString& out) {
200 switch (id.variant.type()) {
201 case JSIDVariant::TSymbolVariant: {
202 out = "<Symbol>";
203 break;
205 case JSIDVariant::TnsString: {
206 nsAutoCString tmp;
207 format(id.variant.get_nsString(), tmp);
208 out = nsPrintfCString("\"%s\"", tmp.get());
209 break;
211 case JSIDVariant::Tint32_t: {
212 out = nsPrintfCString("%d", id.variant.get_int32_t());
213 break;
215 default: {
216 out = "Unknown";
217 break;
222 private:
223 JavaScriptShared* shared;
224 JSContext* cx;
227 } // namespace jsipc
228 } // namespace mozilla
230 #endif