Bug 876555: Avoid including xpcprivate.h in most generated dom binding code. r=bz

This commit is contained in:
Kyle Huey 2013-05-30 11:15:31 +08:00
parent 937fc753aa
commit 0d78767303
18 changed files with 222 additions and 110 deletions

View File

@ -12,13 +12,11 @@
#include "nsCOMPtr.h"
#include "nsDOMString.h"
#include "nsWrapperCache.h"
#include "mozilla/dom/Element.h"
namespace mozilla {
class ErrorResult;
namespace dom {
class Element;
} // namespace dom
} // namespace mozilla
class nsAttrValue;

View File

@ -7,13 +7,11 @@
#define MEDIASTREAMTRACK_H_
#include "nsDOMEventTargetHelper.h"
#include "DOMMediaStream.h"
#include "nsID.h"
#include "StreamBuffer.h"
namespace mozilla {
class DOMMediaStream;
namespace dom {
class AudioStreamTrack;

View File

@ -11,10 +11,9 @@
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/BindingUtils.h"
#include "nsCycleCollectionParticipant.h"
#include "nsPIDOMWindow.h"
#include "nsWrapperCache.h"
class nsPIDOMWindow;
namespace mozilla {
namespace dom {

View File

@ -698,7 +698,7 @@ QueryInterface(JSContext* cx, unsigned argc, JS::Value* vp)
}
nsIJSID* iid;
xpc_qsSelfRef iidRef;
SelfRef iidRef;
if (NS_FAILED(xpc_qsUnwrapArg<nsIJSID>(cx, argv[0], &iid, &iidRef.ptr,
&argv[0]))) {
return Throw<true>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
@ -1731,6 +1731,17 @@ ReportLenientThisUnwrappingFailure(JSContext* cx, JS::Handle<JSObject*> obj)
return true;
}
bool
RegisterForDeferredFinalization(DeferredFinalizeStartFunction start,
DeferredFinalizeFunction run)
{
XPCJSRuntime *rt = nsXPConnect::GetRuntimeInstance();
NS_ENSURE_TRUE(rt, false);
rt->RegisterDeferredFinalize(start, run);
return true;
}
// Date implementation methods
Date::Date() :
mMsecSinceEpoch(UnspecifiedNaN())

View File

@ -27,9 +27,36 @@
class nsPIDOMWindow;
extern nsresult
xpc_qsUnwrapArgImpl(JSContext* cx, jsval v, const nsIID& iid, void** ppArg,
nsISupports** ppArgRef, jsval* vp);
namespace mozilla {
namespace dom {
struct SelfRef
{
SelfRef() : ptr(nullptr) {}
explicit SelfRef(nsISupports *p) : ptr(p) {}
~SelfRef() { NS_IF_RELEASE(ptr); }
nsISupports* ptr;
};
/** Convert a jsval to an XPCOM pointer. */
template <class Interface, class StrongRefType>
inline nsresult
UnwrapArg(JSContext* cx, jsval v, Interface** ppArg,
StrongRefType** ppArgRef, jsval* vp)
{
nsISupports* argRef = *ppArgRef;
nsresult rv = xpc_qsUnwrapArgImpl(cx, v, NS_GET_TEMPLATE_IID(Interface),
reinterpret_cast<void**>(ppArg), &argRef,
vp);
*ppArgRef = static_cast<StrongRefType*>(argRef);
return rv;
}
bool
ThrowErrorMessage(JSContext* aCx, const ErrNum aErrorNumber, ...);
@ -2001,6 +2028,10 @@ bool
GetWindowForJSImplementedObject(JSContext* cx, JS::Handle<JSObject*> obj,
nsPIDOMWindow** window);
bool
RegisterForDeferredFinalization(DeferredFinalizeStartFunction start,
DeferredFinalizeFunction run);
} // namespace dom
} // namespace mozilla

View File

@ -403,6 +403,8 @@ DOMInterfaces = {
'HTMLCollection': {
'nativeType': 'nsIHTMLCollection',
# nsContentList.h pulls in nsIHTMLCollection.h
'headerFile': 'nsContentList.h',
'resultNotAddRefed': [ 'item' ]
},

View File

@ -1006,23 +1006,17 @@ def finalizeHook(descriptor, hookName, context):
if descriptor.workers:
finalize += "self->Release();"
elif descriptor.nativeOwnership == 'nsisupports':
finalize += """XPCJSRuntime *rt = nsXPConnect::GetRuntimeInstance();
if (rt) {
rt->DeferredRelease(reinterpret_cast<nsISupports*>(self));
} else {
NS_RELEASE(self);
}"""
finalize += "xpc::DeferredRelease(reinterpret_cast<nsISupports*>(self));"
else:
smartPtr = DeferredFinalizeSmartPtr(descriptor)
finalize += """static bool registered = false;
if (!registered) {
XPCJSRuntime *rt = nsXPConnect::GetRuntimeInstance();
if (!rt) {
if (!RegisterForDeferredFinalization(GetDeferredFinalizePointers,
DeferredFinalize)) {
%(smartPtr)s dying;
Take(dying, self);
return;
}
rt->RegisterDeferredFinalize(GetDeferredFinalizePointers, DeferredFinalize);
registered = true;
}
if (!sDeferredFinalizePointers) {
@ -2312,9 +2306,9 @@ class CastableObjectUnwrapper():
# not.
self.substitution["codeOnFailure"] = CGIndenter(CGGeneric(string.Template(
"${type} *objPtr;\n"
"xpc_qsSelfRef objRef;\n"
"SelfRef objRef;\n"
"JS::Rooted<JS::Value> val(cx, JS::ObjectValue(*${source}));\n"
"nsresult rv = xpc_qsUnwrapArg<${type}>(cx, val, &objPtr, &objRef.ptr, val.address());\n"
"nsresult rv = UnwrapArg<${type}>(cx, val, &objPtr, &objRef.ptr, val.address());\n"
"if (NS_FAILED(rv)) {\n"
"${codeOnFailure}\n"
"}\n"
@ -3115,7 +3109,7 @@ for (uint32_t i = 0; i < length; ++i) {
templateBody += (
"JS::Rooted<JS::Value> tmpVal(cx, ${val});\n" +
typePtr + " tmp;\n"
"if (NS_FAILED(xpc_qsUnwrapArg<" + typeName + ">(cx, ${val}, &tmp, static_cast<" + typeName + "**>(getter_AddRefs(${holderName})), tmpVal.address()))) {\n")
"if (NS_FAILED(UnwrapArg<" + typeName + ">(cx, ${val}, &tmp, static_cast<" + typeName + "**>(getter_AddRefs(${holderName})), tmpVal.address()))) {\n")
templateBody += CGIndenter(onFailureBadType(failureCode,
descriptor.interface.identifier.name)).define()
templateBody += ("}\n"
@ -8213,6 +8207,8 @@ class CGBindingRoot(CGThing):
def descriptorHasChromeOnlyMembers(desc):
return any(isChromeOnly(a) for a in desc.interface.members)
hasChromeOnlyMembers = any(descriptorHasChromeOnlyMembers(d) for d in descriptors)
# XXXkhuey ugly hack but this is going away soon.
isEventTarget = webIDLFile.endswith("EventTarget.webidl")
hasWorkerStuff = len(config.getDescriptors(webIDLFile=webIDLFile,
workers=True)) != 0
mainDictionaries = config.getDictionaries(webIDLFile=webIDLFile,
@ -8317,10 +8313,7 @@ class CGBindingRoot(CGThing):
['mozilla/dom/BindingUtils.h',
'mozilla/dom/Nullable.h',
'PrimitiveConversions.h',
'XPCQuickStubs.h',
'XPCWrapper.h',
'WrapperFactory.h',
'nsDOMQS.h',
# Have to include nsDOMQS.h to get fast arg unwrapping
# for old-binding things with castability.
'nsDOMQS.h'
@ -8330,7 +8323,8 @@ class CGBindingRoot(CGThing):
+ (['mozilla/dom/NonRefcountedDOMObject.h'] if hasOwnedDescriptors else [])
+ (['nsContentUtils.h'] if requiresContentUtils else [])
+ (['nsCxPusher.h'] if requiresContentUtils else [])
+ (['AccessCheck.h'] if hasChromeOnlyMembers else []),
+ (['AccessCheck.h'] if hasChromeOnlyMembers else [])
+ (['xpcprivate.h'] if isEventTarget else []),
curr,
config,
jsImplemented)

View File

@ -20,6 +20,10 @@
#include <windows.h>
#endif
#ifdef GetClassName
#undef GetClassName
#endif
#include "GLDefs.h"
#include "GLLibraryLoader.h"
#include "gfxASurface.h"

View File

@ -6,6 +6,9 @@
#define BASE_OBJECT_WATCHER_H_
#include <windows.h>
#ifdef GetClassName
#undef GetClassName
#endif
#include "base/message_loop.h"

View File

@ -629,9 +629,9 @@ DoDeferredRelease(nsTArray<T> &array)
}
}
struct DeferredFinalizeFunction
struct DeferredFinalizeFunctionHolder
{
XPCJSRuntime::DeferredFinalizeFunction run;
DeferredFinalizeFunction run;
void *data;
};
@ -639,7 +639,7 @@ class XPCIncrementalReleaseRunnable : public nsRunnable
{
XPCJSRuntime *runtime;
nsTArray<nsISupports *> items;
nsAutoTArray<DeferredFinalizeFunction, 16> deferredFinalizeFunctions;
nsAutoTArray<DeferredFinalizeFunctionHolder, 16> deferredFinalizeFunctions;
uint32_t finalizeFunctionToRun;
static const PRTime SliceMillis = 10; /* ms */
@ -680,7 +680,7 @@ XPCIncrementalReleaseRunnable::XPCIncrementalReleaseRunnable(XPCJSRuntime *rt,
{
nsLayoutStatics::AddRef();
this->items.SwapElements(items);
DeferredFinalizeFunction *function = deferredFinalizeFunctions.AppendElement();
DeferredFinalizeFunctionHolder *function = deferredFinalizeFunctions.AppendElement();
function->run = ReleaseSliceNow;
function->data = &this->items;
for (uint32_t i = 0; i < rt->mDeferredFinalizeFunctions.Length(); ++i) {
@ -712,7 +712,7 @@ XPCIncrementalReleaseRunnable::ReleaseNow(bool limited)
TimeStamp started = TimeStamp::Now();
bool timeout = false;
do {
const DeferredFinalizeFunction &function =
const DeferredFinalizeFunctionHolder &function =
deferredFinalizeFunctions[finalizeFunctionToRun];
if (limited) {
bool done = false;

View File

@ -85,6 +85,16 @@ LookupInterfaceOrAncestor(uint32_t tableSize, const xpc_qsHashEntry *table,
return entry;
}
static MOZ_ALWAYS_INLINE bool
HasBitInInterfacesBitmap(JSObject *obj, uint32_t interfaceBit)
{
NS_ASSERTION(IS_WRAPPER_CLASS(js::GetObjectClass(obj)), "Not a wrapper?");
XPCWrappedNativeJSClass *clasp =
(XPCWrappedNativeJSClass*)js::GetObjectClass(obj);
return (clasp->interfacesBitmap & (1 << interfaceBit)) != 0;
}
static void
PointerFinalize(JSFreeOp *fop, JSObject *obj)
{
@ -650,6 +660,72 @@ castNative(JSContext *cx,
return NS_ERROR_XPC_BAD_OP_ON_WN_PROTO;
}
nsISupports*
castNativeFromWrapper(JSContext *cx,
JSObject *obj,
uint32_t interfaceBit,
uint32_t protoID,
int32_t protoDepth,
nsISupports **pRef,
jsval *pVal,
XPCLazyCallContext *lccx,
nsresult *rv)
{
XPCWrappedNative *wrapper;
XPCWrappedNativeTearOff *tearoff;
JSObject *cur;
if (IS_WRAPPER_CLASS(js::GetObjectClass(obj))) {
cur = obj;
wrapper = IS_WN_WRAPPER_OBJECT(cur) ?
(XPCWrappedNative*)xpc_GetJSPrivate(obj) :
nullptr;
tearoff = nullptr;
} else {
*rv = getWrapper(cx, obj, &wrapper, &cur, &tearoff);
if (NS_FAILED(*rv))
return nullptr;
}
nsISupports *native;
if (wrapper) {
native = wrapper->GetIdentityObject();
cur = wrapper->GetFlatJSObject();
if (!native || !HasBitInInterfacesBitmap(cur, interfaceBit)) {
native = nullptr;
} else if (lccx) {
lccx->SetWrapper(wrapper, tearoff);
}
} else if (cur && IS_SLIM_WRAPPER(cur)) {
native = static_cast<nsISupports*>(xpc_GetJSPrivate(cur));
if (!native || !HasBitInInterfacesBitmap(cur, interfaceBit)) {
native = nullptr;
} else if (lccx) {
lccx->SetWrapper(cur);
}
} else if (cur && protoDepth >= 0) {
const mozilla::dom::DOMClass* domClass =
mozilla::dom::GetDOMClass(cur);
native = mozilla::dom::UnwrapDOMObject<nsISupports>(cur);
if (native &&
(uint32_t)domClass->mInterfaceChain[protoDepth] != protoID) {
native = nullptr;
}
} else {
native = nullptr;
}
if (native) {
*pRef = nullptr;
*pVal = OBJECT_TO_JSVAL(cur);
*rv = NS_OK;
} else {
*rv = NS_ERROR_XPC_BAD_CONVERT_JS;
}
return native;
}
JSBool
xpc_qsUnwrapThisFromCcxImpl(XPCCallContext &ccx,
const nsIID &iid,

View File

@ -8,13 +8,15 @@
#define xpcquickstubs_h___
#include "xpcpublic.h"
#include "xpcprivate.h"
#include "XPCForwards.h"
#include "qsObjectHelper.h"
#include "mozilla/dom/BindingUtils.h"
/* XPCQuickStubs.h - Support functions used only by quick stubs. */
class XPCCallContext;
class XPCLazyCallContext;
class XPCWrappedNativeJSClass;
#define XPC_QS_NULL_INDEX ((uint16_t) -1)
@ -416,17 +418,7 @@ xpc_qsUnwrapThis(JSContext *cx,
return true;
}
MOZ_ALWAYS_INLINE bool
HasBitInInterfacesBitmap(JSObject *obj, uint32_t interfaceBit)
{
NS_ASSERTION(IS_WRAPPER_CLASS(js::GetObjectClass(obj)), "Not a wrapper?");
XPCWrappedNativeJSClass *clasp =
(XPCWrappedNativeJSClass*)js::GetObjectClass(obj);
return (clasp->interfacesBitmap & (1 << interfaceBit)) != 0;
}
MOZ_ALWAYS_INLINE nsISupports*
nsISupports*
castNativeFromWrapper(JSContext *cx,
JSObject *obj,
uint32_t interfaceBit,
@ -435,62 +427,7 @@ castNativeFromWrapper(JSContext *cx,
nsISupports **pRef,
jsval *pVal,
XPCLazyCallContext *lccx,
nsresult *rv)
{
XPCWrappedNative *wrapper;
XPCWrappedNativeTearOff *tearoff;
JSObject *cur;
if (IS_WRAPPER_CLASS(js::GetObjectClass(obj))) {
cur = obj;
wrapper = IS_WN_WRAPPER_OBJECT(cur) ?
(XPCWrappedNative*)xpc_GetJSPrivate(obj) :
nullptr;
tearoff = nullptr;
} else {
*rv = getWrapper(cx, obj, &wrapper, &cur, &tearoff);
if (NS_FAILED(*rv))
return nullptr;
}
nsISupports *native;
if (wrapper) {
native = wrapper->GetIdentityObject();
cur = wrapper->GetFlatJSObject();
if (!native || !HasBitInInterfacesBitmap(cur, interfaceBit)) {
native = nullptr;
} else if (lccx) {
lccx->SetWrapper(wrapper, tearoff);
}
} else if (cur && IS_SLIM_WRAPPER(cur)) {
native = static_cast<nsISupports*>(xpc_GetJSPrivate(cur));
if (!native || !HasBitInInterfacesBitmap(cur, interfaceBit)) {
native = nullptr;
} else if (lccx) {
lccx->SetWrapper(cur);
}
} else if (cur && protoDepth >= 0) {
const mozilla::dom::DOMClass* domClass =
mozilla::dom::GetDOMClass(cur);
native = mozilla::dom::UnwrapDOMObject<nsISupports>(cur);
if (native &&
(uint32_t)domClass->mInterfaceChain[protoDepth] != protoID) {
native = nullptr;
}
} else {
native = nullptr;
}
if (native) {
*pRef = nullptr;
*pVal = OBJECT_TO_JSVAL(cur);
*rv = NS_OK;
} else {
*rv = NS_ERROR_XPC_BAD_CONVERT_JS;
}
return native;
}
nsresult *rv);
JSBool
xpc_qsUnwrapThisFromCcxImpl(XPCCallContext &ccx,

View File

@ -4,6 +4,7 @@
* 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/. */
#include "xpcprivate.h"
#include "XPCWrapper.h"
#include "AccessCheck.h"
#include "WrapperFactory.h"

View File

@ -10,6 +10,8 @@
#include "xpcprivate.h"
#include "xpcpublic.h"
class nsIScriptSecurityManager;
namespace XPCNativeWrapper {
// Given an XPCWrappedNative pointer and the name of the function on

View File

@ -19,6 +19,7 @@ dictionaries = [
# include file names
special_includes = [
'nsContentUtils.h',
'xpcprivate.h',
'XPCQuickStubs.h',
'nsIDOMApplicationRegistry.h',
'nsIDOMFile.h'

View File

@ -26,6 +26,7 @@
#include "mozilla/dom/DocumentBinding.h"
#include "mozilla/dom/SVGElementBinding.h"
#include "mozilla/dom/HTMLDocumentBinding.h"
#include "XPCQuickStubs.h"
template<class T>
struct ProtoIDAndDepth
@ -101,6 +102,7 @@ xpc_qsUnwrapArg<_interface>(JSContext *cx, \
*ppArg = static_cast<_interface*>(static_cast<_base*>(native)); \
return rv; \
} \
\
template <> \
inline nsresult \
xpc_qsUnwrapArg<_interface>(JSContext *cx, \
@ -113,7 +115,35 @@ xpc_qsUnwrapArg<_interface>(JSContext *cx, \
nsresult rv = xpc_qsUnwrapArg<_interface>(cx, v, ppArg, &argRef, vp); \
*ppArgRef = static_cast<_interface*>(static_cast<_base*>(argRef)); \
return rv; \
}
} \
\
namespace mozilla { \
namespace dom { \
\
template <> \
MOZ_ALWAYS_INLINE nsresult \
UnwrapArg<_interface>(JSContext *cx, \
jsval v, \
_interface **ppArg, \
nsISupports **ppArgRef, \
jsval *vp) \
{ \
return xpc_qsUnwrapArg<_interface>(cx, v, ppArg, ppArgRef, vp); \
} \
\
template <> \
inline nsresult \
UnwrapArg<_interface>(JSContext *cx, \
jsval v, \
_interface **ppArg, \
_interface **ppArgRef, \
jsval *vp) \
{ \
return xpc_qsUnwrapArg<_interface>(cx, v, ppArg, ppArgRef, vp); \
} \
\
} /* namespace dom */ \
} /* namespace mozilla */
#undef DOMCI_CASTABLE_INTERFACE
@ -174,7 +204,32 @@ xpc_qsUnwrapArg<_clazz>(JSContext *cx, jsval v, _clazz **ppArg, \
nsresult rv = xpc_qsUnwrapArg<_clazz>(cx, v, ppArg, &argRef, vp); \
*ppArgRef = static_cast<_clazz*>(static_cast<nsIContent*>(argRef)); \
return rv; \
}
} \
\
namespace mozilla { \
namespace dom { \
\
template <> \
inline nsresult \
UnwrapArg<_clazz>(JSContext *cx, \
jsval v, \
_clazz **ppArg, \
nsISupports **ppArgRef, \
jsval *vp) \
{ \
return xpc_qsUnwrapArg<_clazz>(cx, v, ppArg, ppArgRef, vp); \
} \
\
template <> \
inline nsresult \
UnwrapArg<_clazz>(JSContext *cx, jsval v, _clazz **ppArg, \
_clazz **ppArgRef, jsval *vp) \
{ \
return xpc_qsUnwrapArg<_clazz>(cx, v, ppArg, ppArgRef, vp); \
} \
\
} /* namespace dom */ \
} /* namespace mozilla */
DEFINE_UNWRAP_CAST_HTML(canvas, mozilla::dom::HTMLCanvasElement)
DEFINE_UNWRAP_CAST_HTML(form, nsHTMLFormElement)

View File

@ -705,16 +705,6 @@ public:
* destroy during the GC.
*/
// Called once before the deferred finalization starts. Should hand off the
// buffer with things to finalize in the return value.
typedef void* (*DeferredFinalizeStartFunction)();
// Called to finalize a number of objects. Slice is the number of objects
// to finalize, or if it's UINT32_MAX, all objects should be finalized.
// data is the pointer returned by DeferredFinalizeStartFunction.
// Return value indicates whether it finalized all objects in the buffer.
typedef bool (*DeferredFinalizeFunction)(uint32_t slice, void* data);
private:
struct DeferredFinalizeFunctions
{

View File

@ -490,4 +490,14 @@ Register(nsScriptNameSpaceManager* aNameSpaceManager);
} // namespace dom
} // namespace mozilla
// Called once before the deferred finalization starts. Should hand off the
// buffer with things to finalize in the return value.
typedef void* (*DeferredFinalizeStartFunction)();
// Called to finalize a number of objects. Slice is the number of objects
// to finalize, or if it's UINT32_MAX, all objects should be finalized.
// data is the pointer returned by DeferredFinalizeStartFunction.
// Return value indicates whether it finalized all objects in the buffer.
typedef bool (*DeferredFinalizeFunction)(uint32_t slice, void* data);
#endif