LCOV - code coverage report
Current view: top level - dom/bindings - SimpleGlobalObject.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 29 63 46.0 %
Date: 2017-07-14 16:53:18 Functions: 4 11 36.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       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 file,
       5             :  * You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "mozilla/dom/SimpleGlobalObject.h"
       8             : 
       9             : #include "jsapi.h"
      10             : #include "js/Class.h"
      11             : 
      12             : #include "nsJSPrincipals.h"
      13             : #include "NullPrincipal.h"
      14             : #include "nsThreadUtils.h"
      15             : #include "nsContentUtils.h"
      16             : 
      17             : #include "xpcprivate.h"
      18             : 
      19             : #include "mozilla/dom/ScriptSettings.h"
      20             : 
      21             : namespace mozilla {
      22             : namespace dom {
      23             : 
      24             : NS_IMPL_CYCLE_COLLECTION_CLASS(SimpleGlobalObject)
      25             : 
      26           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(SimpleGlobalObject)
      27           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
      28           0 :   tmp->UnlinkHostObjectURIs();
      29           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
      30             : 
      31           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(SimpleGlobalObject)
      32           0 :   tmp->TraverseHostObjectURIs(cb);
      33           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
      34             : 
      35           0 : NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(SimpleGlobalObject)
      36             : 
      37           4 : NS_IMPL_CYCLE_COLLECTING_ADDREF(SimpleGlobalObject)
      38           3 : NS_IMPL_CYCLE_COLLECTING_RELEASE(SimpleGlobalObject)
      39           4 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SimpleGlobalObject)
      40           3 :   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
      41           3 :   NS_INTERFACE_MAP_ENTRY(nsIGlobalObject)
      42           1 : NS_INTERFACE_MAP_END
      43             : 
      44             : static void
      45           0 : SimpleGlobal_finalize(js::FreeOp *fop, JSObject *obj)
      46             : {
      47             :   SimpleGlobalObject* globalObject =
      48           0 :     static_cast<SimpleGlobalObject*>(JS_GetPrivate(obj));
      49           0 :   globalObject->ClearWrapper(obj);
      50           0 :   NS_RELEASE(globalObject);
      51           0 : }
      52             : 
      53             : static void
      54           0 : SimpleGlobal_moved(JSObject *obj, const JSObject *old)
      55             : {
      56             :   SimpleGlobalObject* globalObject =
      57           0 :     static_cast<SimpleGlobalObject*>(JS_GetPrivate(obj));
      58           0 :   globalObject->UpdateWrapper(obj, old);
      59           0 : }
      60             : 
      61             : static const js::ClassOps SimpleGlobalClassOps = {
      62             :     nullptr,
      63             :     nullptr,
      64             :     nullptr,
      65             :     nullptr,
      66             :     nullptr,
      67             :     JS_NewEnumerateStandardClasses,
      68             :     JS_ResolveStandardClass,
      69             :     JS_MayResolveStandardClass,
      70             :     SimpleGlobal_finalize,
      71             :     nullptr,
      72             :     nullptr,
      73             :     nullptr,
      74             :     JS_GlobalObjectTraceHook,
      75             : };
      76             : 
      77             : static const js::ClassExtension SimpleGlobalClassExtension = {
      78             :   nullptr,
      79             :   SimpleGlobal_moved
      80             : };
      81             : 
      82             : const js::Class SimpleGlobalClass = {
      83             :     "",
      84             :     JSCLASS_GLOBAL_FLAGS |
      85             :     JSCLASS_HAS_PRIVATE |
      86             :     JSCLASS_PRIVATE_IS_NSISUPPORTS |
      87             :     JSCLASS_FOREGROUND_FINALIZE,
      88             :     &SimpleGlobalClassOps,
      89             :     JS_NULL_CLASS_SPEC,
      90             :     &SimpleGlobalClassExtension,
      91             :     JS_NULL_OBJECT_OPS
      92             : };
      93             : 
      94             : // static
      95             : JSObject*
      96           1 : SimpleGlobalObject::Create(GlobalType globalType, JS::Handle<JS::Value> proto)
      97             : {
      98             :   // We can't root our return value with our AutoJSAPI because the rooting
      99             :   // analysis thinks ~AutoJSAPI can GC.  So we need to root in a scope outside
     100             :   // the lifetime of the AutoJSAPI.
     101           2 :   JS::Rooted<JSObject*> global(RootingCx());
     102             : 
     103             :   { // Scope to ensure the AutoJSAPI destructor runs before we end up returning
     104           2 :     AutoJSAPI jsapi;
     105           1 :     jsapi.Init();
     106           1 :     JSContext* cx = jsapi.cx();
     107             : 
     108           1 :     JS::CompartmentOptions options;
     109           1 :     options.creationOptions()
     110           1 :            .setInvisibleToDebugger(true)
     111             :            // Put our SimpleGlobalObjects in the system zone, so we won't create
     112             :            // lots of zones for what are probably very short-lived
     113             :            // compartments.  This should help them be GCed quicker and take up
     114             :            // less memory before they're GCed.
     115           1 :            .setSystemZone();
     116             : 
     117           1 :     if (NS_IsMainThread()) {
     118           2 :       nsCOMPtr<nsIPrincipal> principal = NullPrincipal::Create();
     119           1 :       options.creationOptions().setTrace(xpc::TraceXPCGlobal);
     120           2 :       global = xpc::CreateGlobalObject(cx, js::Jsvalify(&SimpleGlobalClass),
     121           1 :                                        nsJSPrincipals::get(principal),
     122           1 :                                        options);
     123             :     } else {
     124           0 :       global = JS_NewGlobalObject(cx, js::Jsvalify(&SimpleGlobalClass),
     125             :                                   nullptr,
     126           0 :                                   JS::DontFireOnNewGlobalHook, options);
     127             :     }
     128             : 
     129           1 :     if (!global) {
     130           0 :       jsapi.ClearException();
     131           0 :       return nullptr;
     132             :     }
     133             : 
     134           2 :     JSAutoCompartment ac(cx, global);
     135             : 
     136             :     // It's important to create the nsIGlobalObject for our new global before we
     137             :     // start trying to wrap things like the prototype into its compartment,
     138             :     // because the wrap operation relies on the global having its
     139             :     // nsIGlobalObject already.
     140             :     RefPtr<SimpleGlobalObject> globalObject =
     141           3 :       new SimpleGlobalObject(global, globalType);
     142             : 
     143             :     // Pass on ownership of globalObject to |global|.
     144           1 :     JS_SetPrivate(global, globalObject.forget().take());
     145             : 
     146           1 :     if (proto.isObjectOrNull()) {
     147           0 :       JS::Rooted<JSObject*> protoObj(cx, proto.toObjectOrNull());
     148           0 :       if (!JS_WrapObject(cx, &protoObj)) {
     149           0 :         jsapi.ClearException();
     150           0 :         return nullptr;
     151             :       }
     152             : 
     153           0 :       if (!JS_SplicePrototype(cx, global, protoObj)) {
     154           0 :         jsapi.ClearException();
     155           0 :         return nullptr;
     156             :       }
     157           1 :     } else if (!proto.isUndefined()) {
     158             :       // Bogus proto.
     159           0 :       return nullptr;
     160             :     }
     161             : 
     162           1 :     JS_FireOnNewGlobalObject(cx, global);
     163             :   }
     164             : 
     165           1 :   return global;
     166             : }
     167             : 
     168             : // static
     169             : SimpleGlobalObject::GlobalType
     170           0 : SimpleGlobalObject::SimpleGlobalType(JSObject* obj)
     171             : {
     172           0 :   if (js::GetObjectClass(obj) != &SimpleGlobalClass) {
     173           0 :     return SimpleGlobalObject::GlobalType::NotSimpleGlobal;
     174             :   }
     175             : 
     176             :   SimpleGlobalObject* globalObject =
     177           0 :     static_cast<SimpleGlobalObject*>(JS_GetPrivate(obj));
     178           0 :   return globalObject->Type();
     179             : }
     180             : 
     181             : } // namespace mozilla
     182             : } // namespace dom

Generated by: LCOV version 1.13