js/xpconnect/src/XPCWrappedNativeProto.cpp

Thu, 15 Jan 2015 15:55:04 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:55:04 +0100
branch
TOR_BUG_9701
changeset 9
a63d609f5ebe
permissions
-rw-r--r--

Back out 97036ab72558 which inappropriately compared turds to third parties.

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     2 /* vim: set ts=8 sts=4 et sw=4 tw=99: */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 /* Shared proto object for XPCWrappedNative. */
     9 #include "xpcprivate.h"
    10 #include "nsCxPusher.h"
    11 #include "pratom.h"
    13 using namespace mozilla;
    15 #ifdef DEBUG
    16 int32_t XPCWrappedNativeProto::gDEBUG_LiveProtoCount = 0;
    17 #endif
    19 XPCWrappedNativeProto::XPCWrappedNativeProto(XPCWrappedNativeScope* Scope,
    20                                              nsIClassInfo* ClassInfo,
    21                                              uint32_t ClassInfoFlags,
    22                                              XPCNativeSet* Set)
    23     : mScope(Scope),
    24       mJSProtoObject(nullptr),
    25       mClassInfo(ClassInfo),
    26       mClassInfoFlags(ClassInfoFlags),
    27       mSet(Set),
    28       mScriptableInfo(nullptr)
    29 {
    30     // This native object lives as long as its associated JSObject - killed
    31     // by finalization of the JSObject (or explicitly if Init fails).
    33     MOZ_COUNT_CTOR(XPCWrappedNativeProto);
    34     MOZ_ASSERT(mScope);
    36 #ifdef DEBUG
    37     PR_ATOMIC_INCREMENT(&gDEBUG_LiveProtoCount);
    38 #endif
    39 }
    41 XPCWrappedNativeProto::~XPCWrappedNativeProto()
    42 {
    43     MOZ_ASSERT(!mJSProtoObject, "JSProtoObject still alive");
    45     MOZ_COUNT_DTOR(XPCWrappedNativeProto);
    47 #ifdef DEBUG
    48     PR_ATOMIC_DECREMENT(&gDEBUG_LiveProtoCount);
    49 #endif
    51     // Note that our weak ref to mScope is not to be trusted at this point.
    53     XPCNativeSet::ClearCacheEntryForClassInfo(mClassInfo);
    55     delete mScriptableInfo;
    56 }
    58 bool
    59 XPCWrappedNativeProto::Init(const XPCNativeScriptableCreateInfo* scriptableCreateInfo,
    60                             bool callPostCreatePrototype)
    61 {
    62     AutoJSContext cx;
    63     nsIXPCScriptable *callback = scriptableCreateInfo ?
    64                                  scriptableCreateInfo->GetCallback() :
    65                                  nullptr;
    66     if (callback) {
    67         mScriptableInfo =
    68             XPCNativeScriptableInfo::Construct(scriptableCreateInfo);
    69         if (!mScriptableInfo)
    70             return false;
    71     }
    73     const js::Class* jsclazz;
    75     if (mScriptableInfo) {
    76         const XPCNativeScriptableFlags& flags(mScriptableInfo->GetFlags());
    78         if (flags.AllowPropModsToPrototype()) {
    79             jsclazz = flags.WantCall() ?
    80                 &XPC_WN_ModsAllowed_WithCall_Proto_JSClass :
    81                 &XPC_WN_ModsAllowed_NoCall_Proto_JSClass;
    82         } else {
    83             jsclazz = flags.WantCall() ?
    84                 &XPC_WN_NoMods_WithCall_Proto_JSClass :
    85                 &XPC_WN_NoMods_NoCall_Proto_JSClass;
    86         }
    87     } else {
    88         jsclazz = &XPC_WN_NoMods_NoCall_Proto_JSClass;
    89     }
    91     JS::RootedObject parent(cx, mScope->GetGlobalJSObject());
    92     JS::RootedObject proto(cx, JS_GetObjectPrototype(cx, parent));
    93     mJSProtoObject = JS_NewObjectWithUniqueType(cx, js::Jsvalify(jsclazz),
    94                                                 proto, parent);
    96     bool success = !!mJSProtoObject;
    97     if (success) {
    98         JS_SetPrivate(mJSProtoObject, this);
    99         if (callPostCreatePrototype)
   100             success = CallPostCreatePrototype();
   101     }
   103     return success;
   104 }
   106 bool
   107 XPCWrappedNativeProto::CallPostCreatePrototype()
   108 {
   109     AutoJSContext cx;
   111     // Nothing to do if we don't have a scriptable callback.
   112     nsIXPCScriptable *callback = mScriptableInfo ? mScriptableInfo->GetCallback()
   113                                                  : nullptr;
   114     if (!callback)
   115         return true;
   117     // Call the helper. This can handle being called if it's not implemented,
   118     // so we don't have to check any sort of "want" here. See xpc_map_end.h.
   119     nsresult rv = callback->PostCreatePrototype(cx, mJSProtoObject);
   120     if (NS_FAILED(rv)) {
   121         JS_SetPrivate(mJSProtoObject, nullptr);
   122         mJSProtoObject = nullptr;
   123         XPCThrower::Throw(rv, cx);
   124         return false;
   125     }
   127     return true;
   128 }
   130 void
   131 XPCWrappedNativeProto::JSProtoObjectFinalized(js::FreeOp *fop, JSObject *obj)
   132 {
   133     MOZ_ASSERT(obj == mJSProtoObject, "huh?");
   135     // Only remove this proto from the map if it is the one in the map.
   136     ClassInfo2WrappedNativeProtoMap* map = GetScope()->GetWrappedNativeProtoMap();
   137     if (map->Find(mClassInfo) == this)
   138         map->Remove(mClassInfo);
   140     GetRuntime()->GetDetachedWrappedNativeProtoMap()->Remove(this);
   141     GetRuntime()->GetDyingWrappedNativeProtoMap()->Add(this);
   143     mJSProtoObject.finalize(js::CastToJSFreeOp(fop)->runtime());
   144 }
   146 void
   147 XPCWrappedNativeProto::SystemIsBeingShutDown()
   148 {
   149     // Note that the instance might receive this call multiple times
   150     // as we walk to here from various places.
   152     if (mJSProtoObject) {
   153         // short circuit future finalization
   154         JS_SetPrivate(mJSProtoObject, nullptr);
   155         mJSProtoObject = nullptr;
   156     }
   157 }
   159 // static
   160 XPCWrappedNativeProto*
   161 XPCWrappedNativeProto::GetNewOrUsed(XPCWrappedNativeScope* scope,
   162                                     nsIClassInfo* classInfo,
   163                                     const XPCNativeScriptableCreateInfo* scriptableCreateInfo,
   164                                     bool callPostCreatePrototype)
   165 {
   166     AutoJSContext cx;
   167     MOZ_ASSERT(scope, "bad param");
   168     MOZ_ASSERT(classInfo, "bad param");
   170     AutoMarkingWrappedNativeProtoPtr proto(cx);
   171     ClassInfo2WrappedNativeProtoMap* map = nullptr;
   173     uint32_t ciFlags;
   174     if (NS_FAILED(classInfo->GetFlags(&ciFlags)))
   175         ciFlags = 0;
   177     map = scope->GetWrappedNativeProtoMap();
   178     proto = map->Find(classInfo);
   179     if (proto)
   180         return proto;
   182     AutoMarkingNativeSetPtr set(cx);
   183     set = XPCNativeSet::GetNewOrUsed(classInfo);
   184     if (!set)
   185         return nullptr;
   187     proto = new XPCWrappedNativeProto(scope, classInfo, ciFlags, set);
   189     if (!proto || !proto->Init(scriptableCreateInfo, callPostCreatePrototype)) {
   190         delete proto.get();
   191         return nullptr;
   192     }
   194     map->Add(classInfo, proto);
   196     return proto;
   197 }
   199 void
   200 XPCWrappedNativeProto::DebugDump(int16_t depth)
   201 {
   202 #ifdef DEBUG
   203     depth-- ;
   204     XPC_LOG_ALWAYS(("XPCWrappedNativeProto @ %x", this));
   205     XPC_LOG_INDENT();
   206         XPC_LOG_ALWAYS(("gDEBUG_LiveProtoCount is %d", gDEBUG_LiveProtoCount));
   207         XPC_LOG_ALWAYS(("mScope @ %x", mScope));
   208         XPC_LOG_ALWAYS(("mJSProtoObject @ %x", mJSProtoObject.get()));
   209         XPC_LOG_ALWAYS(("mSet @ %x", mSet));
   210         XPC_LOG_ALWAYS(("mScriptableInfo @ %x", mScriptableInfo));
   211         if (depth && mScriptableInfo) {
   212             XPC_LOG_INDENT();
   213             XPC_LOG_ALWAYS(("mScriptable @ %x", mScriptableInfo->GetCallback()));
   214             XPC_LOG_ALWAYS(("mFlags of %x", (uint32_t)mScriptableInfo->GetFlags()));
   215             XPC_LOG_ALWAYS(("mJSClass @ %x", mScriptableInfo->GetJSClass()));
   216             XPC_LOG_OUTDENT();
   217         }
   218     XPC_LOG_OUTDENT();
   219 #endif
   220 }

mercurial