js/xpconnect/src/xpcpublic.h

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 #ifndef xpcpublic_h
     8 #define xpcpublic_h
    10 #include "jsapi.h"
    11 #include "jsproxy.h"
    12 #include "js/HeapAPI.h"
    13 #include "js/GCAPI.h"
    15 #include "nsISupports.h"
    16 #include "nsIURI.h"
    17 #include "nsIPrincipal.h"
    18 #include "nsWrapperCache.h"
    19 #include "nsStringGlue.h"
    20 #include "nsTArray.h"
    21 #include "mozilla/dom/JSSlots.h"
    22 #include "nsMathUtils.h"
    23 #include "nsStringBuffer.h"
    24 #include "mozilla/dom/BindingDeclarations.h"
    26 class nsGlobalWindow;
    27 class nsIPrincipal;
    28 class nsScriptNameSpaceManager;
    29 class nsIGlobalObject;
    30 class nsIMemoryReporterCallback;
    32 #ifndef BAD_TLS_INDEX
    33 #define BAD_TLS_INDEX ((uint32_t) -1)
    34 #endif
    36 namespace xpc {
    38 class Scriptability {
    39 public:
    40     Scriptability(JSCompartment *c);
    41     bool Allowed();
    42     bool IsImmuneToScriptPolicy();
    44     void Block();
    45     void Unblock();
    46     void SetDocShellAllowsScript(bool aAllowed);
    48     static Scriptability& Get(JSObject *aScope);
    50 private:
    51     // Whenever a consumer wishes to prevent script from running on a global,
    52     // it increments this value with a call to Block(). When it wishes to
    53     // re-enable it (if ever), it decrements this value with a call to Unblock().
    54     // Script may not run if this value is non-zero.
    55     uint32_t mScriptBlocks;
    57     // Whether the docshell allows javascript in this scope. If this scope
    58     // doesn't have a docshell, this value is always true.
    59     bool mDocShellAllowsScript;
    61     // Whether this scope is immune to user-defined or addon-defined script
    62     // policy.
    63     bool mImmuneToScriptPolicy;
    65     // Whether the new-style domain policy when this compartment was created
    66     // forbids script execution.
    67     bool mScriptBlockedByPolicy;
    68 };
    70 JSObject *
    71 TransplantObject(JSContext *cx, JS::HandleObject origobj, JS::HandleObject target);
    73 bool IsXBLScope(JSCompartment *compartment);
    74 bool IsInXBLScope(JSObject *obj);
    76 // Return a raw XBL scope object corresponding to contentScope, which must
    77 // be an object whose global is a DOM window.
    78 //
    79 // The return value is not wrapped into cx->compartment, so be sure to enter
    80 // its compartment before doing anything meaningful.
    81 //
    82 // Also note that XBL scopes are lazily created, so the return-value should be
    83 // null-checked unless the caller can ensure that the scope must already
    84 // exist.
    85 //
    86 // This function asserts if |contentScope| is itself in an XBL scope to catch
    87 // sloppy consumers. Conversely, GetXBLScopeOrGlobal will handle objects that
    88 // are in XBL scope (by just returning the global).
    89 JSObject *
    90 GetXBLScope(JSContext *cx, JSObject *contentScope);
    92 inline JSObject *
    93 GetXBLScopeOrGlobal(JSContext *cx, JSObject *obj) {
    94     if (IsInXBLScope(obj))
    95         return js::GetGlobalForObjectCrossCompartment(obj);
    96     return GetXBLScope(cx, obj);
    97 }
    99 // Returns whether XBL scopes have been explicitly disabled for code running
   100 // in this compartment. See the comment around mAllowXBLScope.
   101 bool
   102 AllowXBLScope(JSCompartment *c);
   104 // Returns whether we will use an XBL scope for this compartment. This is
   105 // semantically equivalent to comparing global != GetXBLScope(global), but it
   106 // does not have the side-effect of eagerly creating the XBL scope if it does
   107 // not already exist.
   108 bool
   109 UseXBLScope(JSCompartment *c);
   111 bool
   112 IsSandboxPrototypeProxy(JSObject *obj);
   114 bool
   115 IsReflector(JSObject *obj);
   117 bool
   118 IsXrayWrapper(JSObject *obj);
   120 // If this function was created for a given XrayWrapper, returns the global of
   121 // the Xrayed object. Otherwise, returns the global of the function.
   122 //
   123 // To emphasize the obvious: the return value here is not necessarily same-
   124 // compartment with the argument.
   125 JSObject *
   126 XrayAwareCalleeGlobal(JSObject *fun);
   128 void
   129 TraceXPCGlobal(JSTracer *trc, JSObject *obj);
   131 } /* namespace xpc */
   133 namespace JS {
   135 struct RuntimeStats;
   137 }
   139 #define XPCONNECT_GLOBAL_FLAGS_WITH_EXTRA_SLOTS(n)                            \
   140     JSCLASS_DOM_GLOBAL | JSCLASS_HAS_PRIVATE |                                \
   141     JSCLASS_PRIVATE_IS_NSISUPPORTS | JSCLASS_IMPLEMENTS_BARRIERS |            \
   142     JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(DOM_GLOBAL_SLOTS + n)
   144 #define XPCONNECT_GLOBAL_EXTRA_SLOT_OFFSET (JSCLASS_GLOBAL_SLOT_COUNT + DOM_GLOBAL_SLOTS)
   146 #define XPCONNECT_GLOBAL_FLAGS XPCONNECT_GLOBAL_FLAGS_WITH_EXTRA_SLOTS(0)
   148 inline JSObject*
   149 xpc_FastGetCachedWrapper(JSContext *cx, nsWrapperCache *cache, JS::MutableHandleValue vp)
   150 {
   151     if (cache) {
   152         JSObject* wrapper = cache->GetWrapper();
   153         if (wrapper &&
   154             js::GetObjectCompartment(wrapper) == js::GetContextCompartment(cx))
   155         {
   156             vp.setObject(*wrapper);
   157             return wrapper;
   158         }
   159     }
   161     return nullptr;
   162 }
   164 // The JS GC marks objects gray that are held alive directly or
   165 // indirectly by an XPConnect root. The cycle collector explores only
   166 // this subset of the JS heap.
   167 inline bool
   168 xpc_IsGrayGCThing(void *thing)
   169 {
   170     return JS::GCThingIsMarkedGray(thing);
   171 }
   173 // The cycle collector only cares about some kinds of GCthings that are
   174 // reachable from an XPConnect root. Implemented in nsXPConnect.cpp.
   175 extern bool
   176 xpc_GCThingIsGrayCCThing(void *thing);
   178 inline JSScript *
   179 xpc_UnmarkGrayScript(JSScript *script)
   180 {
   181     if (script)
   182         JS::ExposeGCThingToActiveJS(script, JSTRACE_SCRIPT);
   184     return script;
   185 }
   187 // If aVariant is an XPCVariant, this marks the object to be in aGeneration.
   188 // This also unmarks the gray JSObject.
   189 extern void
   190 xpc_MarkInCCGeneration(nsISupports* aVariant, uint32_t aGeneration);
   192 // If aWrappedJS is a JS wrapper, unmark its JSObject.
   193 extern void
   194 xpc_TryUnmarkWrappedGrayObject(nsISupports* aWrappedJS);
   196 extern void
   197 xpc_UnmarkSkippableJSHolders();
   199 // No JS can be on the stack when this is called. Probably only useful from
   200 // xpcshell.
   201 void
   202 xpc_ActivateDebugMode();
   204 // readable string conversions, static methods and members only
   205 class XPCStringConvert
   206 {
   207     // One-slot cache, because it turns out it's common for web pages to
   208     // get the same string a few times in a row.  We get about a 40% cache
   209     // hit rate on this cache last it was measured.  We'd get about 70%
   210     // hit rate with a hashtable with removal on finalization, but that
   211     // would take a lot more machinery.
   212     struct ZoneStringCache
   213     {
   214         nsStringBuffer* mBuffer;
   215         JSString* mString;
   216     };
   218 public:
   220     // If the string shares the readable's buffer, that buffer will
   221     // get assigned to *sharedBuffer.  Otherwise null will be
   222     // assigned.
   223     static bool ReadableToJSVal(JSContext *cx, const nsAString &readable,
   224                                 nsStringBuffer** sharedBuffer,
   225                                 JS::MutableHandleValue vp);
   227     // Convert the given stringbuffer/length pair to a jsval
   228     static MOZ_ALWAYS_INLINE bool
   229     StringBufferToJSVal(JSContext* cx, nsStringBuffer* buf, uint32_t length,
   230                         JS::MutableHandleValue rval, bool* sharedBuffer)
   231     {
   232         JS::Zone *zone = js::GetContextZone(cx);
   233         ZoneStringCache *cache = static_cast<ZoneStringCache*>(JS_GetZoneUserData(zone));
   234         if (cache && buf == cache->mBuffer) {
   235             MOZ_ASSERT(JS::GetGCThingZone(cache->mString) == zone);
   236             JS::MarkStringAsLive(zone, cache->mString);
   237             rval.setString(cache->mString);
   238             *sharedBuffer = false;
   239             return true;
   240         }
   242         JSString *str = JS_NewExternalString(cx,
   243                                              static_cast<jschar*>(buf->Data()),
   244                                              length, &sDOMStringFinalizer);
   245         if (!str) {
   246             return false;
   247         }
   248         rval.setString(str);
   249         if (!cache) {
   250             cache = new ZoneStringCache();
   251             JS_SetZoneUserData(zone, cache);
   252         }
   253         cache->mBuffer = buf;
   254         cache->mString = str;
   255         *sharedBuffer = true;
   256         return true;
   257     }
   259     static void FreeZoneCache(JS::Zone *zone);
   260     static void ClearZoneCache(JS::Zone *zone);
   262     static MOZ_ALWAYS_INLINE bool IsLiteral(JSString *str)
   263     {
   264         return JS_IsExternalString(str) &&
   265                JS_GetExternalStringFinalizer(str) == &sLiteralFinalizer;
   266     }
   268     static MOZ_ALWAYS_INLINE bool IsDOMString(JSString *str)
   269     {
   270         return JS_IsExternalString(str) &&
   271                JS_GetExternalStringFinalizer(str) == &sDOMStringFinalizer;
   272     }
   274 private:
   275     static const JSStringFinalizer sLiteralFinalizer, sDOMStringFinalizer;
   277     static void FinalizeLiteral(const JSStringFinalizer *fin, jschar *chars);
   279     static void FinalizeDOMString(const JSStringFinalizer *fin, jschar *chars);
   281     XPCStringConvert();         // not implemented
   282 };
   284 namespace xpc {
   286 // If these functions return false, then an exception will be set on cx.
   287 bool Base64Encode(JSContext *cx, JS::HandleValue val, JS::MutableHandleValue out);
   288 bool Base64Decode(JSContext *cx, JS::HandleValue val, JS::MutableHandleValue out);
   290 /**
   291  * Convert an nsString to jsval, returning true on success.
   292  * Note, the ownership of the string buffer may be moved from str to rval.
   293  * If that happens, str will point to an empty string after this call.
   294  */
   295 bool NonVoidStringToJsval(JSContext *cx, nsAString &str, JS::MutableHandleValue rval);
   296 inline bool StringToJsval(JSContext *cx, nsAString &str, JS::MutableHandleValue rval)
   297 {
   298     // From the T_DOMSTRING case in XPCConvert::NativeData2JS.
   299     if (str.IsVoid()) {
   300         rval.setNull();
   301         return true;
   302     }
   303     return NonVoidStringToJsval(cx, str, rval);
   304 }
   306 inline bool
   307 NonVoidStringToJsval(JSContext* cx, const nsAString& str, JS::MutableHandleValue rval)
   308 {
   309     nsString mutableCopy(str);
   310     return NonVoidStringToJsval(cx, mutableCopy, rval);
   311 }
   313 inline bool
   314 StringToJsval(JSContext* cx, const nsAString& str, JS::MutableHandleValue rval)
   315 {
   316     nsString mutableCopy(str);
   317     return StringToJsval(cx, mutableCopy, rval);
   318 }
   320 /**
   321  * As above, but for mozilla::dom::DOMString.
   322  */
   323 MOZ_ALWAYS_INLINE
   324 bool NonVoidStringToJsval(JSContext* cx, mozilla::dom::DOMString& str,
   325                           JS::MutableHandleValue rval)
   326 {
   327     if (!str.HasStringBuffer()) {
   328         // It's an actual XPCOM string
   329         return NonVoidStringToJsval(cx, str.AsAString(), rval);
   330     }
   332     uint32_t length = str.StringBufferLength();
   333     if (length == 0) {
   334         rval.set(JS_GetEmptyStringValue(cx));
   335         return true;
   336     }
   338     nsStringBuffer* buf = str.StringBuffer();
   339     bool shared;
   340     if (!XPCStringConvert::StringBufferToJSVal(cx, buf, length, rval,
   341                                                &shared)) {
   342         return false;
   343     }
   344     if (shared) {
   345         // JS now needs to hold a reference to the buffer
   346         buf->AddRef();
   347     }
   348     return true;
   349 }
   351 MOZ_ALWAYS_INLINE
   352 bool StringToJsval(JSContext* cx, mozilla::dom::DOMString& str,
   353                    JS::MutableHandleValue rval)
   354 {
   355     if (str.IsNull()) {
   356         rval.setNull();
   357         return true;
   358     }
   359     return NonVoidStringToJsval(cx, str, rval);
   360 }
   362 nsIPrincipal *GetCompartmentPrincipal(JSCompartment *compartment);
   364 void SetLocationForGlobal(JSObject *global, const nsACString& location);
   365 void SetLocationForGlobal(JSObject *global, nsIURI *locationURI);
   367 // ReportJSRuntimeExplicitTreeStats will expect this in the |extra| member
   368 // of JS::ZoneStats.
   369 class ZoneStatsExtras {
   370 public:
   371     ZoneStatsExtras()
   372     {}
   374     nsAutoCString pathPrefix;
   376 private:
   377     ZoneStatsExtras(const ZoneStatsExtras &other) MOZ_DELETE;
   378     ZoneStatsExtras& operator=(const ZoneStatsExtras &other) MOZ_DELETE;
   379 };
   381 // ReportJSRuntimeExplicitTreeStats will expect this in the |extra| member
   382 // of JS::CompartmentStats.
   383 class CompartmentStatsExtras {
   384 public:
   385     CompartmentStatsExtras()
   386     {}
   388     nsAutoCString jsPathPrefix;
   389     nsAutoCString domPathPrefix;
   390     nsCOMPtr<nsIURI> location;
   392 private:
   393     CompartmentStatsExtras(const CompartmentStatsExtras &other) MOZ_DELETE;
   394     CompartmentStatsExtras& operator=(const CompartmentStatsExtras &other) MOZ_DELETE;
   395 };
   397 // This reports all the stats in |rtStats| that belong in the "explicit" tree,
   398 // (which isn't all of them).
   399 // @see ZoneStatsExtras
   400 // @see CompartmentStatsExtras
   401 nsresult
   402 ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats &rtStats,
   403                                  const nsACString &rtPath,
   404                                  nsIMemoryReporterCallback *cb,
   405                                  nsISupports *closure, size_t *rtTotal = nullptr);
   407 /**
   408  * Throws an exception on cx and returns false.
   409  */
   410 bool
   411 Throw(JSContext *cx, nsresult rv);
   413 /**
   414  * Every global should hold a native that implements the nsIGlobalObject interface.
   415  */
   416 nsIGlobalObject *
   417 GetNativeForGlobal(JSObject *global);
   419 /**
   420  * In some cases a native object does not really belong to any compartment (XBL,
   421  * document created from by XHR of a worker, etc.). But when for some reason we
   422  * have to wrap these natives (because of an event for example) instead of just
   423  * wrapping them into some random compartment we find on the context stack (like
   424  * we did previously) a default compartment is used. This function returns that
   425  * compartment's global. It is a singleton on the runtime.
   426  * If you find yourself wanting to use this compartment, you're probably doing
   427  * something wrong. Callers MUST consult with the XPConnect module owner before
   428  * using this compartment. If you don't, bholley will hunt you down.
   429  */
   430 JSObject *
   431 GetJunkScope();
   433 /**
   434  * Returns the native global of the junk scope. See comment of GetJunkScope
   435  * about the conditions of using it.
   436  */
   437 nsIGlobalObject *
   438 GetJunkScopeGlobal();
   440 /**
   441  * Shared compilation scope for XUL prototype documents and XBL
   442  * precompilation. This compartment has a null principal. No code may run, and
   443  * it is invisible to the debugger.
   444  */
   445 JSObject *
   446 GetCompilationScope();
   448 /**
   449  * If |aObj| is a window, returns the associated nsGlobalWindow.
   450  * Otherwise, returns null.
   451  */
   452 nsGlobalWindow*
   453 WindowOrNull(JSObject *aObj);
   455 /*
   456  * Returns the dummy global associated with the SafeJSContext. Callers MUST
   457  * consult with the XPConnect module owner before using this function.
   458  */
   459 JSObject *
   460 GetSafeJSContextGlobal();
   462 /**
   463  * If |aObj| has a window for a global, returns the associated nsGlobalWindow.
   464  * Otherwise, returns null.
   465  */
   466 nsGlobalWindow*
   467 WindowGlobalOrNull(JSObject *aObj);
   469 // Error reporter used when there is no associated DOM window on to which to
   470 // report errors and warnings.
   471 void
   472 SystemErrorReporter(JSContext *cx, const char *message, JSErrorReport *rep);
   474 void
   475 SimulateActivityCallback(bool aActive);
   477 void
   478 RecordAdoptedNode(JSCompartment *c);
   480 void
   481 RecordDonatedNode(JSCompartment *c);
   483 // This function may be used off-main-thread, in which case it is benignly
   484 // racey.
   485 bool
   486 ShouldDiscardSystemSource();
   488 } // namespace xpc
   490 namespace mozilla {
   491 namespace dom {
   493 typedef JSObject*
   494 (*DefineInterface)(JSContext *cx, JS::Handle<JSObject*> global,
   495                    JS::Handle<jsid> id, bool defineOnGlobal);
   497 typedef JSObject*
   498 (*ConstructNavigatorProperty)(JSContext *cx, JS::Handle<JSObject*> naviObj);
   500 // Check whether a constructor should be enabled for the given object.
   501 // Note that the object should NOT be an Xray, since Xrays will end up
   502 // defining constructors on the underlying object.
   503 // This is a typedef for the function type itself, not the function
   504 // pointer, so it's more obvious that pointers to a ConstructorEnabled
   505 // can be null.
   506 typedef bool
   507 (ConstructorEnabled)(JSContext* cx, JS::Handle<JSObject*> obj);
   509 void
   510 Register(nsScriptNameSpaceManager* aNameSpaceManager);
   512 /**
   513  * A test for whether WebIDL methods that should only be visible to
   514  * chrome or XBL scopes should be exposed.
   515  */
   516 bool IsChromeOrXBL(JSContext* cx, JSObject* /* unused */);
   518 } // namespace dom
   519 } // namespace mozilla
   521 #endif

mercurial