mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 957742 - Logging for CPOWs (r=mrbkap)
This commit is contained in:
parent
f86aa991e3
commit
28ef5afa8b
@ -25,6 +25,9 @@ class JavaScriptChild : public JavaScriptBase<PJavaScriptChild>
|
||||
|
||||
void drop(JSObject *obj);
|
||||
|
||||
protected:
|
||||
virtual bool isParent() { return false; }
|
||||
|
||||
private:
|
||||
bool fail(JSContext *cx, ReturnStatus *rs);
|
||||
bool ok(ReturnStatus *rs);
|
||||
|
194
js/ipc/JavaScriptLogging.h
Normal file
194
js/ipc/JavaScriptLogging.h
Normal file
@ -0,0 +1,194 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sw=4 et tw=80:
|
||||
*
|
||||
* 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 "js/OldDebugAPI.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;
|
||||
ReceiverObj(ObjectId id) : id(id) {}
|
||||
};
|
||||
|
||||
struct InVariant
|
||||
{
|
||||
JSVariant variant;
|
||||
InVariant(const JSVariant &variant) : variant(variant) {}
|
||||
};
|
||||
|
||||
struct OutVariant
|
||||
{
|
||||
JSVariant variant;
|
||||
OutVariant(const JSVariant &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, *objDesc;
|
||||
|
||||
if (local == incoming) {
|
||||
RootedObject obj(cx);
|
||||
obj = shared->findObjectById(id);
|
||||
if (obj) {
|
||||
JSAutoCompartment ac(cx, obj);
|
||||
objDesc = js_ObjectClassName(cx, obj);
|
||||
} else {
|
||||
objDesc = "<dead object>";
|
||||
}
|
||||
|
||||
side = shared->isParent() ? "parent" : "child";
|
||||
} else {
|
||||
objDesc = "<cpow>";
|
||||
side = shared->isParent() ? "child" : "parent";
|
||||
}
|
||||
|
||||
out = nsPrintfCString("<%s %s:%d>", side, objDesc, id);
|
||||
}
|
||||
|
||||
|
||||
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, ovar.get_LocalObject().id(), out);
|
||||
else
|
||||
formatObject(incoming, false, ovar.get_RemoteObject().id(), out);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
JavaScriptShared *shared;
|
||||
JSContext *cx;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -27,6 +27,9 @@ class JavaScriptParent : public JavaScriptBase<PJavaScriptParent>
|
||||
|
||||
mozilla::ipc::IProtocol*
|
||||
CloneProtocol(Channel* aChannel, ProtocolCloneContext* aCtx) MOZ_OVERRIDE;
|
||||
|
||||
protected:
|
||||
virtual bool isParent() { return true; }
|
||||
};
|
||||
|
||||
} // jsipc
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "mozilla/dom/TabChild.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "xpcprivate.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace JS;
|
||||
@ -144,11 +145,22 @@ ObjectToIdMap::remove(JSObject *obj)
|
||||
table_->remove(obj);
|
||||
}
|
||||
|
||||
bool JavaScriptShared::sLoggingInitialized;
|
||||
bool JavaScriptShared::sLoggingEnabled;
|
||||
bool JavaScriptShared::sStackLoggingEnabled;
|
||||
|
||||
JavaScriptShared::JavaScriptShared(JSRuntime *rt)
|
||||
: rt_(rt),
|
||||
refcount_(1),
|
||||
lastId_(0)
|
||||
{
|
||||
if (!sLoggingInitialized) {
|
||||
sLoggingInitialized = true;
|
||||
Preferences::AddBoolVarCache(&sLoggingEnabled,
|
||||
"dom.ipc.cpows.log.enabled", false);
|
||||
Preferences::AddBoolVarCache(&sStackLoggingEnabled,
|
||||
"dom.ipc.cpows.log.stack", false);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -81,6 +81,8 @@ class ObjectToIdMap
|
||||
Table *table_;
|
||||
};
|
||||
|
||||
class Logging;
|
||||
|
||||
class JavaScriptShared
|
||||
{
|
||||
public:
|
||||
@ -124,6 +126,13 @@ class JavaScriptShared
|
||||
}
|
||||
JSObject *findObjectById(JSContext *cx, uint32_t objId);
|
||||
|
||||
static bool LoggingEnabled() { return sLoggingEnabled; }
|
||||
static bool StackLoggingEnabled() { return sStackLoggingEnabled; }
|
||||
|
||||
friend class Logging;
|
||||
|
||||
virtual bool isParent() = 0;
|
||||
|
||||
protected:
|
||||
JSRuntime *rt_;
|
||||
uintptr_t refcount_;
|
||||
@ -133,6 +142,10 @@ class JavaScriptShared
|
||||
|
||||
ObjectId lastId_;
|
||||
ObjectToIdMap objectIds_;
|
||||
|
||||
static bool sLoggingInitialized;
|
||||
static bool sLoggingEnabled;
|
||||
static bool sStackLoggingEnabled;
|
||||
};
|
||||
|
||||
// Use 47 at most, to be safe, since jsval privates are encoded as doubles.
|
||||
|
@ -6,6 +6,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "WrapperAnswer.h"
|
||||
#include "JavaScriptLogging.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "nsContentUtils.h"
|
||||
@ -71,6 +72,8 @@ WrapperAnswer::AnswerPreventExtensions(const ObjectId &objId, ReturnStatus *rs)
|
||||
if (!JS_PreventExtensions(cx, obj))
|
||||
return fail(cx, rs);
|
||||
|
||||
LOG("%s.preventExtensions()", ReceiverObj(objId));
|
||||
|
||||
return ok(rs);
|
||||
}
|
||||
|
||||
@ -99,6 +102,8 @@ WrapperAnswer::AnswerGetPropertyDescriptor(const ObjectId &objId, const nsString
|
||||
|
||||
JSAutoCompartment comp(cx, obj);
|
||||
|
||||
LOG("%s.getPropertyDescriptor(%s)", ReceiverObj(objId), id);
|
||||
|
||||
RootedId internedId(cx);
|
||||
if (!convertGeckoStringToId(cx, id, &internedId))
|
||||
return fail(cx, rs);
|
||||
@ -131,6 +136,8 @@ WrapperAnswer::AnswerGetOwnPropertyDescriptor(const ObjectId &objId, const nsStr
|
||||
|
||||
JSAutoCompartment comp(cx, obj);
|
||||
|
||||
LOG("%s.getOwnPropertyDescriptor(%s)", ReceiverObj(objId), id);
|
||||
|
||||
RootedId internedId(cx);
|
||||
if (!convertGeckoStringToId(cx, id, &internedId))
|
||||
return fail(cx, rs);
|
||||
@ -161,6 +168,8 @@ WrapperAnswer::AnswerDefineProperty(const ObjectId &objId, const nsString &id,
|
||||
|
||||
JSAutoCompartment comp(cx, obj);
|
||||
|
||||
LOG("define %s[%s]", ReceiverObj(objId), id);
|
||||
|
||||
RootedId internedId(cx);
|
||||
if (!convertGeckoStringToId(cx, id, &internedId))
|
||||
return fail(cx, rs);
|
||||
@ -199,6 +208,8 @@ WrapperAnswer::AnswerDelete(const ObjectId &objId, const nsString &id, ReturnSta
|
||||
|
||||
JSAutoCompartment comp(cx, obj);
|
||||
|
||||
LOG("delete %s[%s]", ReceiverObj(objId), id);
|
||||
|
||||
RootedId internedId(cx);
|
||||
if (!convertGeckoStringToId(cx, id, &internedId))
|
||||
return fail(cx, rs);
|
||||
@ -223,6 +234,8 @@ WrapperAnswer::AnswerHas(const ObjectId &objId, const nsString &id, ReturnStatus
|
||||
|
||||
JSAutoCompartment comp(cx, obj);
|
||||
|
||||
LOG("%s.has(%s)", ReceiverObj(objId), id);
|
||||
|
||||
RootedId internedId(cx);
|
||||
if (!convertGeckoStringToId(cx, id, &internedId))
|
||||
return fail(cx, rs);
|
||||
@ -249,6 +262,8 @@ WrapperAnswer::AnswerHasOwn(const ObjectId &objId, const nsString &id, ReturnSta
|
||||
|
||||
JSAutoCompartment comp(cx, obj);
|
||||
|
||||
LOG("%s.hasOwn(%s)", ReceiverObj(objId), id);
|
||||
|
||||
RootedId internedId(cx);
|
||||
if (!convertGeckoStringToId(cx, id, &internedId))
|
||||
return fail(cx, rs);
|
||||
@ -293,6 +308,8 @@ WrapperAnswer::AnswerGet(const ObjectId &objId, const ObjectId &receiverId, cons
|
||||
if (!toVariant(cx, val, result))
|
||||
return fail(cx, rs);
|
||||
|
||||
LOG("get %s.%s = %s", ReceiverObj(objId), id, OutVariant(*result));
|
||||
|
||||
return ok(rs);
|
||||
}
|
||||
|
||||
@ -318,6 +335,8 @@ WrapperAnswer::AnswerSet(const ObjectId &objId, const ObjectId &receiverId, cons
|
||||
|
||||
JSAutoCompartment comp(cx, obj);
|
||||
|
||||
LOG("set %s[%s] = %s", ReceiverObj(objId), id, InVariant(value));
|
||||
|
||||
RootedId internedId(cx);
|
||||
if (!convertGeckoStringToId(cx, id, &internedId))
|
||||
return fail(cx, rs);
|
||||
@ -351,6 +370,8 @@ WrapperAnswer::AnswerIsExtensible(const ObjectId &objId, ReturnStatus *rs, bool
|
||||
|
||||
JSAutoCompartment comp(cx, obj);
|
||||
|
||||
LOG("%s.isExtensible()", ReceiverObj(objId));
|
||||
|
||||
bool extensible;
|
||||
if (!JS_IsExtensible(cx, obj, &extensible))
|
||||
return fail(cx, rs);
|
||||
@ -453,6 +474,8 @@ WrapperAnswer::AnswerCall(const ObjectId &objId, const nsTArray<JSParam> &argv,
|
||||
outparams->ReplaceElementAt(i, JSParam(variant));
|
||||
}
|
||||
|
||||
LOG("%s.call(%s) = %s", ReceiverObj(objId), argv, OutVariant(*result));
|
||||
|
||||
return ok(rs);
|
||||
}
|
||||
|
||||
@ -472,6 +495,8 @@ WrapperAnswer::AnswerObjectClassIs(const ObjectId &objId, const uint32_t &classV
|
||||
|
||||
JSAutoCompartment comp(cx, obj);
|
||||
|
||||
LOG("%s.objectClassIs()", ReceiverObj(objId));
|
||||
|
||||
*result = js_ObjectClassIs(cx, obj, (js::ESClassValue)classValue);
|
||||
return true;
|
||||
}
|
||||
@ -490,6 +515,8 @@ WrapperAnswer::AnswerClassName(const ObjectId &objId, nsString *name)
|
||||
|
||||
JSAutoCompartment comp(cx, obj);
|
||||
|
||||
LOG("%s.className()", ReceiverObj(objId));
|
||||
|
||||
*name = NS_ConvertASCIItoUTF16(js_ObjectClassName(cx, obj));
|
||||
return true;
|
||||
}
|
||||
@ -507,6 +534,8 @@ WrapperAnswer::AnswerGetPropertyNames(const ObjectId &objId, const uint32_t &fla
|
||||
|
||||
JSAutoCompartment comp(cx, obj);
|
||||
|
||||
LOG("%s.getPropertyNames()", ReceiverObj(objId));
|
||||
|
||||
AutoIdVector props(cx);
|
||||
if (!js::GetPropertyNames(cx, obj, flags, &props))
|
||||
return fail(cx, rs);
|
||||
@ -537,6 +566,8 @@ WrapperAnswer::AnswerInstanceOf(const ObjectId &objId, const JSIID &iid, ReturnS
|
||||
|
||||
JSAutoCompartment comp(cx, obj);
|
||||
|
||||
LOG("%s.instanceOf()", ReceiverObj(objId));
|
||||
|
||||
nsID nsiid;
|
||||
ConvertID(iid, &nsiid);
|
||||
|
||||
@ -563,6 +594,8 @@ WrapperAnswer::AnswerDOMInstanceOf(const ObjectId &objId, const int &prototypeID
|
||||
|
||||
JSAutoCompartment comp(cx, obj);
|
||||
|
||||
LOG("%s.domInstanceOf()", ReceiverObj(objId));
|
||||
|
||||
bool tmp;
|
||||
if (!mozilla::dom::InterfaceHasInstance(cx, prototypeID, depth, obj, &tmp))
|
||||
return fail(cx, rs);
|
||||
|
@ -6,6 +6,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "WrapperOwner.h"
|
||||
#include "JavaScriptLogging.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "jsfriendapi.h"
|
||||
@ -111,6 +112,8 @@ WrapperOwner::preventExtensions(JSContext *cx, HandleObject proxy)
|
||||
if (!CallPreventExtensions(objId, &status))
|
||||
return ipcfail(cx);
|
||||
|
||||
LOG_STACK();
|
||||
|
||||
return ok(cx, status);
|
||||
}
|
||||
|
||||
@ -135,6 +138,9 @@ WrapperOwner::getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId
|
||||
PPropertyDescriptor result;
|
||||
if (!CallGetPropertyDescriptor(objId, idstr, &status, &result))
|
||||
return ipcfail(cx);
|
||||
|
||||
LOG_STACK();
|
||||
|
||||
if (!ok(cx, status))
|
||||
return false;
|
||||
|
||||
@ -162,6 +168,9 @@ WrapperOwner::getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, Handle
|
||||
PPropertyDescriptor result;
|
||||
if (!CallGetOwnPropertyDescriptor(objId, idstr, &status, &result))
|
||||
return ipcfail(cx);
|
||||
|
||||
LOG_STACK();
|
||||
|
||||
if (!ok(cx, status))
|
||||
return false;
|
||||
|
||||
@ -193,6 +202,8 @@ WrapperOwner::defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
if (!CallDefineProperty(objId, idstr, descriptor, &status))
|
||||
return ipcfail(cx);
|
||||
|
||||
LOG_STACK();
|
||||
|
||||
return ok(cx, status);
|
||||
}
|
||||
|
||||
@ -227,6 +238,8 @@ WrapperOwner::delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp)
|
||||
if (!CallDelete(objId, idstr, &status, bp))
|
||||
return ipcfail(cx);
|
||||
|
||||
LOG_STACK();
|
||||
|
||||
return ok(cx, status);
|
||||
}
|
||||
|
||||
@ -261,6 +274,8 @@ WrapperOwner::has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp)
|
||||
if (!CallHas(objId, idstr, &status, bp))
|
||||
return ipcfail(cx);
|
||||
|
||||
LOG_STACK();
|
||||
|
||||
return ok(cx, status);
|
||||
}
|
||||
|
||||
@ -283,6 +298,8 @@ WrapperOwner::hasOwn(JSContext *cx, HandleObject proxy, HandleId id, bool *bp)
|
||||
if (!CallHasOwn(objId, idstr, &status, bp))
|
||||
return ipcfail(cx);
|
||||
|
||||
LOG_STACK();
|
||||
|
||||
return !!ok(cx, status);
|
||||
}
|
||||
|
||||
@ -309,6 +326,8 @@ WrapperOwner::get(JSContext *cx, HandleObject proxy, HandleObject receiver,
|
||||
if (!CallGet(objId, receiverId, idstr, &status, &val))
|
||||
return ipcfail(cx);
|
||||
|
||||
LOG_STACK();
|
||||
|
||||
if (!ok(cx, status))
|
||||
return false;
|
||||
|
||||
@ -342,6 +361,8 @@ WrapperOwner::set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiv
|
||||
if (!CallSet(objId, receiverId, idstr, strict, val, &status, &result))
|
||||
return ipcfail(cx);
|
||||
|
||||
LOG_STACK();
|
||||
|
||||
if (!ok(cx, status))
|
||||
return false;
|
||||
|
||||
@ -375,6 +396,8 @@ WrapperOwner::isExtensible(JSContext *cx, HandleObject proxy, bool *extensible)
|
||||
if (!CallIsExtensible(objId, &status, extensible))
|
||||
return ipcfail(cx);
|
||||
|
||||
LOG_STACK();
|
||||
|
||||
return ok(cx, status);
|
||||
}
|
||||
|
||||
@ -424,6 +447,9 @@ WrapperOwner::call(JSContext *cx, HandleObject proxy, const CallArgs &args)
|
||||
InfallibleTArray<JSParam> outparams;
|
||||
if (!CallCall(objId, vals, &status, &result, &outparams))
|
||||
return ipcfail(cx);
|
||||
|
||||
LOG_STACK();
|
||||
|
||||
if (!ok(cx, status))
|
||||
return false;
|
||||
|
||||
@ -470,6 +496,8 @@ WrapperOwner::objectClassIs(JSContext *cx, HandleObject proxy, js::ESClassValue
|
||||
if (!CallObjectClassIs(objId, classValue, &result))
|
||||
return false;
|
||||
|
||||
LOG_STACK();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -491,6 +519,8 @@ WrapperOwner::className(JSContext *cx, HandleObject proxy)
|
||||
if (!CallClassName(objId, &name))
|
||||
return "<error>";
|
||||
|
||||
LOG_STACK();
|
||||
|
||||
return ToNewCString(name);
|
||||
}
|
||||
|
||||
@ -529,6 +559,9 @@ WrapperOwner::getPropertyNames(JSContext *cx, HandleObject proxy, uint32_t flags
|
||||
InfallibleTArray<nsString> names;
|
||||
if (!CallGetPropertyNames(objId, flags, &status, &names))
|
||||
return ipcfail(cx);
|
||||
|
||||
LOG_STACK();
|
||||
|
||||
if (!ok(cx, status))
|
||||
return false;
|
||||
|
||||
@ -597,6 +630,8 @@ WrapperOwner::domInstanceOf(JSContext *cx, JSObject *obj, int prototypeID, int d
|
||||
if (!CallDOMInstanceOf(objId, prototypeID, depth, &status, bp))
|
||||
return ipcfail(cx);
|
||||
|
||||
LOG_STACK();
|
||||
|
||||
return ok(cx, status);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user