123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- #ifndef mozilla_jsipc_JavaScriptLogging__
- #define mozilla_jsipc_JavaScriptLogging__
- #include "nsString.h"
- #include "nsPrintfCString.h"
- #include "jsfriendapi.h"
- #include "jswrapper.h"
- namespace mozilla {
- namespace jsipc {
- #define LOG(...) \
- PR_BEGIN_MACRO \
- if (LoggingEnabled()) { \
- Logging log(this, cx); \
- log.print(__VA_ARGS__); \
- } \
- PR_END_MACRO
- #define LOG_STACK() \
- PR_BEGIN_MACRO \
- if (StackLoggingEnabled()) { \
- js::DumpBacktrace(cx); \
- } \
- PR_END_MACRO
- struct ReceiverObj
- {
- ObjectId id;
- explicit ReceiverObj(ObjectId id) : id(id) {}
- };
- struct InVariant
- {
- JSVariant variant;
- explicit InVariant(const JSVariant& variant) : variant(variant) {}
- };
- struct OutVariant
- {
- JSVariant variant;
- explicit OutVariant(const JSVariant& variant) : variant(variant) {}
- };
- struct Identifier
- {
- JSIDVariant variant;
- explicit Identifier(const JSIDVariant& variant) : variant(variant) {}
- };
- class Logging
- {
- public:
- Logging(JavaScriptShared* shared, JSContext* cx) : shared(shared), cx(cx) {}
- void print(const nsCString& str) {
- const char* side = shared->isParent() ? "from child" : "from parent";
- printf("CPOW %s: %s\n", side, str.get());
- }
- void print(const char* str) {
- print(nsCString(str));
- }
- template<typename T1>
- void print(const char* fmt, const T1& a1) {
- nsAutoCString tmp1;
- format(a1, tmp1);
- print(nsPrintfCString(fmt, tmp1.get()));
- }
- template<typename T1, typename T2>
- void print(const char* fmt, const T1& a1, const T2& a2) {
- nsAutoCString tmp1;
- nsAutoCString tmp2;
- format(a1, tmp1);
- format(a2, tmp2);
- print(nsPrintfCString(fmt, tmp1.get(), tmp2.get()));
- }
- template<typename T1, typename T2, typename T3>
- void print(const char* fmt, const T1& a1, const T2& a2, const T3& a3) {
- nsAutoCString tmp1;
- nsAutoCString tmp2;
- nsAutoCString tmp3;
- format(a1, tmp1);
- format(a2, tmp2);
- format(a3, tmp3);
- print(nsPrintfCString(fmt, tmp1.get(), tmp2.get(), tmp3.get()));
- }
- void format(const nsString& str, nsCString& out) {
- out = NS_ConvertUTF16toUTF8(str);
- }
- void formatObject(bool incoming, bool local, ObjectId id, nsCString& out) {
- const char* side;
- const char* objDesc;
- void* ptr;
- if (local == incoming) {
- JS::RootedObject obj(cx);
- obj = shared->objects_.find(id);
- if (obj) {
- JSAutoCompartment ac(cx, obj);
- objDesc = js::ObjectClassName(cx, obj);
- } else {
- objDesc = "<dead object>";
- }
- side = shared->isParent() ? "parent" : "child";
- ptr = js::UncheckedUnwrap(obj, true);
- } else {
- objDesc = "<cpow>";
- side = shared->isParent() ? "child" : "parent";
- ptr = nullptr;
- }
- out = nsPrintfCString("<%s %s:%d:%p>", side, objDesc, id.serialNumber(), ptr);
- }
- void format(const ReceiverObj& obj, nsCString& out) {
- formatObject(true, true, obj.id, out);
- }
- void format(const nsTArray<JSParam>& values, nsCString& out) {
- nsAutoCString tmp;
- out.Truncate();
- for (size_t i = 0; i < values.Length(); i++) {
- if (i)
- out.AppendLiteral(", ");
- if (values[i].type() == JSParam::Tvoid_t) {
- out.AppendLiteral("<void>");
- } else {
- format(InVariant(values[i].get_JSVariant()), tmp);
- out += tmp;
- }
- }
- }
- void format(const InVariant& value, nsCString& out) {
- format(true, value.variant, out);
- }
- void format(const OutVariant& value, nsCString& out) {
- format(false, value.variant, out);
- }
- void format(bool incoming, const JSVariant& value, nsCString& out) {
- switch (value.type()) {
- case JSVariant::TUndefinedVariant: {
- out = "undefined";
- break;
- }
- case JSVariant::TNullVariant: {
- out = "null";
- break;
- }
- case JSVariant::TnsString: {
- nsAutoCString tmp;
- format(value.get_nsString(), tmp);
- out = nsPrintfCString("\"%s\"", tmp.get());
- break;
- }
- case JSVariant::TObjectVariant: {
- const ObjectVariant& ovar = value.get_ObjectVariant();
- if (ovar.type() == ObjectVariant::TLocalObject)
- formatObject(incoming, true, ObjectId::deserialize(ovar.get_LocalObject().serializedId()), out);
- else
- formatObject(incoming, false, ObjectId::deserialize(ovar.get_RemoteObject().serializedId()), out);
- break;
- }
- case JSVariant::TSymbolVariant: {
- out = "<Symbol>";
- break;
- }
- case JSVariant::Tdouble: {
- out = nsPrintfCString("%.0f", value.get_double());
- break;
- }
- case JSVariant::Tbool: {
- out = value.get_bool() ? "true" : "false";
- break;
- }
- case JSVariant::TJSIID: {
- out = "<JSIID>";
- break;
- }
- default: {
- out = "<JSIID>";
- break;
- }
- }
- }
- void format(const Identifier& id, nsCString& out) {
- switch (id.variant.type()) {
- case JSIDVariant::TSymbolVariant: {
- out = "<Symbol>";
- break;
- }
- case JSIDVariant::TnsString: {
- nsAutoCString tmp;
- format(id.variant.get_nsString(), tmp);
- out = nsPrintfCString("\"%s\"", tmp.get());
- break;
- }
- case JSIDVariant::Tint32_t: {
- out = nsPrintfCString("%d", id.variant.get_int32_t());
- break;
- }
- default: {
- out = "Unknown";
- break;
- }
- }
- }
- private:
- JavaScriptShared* shared;
- JSContext* cx;
- };
- } // namespace jsipc
- } // namespace mozilla
- #endif
|