LCOV - code coverage report
Current view: top level - js/xpconnect/src - XPCWrappedNativeProto.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 45 90 50.0 %
Date: 2017-07-14 16:53:18 Functions: 4 9 44.4 %
Legend: Lines: hit not hit

          Line data    Source code
       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/. */
       6             : 
       7             : /* Shared proto object for XPCWrappedNative. */
       8             : 
       9             : #include "xpcprivate.h"
      10             : #include "pratom.h"
      11             : 
      12             : using namespace mozilla;
      13             : 
      14             : #ifdef DEBUG
      15             : int32_t XPCWrappedNativeProto::gDEBUG_LiveProtoCount = 0;
      16             : #endif
      17             : 
      18        1824 : XPCWrappedNativeProto::XPCWrappedNativeProto(XPCWrappedNativeScope* Scope,
      19             :                                              nsIClassInfo* ClassInfo,
      20        1824 :                                              already_AddRefed<XPCNativeSet>&& Set)
      21             :     : mScope(Scope),
      22             :       mJSProtoObject(nullptr),
      23             :       mClassInfo(ClassInfo),
      24        1824 :       mSet(Set)
      25             : {
      26             :     // This native object lives as long as its associated JSObject - killed
      27             :     // by finalization of the JSObject (or explicitly if Init fails).
      28             : 
      29        1824 :     MOZ_COUNT_CTOR(XPCWrappedNativeProto);
      30        1824 :     MOZ_ASSERT(mScope);
      31             : 
      32             : #ifdef DEBUG
      33        1824 :     gDEBUG_LiveProtoCount++;
      34             : #endif
      35        1824 : }
      36             : 
      37           0 : XPCWrappedNativeProto::~XPCWrappedNativeProto()
      38             : {
      39           0 :     MOZ_ASSERT(!mJSProtoObject, "JSProtoObject still alive");
      40             : 
      41           0 :     MOZ_COUNT_DTOR(XPCWrappedNativeProto);
      42             : 
      43             : #ifdef DEBUG
      44           0 :     gDEBUG_LiveProtoCount--;
      45             : #endif
      46             : 
      47             :     // Note that our weak ref to mScope is not to be trusted at this point.
      48             : 
      49           0 :     XPCNativeSet::ClearCacheEntryForClassInfo(mClassInfo);
      50           0 : }
      51             : 
      52             : bool
      53        1824 : XPCWrappedNativeProto::Init(nsIXPCScriptable* scriptable,
      54             :                             bool callPostCreatePrototype)
      55             : {
      56        3648 :     AutoJSContext cx;
      57        1824 :     mScriptable = scriptable;
      58             : 
      59             :     const js::Class* jsclazz =
      60        2577 :         (mScriptable && mScriptable->AllowPropModsToPrototype())
      61        1867 :         ? &XPC_WN_ModsAllowed_Proto_JSClass
      62        1824 :         : &XPC_WN_NoMods_Proto_JSClass;
      63             : 
      64        3648 :     JS::RootedObject global(cx, mScope->GetGlobalJSObject());
      65        3648 :     JS::RootedObject proto(cx, JS_GetObjectPrototype(cx, global));
      66             :     mJSProtoObject = JS_NewObjectWithUniqueType(cx, js::Jsvalify(jsclazz),
      67        1824 :                                                 proto);
      68             : 
      69        1824 :     bool success = !!mJSProtoObject;
      70        1824 :     if (success) {
      71        1824 :         JS_SetPrivate(mJSProtoObject, this);
      72        1824 :         if (callPostCreatePrototype)
      73        1564 :             success = CallPostCreatePrototype();
      74             :     }
      75             : 
      76        3648 :     return success;
      77             : }
      78             : 
      79             : bool
      80        1564 : XPCWrappedNativeProto::CallPostCreatePrototype()
      81             : {
      82        3128 :     AutoJSContext cx;
      83             : 
      84             :     // Nothing to do if we don't have a scriptable callback.
      85        1564 :     if (!mScriptable)
      86        1071 :         return true;
      87             : 
      88             :     // Call the helper. This can handle being called if it's not implemented,
      89             :     // so we don't have to check any sort of "want" here. See xpc_map_end.h.
      90         493 :     nsresult rv = mScriptable->PostCreatePrototype(cx, mJSProtoObject);
      91         493 :     if (NS_FAILED(rv)) {
      92           0 :         JS_SetPrivate(mJSProtoObject, nullptr);
      93           0 :         mJSProtoObject = nullptr;
      94           0 :         XPCThrower::Throw(rv, cx);
      95           0 :         return false;
      96             :     }
      97             : 
      98         493 :     return true;
      99             : }
     100             : 
     101             : void
     102           0 : XPCWrappedNativeProto::JSProtoObjectFinalized(js::FreeOp* fop, JSObject* obj)
     103             : {
     104           0 :     MOZ_ASSERT(obj == mJSProtoObject, "huh?");
     105             : 
     106             : #ifdef DEBUG
     107             :     // Check that this object has already been swept from the map.
     108           0 :     ClassInfo2WrappedNativeProtoMap* map = GetScope()->GetWrappedNativeProtoMap();
     109           0 :     MOZ_ASSERT(map->Find(mClassInfo) != this);
     110             : #endif
     111             : 
     112           0 :     GetRuntime()->GetDyingWrappedNativeProtoMap()->Add(this);
     113             : 
     114           0 :     mJSProtoObject.finalize(js::CastToJSFreeOp(fop)->runtime());
     115           0 : }
     116             : 
     117             : void
     118           0 : XPCWrappedNativeProto::JSProtoObjectMoved(JSObject* obj, const JSObject* old)
     119             : {
     120           0 :     MOZ_ASSERT(mJSProtoObject == old);
     121           0 :     mJSProtoObject.init(obj); // Update without triggering barriers.
     122           0 : }
     123             : 
     124             : void
     125           0 : XPCWrappedNativeProto::SystemIsBeingShutDown()
     126             : {
     127             :     // Note that the instance might receive this call multiple times
     128             :     // as we walk to here from various places.
     129             : 
     130           0 :     if (mJSProtoObject) {
     131             :         // short circuit future finalization
     132           0 :         JS_SetPrivate(mJSProtoObject, nullptr);
     133           0 :         mJSProtoObject = nullptr;
     134             :     }
     135           0 : }
     136             : 
     137             : // static
     138             : XPCWrappedNativeProto*
     139        4378 : XPCWrappedNativeProto::GetNewOrUsed(XPCWrappedNativeScope* scope,
     140             :                                     nsIClassInfo* classInfo,
     141             :                                     nsIXPCScriptable* scriptable,
     142             :                                     bool callPostCreatePrototype)
     143             : {
     144        8756 :     AutoJSContext cx;
     145        4378 :     MOZ_ASSERT(scope, "bad param");
     146        4378 :     MOZ_ASSERT(classInfo, "bad param");
     147             : 
     148        8756 :     AutoMarkingWrappedNativeProtoPtr proto(cx);
     149        4378 :     ClassInfo2WrappedNativeProtoMap* map = nullptr;
     150             : 
     151        4378 :     map = scope->GetWrappedNativeProtoMap();
     152        4378 :     proto = map->Find(classInfo);
     153        4378 :     if (proto)
     154        2554 :         return proto;
     155             : 
     156        3648 :     RefPtr<XPCNativeSet> set = XPCNativeSet::GetNewOrUsed(classInfo);
     157        1824 :     if (!set)
     158           0 :         return nullptr;
     159             : 
     160        3648 :     proto = new XPCWrappedNativeProto(scope, classInfo, set.forget());
     161             : 
     162        1824 :     if (!proto || !proto->Init(scriptable, callPostCreatePrototype)) {
     163           0 :         delete proto.get();
     164           0 :         return nullptr;
     165             :     }
     166             : 
     167        1824 :     map->Add(classInfo, proto);
     168             : 
     169        1824 :     return proto;
     170             : }
     171             : 
     172             : void
     173           0 : XPCWrappedNativeProto::DebugDump(int16_t depth)
     174             : {
     175             : #ifdef DEBUG
     176           0 :     depth-- ;
     177           0 :     XPC_LOG_ALWAYS(("XPCWrappedNativeProto @ %p", this));
     178           0 :     XPC_LOG_INDENT();
     179           0 :         XPC_LOG_ALWAYS(("gDEBUG_LiveProtoCount is %d", gDEBUG_LiveProtoCount));
     180           0 :         XPC_LOG_ALWAYS(("mScope @ %p", mScope));
     181           0 :         XPC_LOG_ALWAYS(("mJSProtoObject @ %p", mJSProtoObject.get()));
     182           0 :         XPC_LOG_ALWAYS(("mSet @ %p", mSet.get()));
     183           0 :         XPC_LOG_ALWAYS(("mScriptable @ %p", mScriptable.get()));
     184           0 :         if (depth && mScriptable) {
     185           0 :             XPC_LOG_INDENT();
     186           0 :             XPC_LOG_ALWAYS(("mFlags of %x", mScriptable->GetScriptableFlags()));
     187           0 :             XPC_LOG_ALWAYS(("mJSClass @ %p", mScriptable->GetJSClass()));
     188           0 :             XPC_LOG_OUTDENT();
     189             :         }
     190           0 :     XPC_LOG_OUTDENT();
     191             : #endif
     192           0 : }
     193             : 
     194             : 

Generated by: LCOV version 1.13