LCOV - code coverage report
Current view: top level - js/public - GCVariant.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 45 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 94 0.0 %
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             : #ifndef js_GCVariant_h
       8             : #define js_GCVariant_h
       9             : 
      10             : #include "mozilla/Variant.h"
      11             : 
      12             : #include "js/GCPolicyAPI.h"
      13             : #include "js/RootingAPI.h"
      14             : #include "js/TracingAPI.h"
      15             : 
      16             : namespace JS {
      17             : 
      18             : // These template specializations allow Variant to be used inside GC wrappers.
      19             : //
      20             : // When matching on GC wrappers around Variants, matching should be done on
      21             : // the wrapper itself. The matcher class's methods should take Handles or
      22             : // MutableHandles. For example,
      23             : //
      24             : //   struct MyMatcher
      25             : //   {
      26             : //        using ReturnType = const char*;
      27             : //        ReturnType match(HandleObject o) { return "object"; }
      28             : //        ReturnType match(HandleScript s) { return "script"; }
      29             : //   };
      30             : //
      31             : //   Rooted<Variant<JSObject*, JSScript*>> v(cx, someScript);
      32             : //   MyMatcher mm;
      33             : //   v.match(mm);
      34             : //
      35             : // If you get compile errors about inability to upcast subclasses (e.g., from
      36             : // NativeObject* to JSObject*) and are inside js/src, be sure to also include
      37             : // "gc/Policy.h".
      38             : 
      39             : namespace detail {
      40             : 
      41             : template <typename... Ts>
      42             : struct GCVariantImplementation;
      43             : 
      44             : // The base case.
      45             : template <typename T>
      46             : struct GCVariantImplementation<T>
      47             : {
      48             :     template <typename ConcreteVariant>
      49           0 :     static void trace(JSTracer* trc, ConcreteVariant* v, const char* name) {
      50           0 :         T& thing = v->template as<T>();
      51           0 :         if (!mozilla::IsPointer<T>::value || thing)
      52           0 :             GCPolicy<T>::trace(trc, &thing, name);
      53           0 :     }
      54             : 
      55             :     template <typename Matcher, typename ConcreteVariant>
      56             :     static typename Matcher::ReturnType
      57           0 :     match(Matcher& matcher, Handle<ConcreteVariant> v) {
      58           0 :         const T& thing = v.get().template as<T>();
      59           0 :         return matcher.match(Handle<T>::fromMarkedLocation(&thing));
      60             :     }
      61             : 
      62             :     template <typename Matcher, typename ConcreteVariant>
      63             :     static typename Matcher::ReturnType
      64           0 :     match(Matcher& matcher, MutableHandle<ConcreteVariant> v) {
      65           0 :         T& thing = v.get().template as<T>();
      66           0 :         return matcher.match(MutableHandle<T>::fromMarkedLocation(&thing));
      67             :     }
      68             : };
      69             : 
      70             : // The inductive case.
      71             : template <typename T, typename... Ts>
      72             : struct GCVariantImplementation<T, Ts...>
      73             : {
      74             :     using Next = GCVariantImplementation<Ts...>;
      75             : 
      76             :     template <typename ConcreteVariant>
      77           0 :     static void trace(JSTracer* trc, ConcreteVariant* v, const char* name) {
      78           0 :         if (v->template is<T>()) {
      79           0 :             T& thing = v->template as<T>();
      80           0 :             if (!mozilla::IsPointer<T>::value || thing)
      81           0 :                 GCPolicy<T>::trace(trc, &thing, name);
      82             :         } else {
      83           0 :             Next::trace(trc, v, name);
      84             :         }
      85           0 :     }
      86             : 
      87             :     template <typename Matcher, typename ConcreteVariant>
      88             :     static typename Matcher::ReturnType
      89           0 :     match(Matcher& matcher, Handle<ConcreteVariant> v) {
      90           0 :         if (v.get().template is<T>()) {
      91           0 :             const T& thing = v.get().template as<T>();
      92           0 :             return matcher.match(Handle<T>::fromMarkedLocation(&thing));
      93             :         }
      94           0 :         return Next::match(matcher, v);
      95             :     }
      96             : 
      97             :     template <typename Matcher, typename ConcreteVariant>
      98             :     static typename Matcher::ReturnType
      99           0 :     match(Matcher& matcher, MutableHandle<ConcreteVariant> v) {
     100           0 :         if (v.get().template is<T>()) {
     101           0 :             T& thing = v.get().template as<T>();
     102           0 :             return matcher.match(MutableHandle<T>::fromMarkedLocation(&thing));
     103             :         }
     104           0 :         return Next::match(matcher, v);
     105             :     }
     106             : };
     107             : 
     108             : } // namespace detail
     109             : 
     110             : template <typename... Ts>
     111             : struct GCPolicy<mozilla::Variant<Ts...>>
     112             : {
     113             :     using Impl = detail::GCVariantImplementation<Ts...>;
     114             : 
     115             :     // Variants do not provide initial(). They do not have a default initial
     116             :     // value and one must be provided.
     117             : 
     118           0 :     static void trace(JSTracer* trc, mozilla::Variant<Ts...>* v, const char* name) {
     119           0 :         Impl::trace(trc, v, name);
     120           0 :     }
     121             : };
     122             : 
     123             : } // namespace JS
     124             : 
     125             : namespace js {
     126             : 
     127             : template <typename Wrapper, typename... Ts>
     128           0 : class WrappedPtrOperations<mozilla::Variant<Ts...>, Wrapper>
     129             : {
     130             :     using Impl = JS::detail::GCVariantImplementation<Ts...>;
     131             :     using Variant = mozilla::Variant<Ts...>;
     132             : 
     133           0 :     const Variant& variant() const { return static_cast<const Wrapper*>(this)->get(); }
     134             : 
     135             :   public:
     136             :     template <typename T>
     137           0 :     bool is() const {
     138           0 :         return variant().template is<T>();
     139             :     }
     140             : 
     141             :     template <typename T>
     142           0 :     JS::Handle<T> as() const {
     143           0 :         return Handle<T>::fromMarkedLocation(&variant().template as<T>());
     144             :     }
     145             : 
     146             :     template <typename Matcher>
     147             :     typename Matcher::ReturnType
     148           0 :     match(Matcher& matcher) const {
     149           0 :         return Impl::match(matcher, JS::Handle<Variant>::fromMarkedLocation(&variant()));
     150             :     }
     151             : };
     152             : 
     153             : template <typename Wrapper, typename... Ts>
     154           0 : class MutableWrappedPtrOperations<mozilla::Variant<Ts...>, Wrapper>
     155             :   : public WrappedPtrOperations<mozilla::Variant<Ts...>, Wrapper>
     156             : {
     157             :     using Impl = JS::detail::GCVariantImplementation<Ts...>;
     158             :     using Variant = mozilla::Variant<Ts...>;
     159             : 
     160             :     const Variant& variant() const { return static_cast<const Wrapper*>(this)->get(); }
     161           0 :     Variant& variant() { return static_cast<Wrapper*>(this)->get(); }
     162             : 
     163             :   public:
     164             :     template <typename T>
     165           0 :     JS::MutableHandle<T> as() {
     166           0 :         return JS::MutableHandle<T>::fromMarkedLocation(&variant().template as<T>());
     167             :     }
     168             : 
     169             :     template <typename Matcher>
     170             :     typename Matcher::ReturnType
     171           0 :     match(Matcher& matcher) {
     172           0 :         return Impl::match(matcher, JS::MutableHandle<Variant>::fromMarkedLocation(&variant()));
     173             :     }
     174             : };
     175             : 
     176             : } // namespace js
     177             : 
     178             : #endif // js_GCVariant_h

Generated by: LCOV version 1.13