Bumping manifests a=b2g-bump
[gecko.git] / js / ipc / JavaScriptLogging.h
blob13a965e9c171c6c632cad1dc3bf095a3182673ab
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sw=4 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 "jswrapper.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
36 ObjectId id;
37 explicit ReceiverObj(ObjectId id) : id(id) {}
40 struct InVariant
42 JSVariant variant;
43 explicit InVariant(const JSVariant& variant) : variant(variant) {}
46 struct OutVariant
48 JSVariant variant;
49 explicit OutVariant(const JSVariant& variant) : variant(variant) {}
52 struct Identifier
54 JSIDVariant variant;
55 explicit Identifier(const JSIDVariant& variant) : variant(variant) {}
58 class Logging
60 public:
61 Logging(JavaScriptShared* shared, JSContext* cx) : shared(shared), cx(cx) {}
63 void print(const nsCString& str) {
64 const char* side = shared->isParent() ? "from child" : "from parent";
65 printf("CPOW %s: %s\n", side, str.get());
68 void print(const char* str) {
69 print(nsCString(str));
71 template<typename T1>
72 void print(const char* fmt, const T1& a1) {
73 nsAutoCString tmp1;
74 format(a1, tmp1);
75 print(nsPrintfCString(fmt, tmp1.get()));
77 template<typename T1, typename T2>
78 void print(const char* fmt, const T1& a1, const T2& a2) {
79 nsAutoCString tmp1;
80 nsAutoCString tmp2;
81 format(a1, tmp1);
82 format(a2, tmp2);
83 print(nsPrintfCString(fmt, tmp1.get(), tmp2.get()));
85 template<typename T1, typename T2, typename T3>
86 void print(const char* fmt, const T1& a1, const T2& a2, const T3& a3) {
87 nsAutoCString tmp1;
88 nsAutoCString tmp2;
89 nsAutoCString tmp3;
90 format(a1, tmp1);
91 format(a2, tmp2);
92 format(a3, tmp3);
93 print(nsPrintfCString(fmt, tmp1.get(), tmp2.get(), tmp3.get()));
96 void format(const nsString& str, nsCString& out) {
97 out = NS_ConvertUTF16toUTF8(str);
100 void formatObject(bool incoming, bool local, ObjectId id, nsCString& out) {
101 const char* side, *objDesc;
102 void* ptr;
104 if (local == incoming) {
105 JS::RootedObject obj(cx);
106 obj = shared->objects_.find(id);
107 if (obj) {
108 JSAutoCompartment ac(cx, obj);
109 objDesc = js_ObjectClassName(cx, obj);
110 } else {
111 objDesc = "<dead object>";
114 side = shared->isParent() ? "parent" : "child";
115 ptr = js::UncheckedUnwrap(obj, true);
116 } else {
117 objDesc = "<cpow>";
118 side = shared->isParent() ? "child" : "parent";
119 ptr = nullptr;
122 out = nsPrintfCString("<%s %s:%d:%p>", side, objDesc, id.serialNumber(), ptr);
125 void format(const ReceiverObj& obj, nsCString& out) {
126 formatObject(true, true, obj.id, out);
129 void format(const nsTArray<JSParam>& values, nsCString& out) {
130 nsAutoCString tmp;
131 out.Truncate();
132 for (size_t i = 0; i < values.Length(); i++) {
133 if (i)
134 out.AppendLiteral(", ");
135 if (values[i].type() == JSParam::Tvoid_t) {
136 out.AppendLiteral("<void>");
137 } else {
138 format(InVariant(values[i].get_JSVariant()), tmp);
139 out += tmp;
144 void format(const InVariant& value, nsCString& out) {
145 format(true, value.variant, out);
148 void format(const OutVariant& value, nsCString& out) {
149 format(false, value.variant, out);
152 void format(bool incoming, const JSVariant& value, nsCString& out) {
153 switch (value.type()) {
154 case JSVariant::TUndefinedVariant: {
155 out = "undefined";
156 break;
158 case JSVariant::TNullVariant: {
159 out = "null";
160 break;
162 case JSVariant::TnsString: {
163 nsAutoCString tmp;
164 format(value.get_nsString(), tmp);
165 out = nsPrintfCString("\"%s\"", tmp.get());
166 break;
168 case JSVariant::TObjectVariant: {
169 const ObjectVariant& ovar = value.get_ObjectVariant();
170 if (ovar.type() == ObjectVariant::TLocalObject)
171 formatObject(incoming, true, ObjectId::deserialize(ovar.get_LocalObject().serializedId()), out);
172 else
173 formatObject(incoming, false, ObjectId::deserialize(ovar.get_RemoteObject().serializedId()), 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;
230 #endif