tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

NativeThenHandler.cpp (5556B)


      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
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "gtest/gtest.h"
      8 #include "js/TypeDecls.h"
      9 #include "js/Value.h"
     10 #include "mozilla/dom/Promise-inl.h"
     11 #include "mozilla/dom/Promise.h"
     12 #include "xpcpublic.h"
     13 
     14 using namespace mozilla;
     15 using namespace mozilla::dom;
     16 
     17 struct TraceCounts {
     18  int32_t mValue = 0;
     19  int32_t mId = 0;
     20  int32_t mObject = 0;
     21  int32_t mWrapperCache = 0;
     22  int32_t mTenuredHeapObject = 0;
     23  int32_t mString = 0;
     24  int32_t mScript = 0;
     25  int32_t mFunction = 0;
     26 };
     27 
     28 struct DummyCallbacks final : public TraceCallbacks {
     29  void Trace(JS::Heap<JS::Value>*, const char*, void* aClosure) const override {
     30    static_cast<TraceCounts*>(aClosure)->mValue++;
     31  }
     32 
     33  void Trace(JS::Heap<jsid>*, const char*, void* aClosure) const override {
     34    static_cast<TraceCounts*>(aClosure)->mId++;
     35  }
     36 
     37  void Trace(JS::Heap<JSObject*>*, const char*, void* aClosure) const override {
     38    static_cast<TraceCounts*>(aClosure)->mObject++;
     39  }
     40 
     41  void Trace(nsWrapperCache*, const char* aName,
     42             void* aClosure) const override {
     43    static_cast<TraceCounts*>(aClosure)->mWrapperCache++;
     44  }
     45 
     46  void Trace(JS::TenuredHeap<JSObject*>*, const char*,
     47             void* aClosure) const override {
     48    static_cast<TraceCounts*>(aClosure)->mTenuredHeapObject++;
     49  }
     50 
     51  void Trace(JS::Heap<JSString*>*, const char*, void* aClosure) const override {
     52    static_cast<TraceCounts*>(aClosure)->mString++;
     53  }
     54 
     55  void Trace(JS::Heap<JSScript*>*, const char*, void* aClosure) const override {
     56    static_cast<TraceCounts*>(aClosure)->mScript++;
     57  }
     58 
     59  void Trace(JS::Heap<JSFunction*>*, const char*,
     60             void* aClosure) const override {
     61    static_cast<TraceCounts*>(aClosure)->mFunction++;
     62  }
     63 };
     64 
     65 TEST(NativeThenHandler, TraceValue)
     66 {
     67  auto onResolve = [](JSContext*, JS::Handle<JS::Value>, ErrorResult&,
     68                      JS::Handle<JS::Value>) -> already_AddRefed<Promise> {
     69    return nullptr;
     70  };
     71  auto onReject = [](JSContext*, JS::Handle<JS::Value>, ErrorResult&,
     72                     JS::Handle<JS::Value>) -> already_AddRefed<Promise> {
     73    return nullptr;
     74  };
     75 
     76  // Explicit type for backward compatibility with clang<7 / gcc<8
     77  using HandlerType =
     78      NativeThenHandler<decltype(onResolve), decltype(onReject), std::tuple<>,
     79                        std::tuple<JS::HandleValue>>;
     80  RefPtr<HandlerType> handler = new HandlerType(
     81      nullptr, Some(onResolve), Some(onReject), std::make_tuple(),
     82      std::make_tuple(JS::UndefinedHandleValue));
     83 
     84  TraceCounts counts;
     85  NS_CYCLE_COLLECTION_PARTICIPANT(HandlerType)
     86      ->Trace(handler.get(), DummyCallbacks(), &counts);
     87 
     88  EXPECT_EQ(counts.mValue, 1);
     89 }
     90 
     91 TEST(NativeThenHandler, TraceObject)
     92 {
     93  auto onResolve = [](JSContext*, JS::Handle<JS::Value>, ErrorResult&,
     94                      JS::Handle<JSObject*>) -> already_AddRefed<Promise> {
     95    return nullptr;
     96  };
     97  auto onReject = [](JSContext*, JS::Handle<JS::Value>, ErrorResult&,
     98                     JS::Handle<JSObject*>) -> already_AddRefed<Promise> {
     99    return nullptr;
    100  };
    101 
    102  AutoJSAPI jsapi;
    103  MOZ_ALWAYS_TRUE(jsapi.Init(xpc::PrivilegedJunkScope()));
    104  JSContext* cx = jsapi.cx();
    105  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
    106 
    107  // Explicit type for backward compatibility with clang<7 / gcc<8
    108  using HandlerType =
    109      NativeThenHandler<decltype(onResolve), decltype(onReject), std::tuple<>,
    110                        std::tuple<JS::HandleObject>>;
    111  RefPtr<HandlerType> handler = new HandlerType(
    112      nullptr, Some(onResolve), Some(onReject), std::make_tuple(),
    113      std::make_tuple(JS::HandleObject(obj)));
    114 
    115  TraceCounts counts;
    116  NS_CYCLE_COLLECTION_PARTICIPANT(HandlerType)
    117      ->Trace(handler.get(), DummyCallbacks(), &counts);
    118 
    119  EXPECT_EQ(counts.mObject, 1);
    120 }
    121 
    122 TEST(NativeThenHandler, TraceMixed)
    123 {
    124  auto onResolve = [](JSContext*, JS::Handle<JS::Value>, ErrorResult&,
    125                      nsIGlobalObject*, Promise*, JS::Handle<JS::Value>,
    126                      JS::Handle<JSObject*>) -> already_AddRefed<Promise> {
    127    return nullptr;
    128  };
    129  auto onReject = [](JSContext*, JS::Handle<JS::Value>, ErrorResult&,
    130                     nsIGlobalObject*, Promise*, JS::Handle<JS::Value>,
    131                     JS::Handle<JSObject*>) -> already_AddRefed<Promise> {
    132    return nullptr;
    133  };
    134 
    135  AutoJSAPI jsapi;
    136  MOZ_ALWAYS_TRUE(jsapi.Init(xpc::PrivilegedJunkScope()));
    137  JSContext* cx = jsapi.cx();
    138  nsCOMPtr<nsIGlobalObject> global = xpc::CurrentNativeGlobal(cx);
    139  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
    140 
    141  RefPtr<Promise> promise = Promise::Create(global, IgnoreErrors());
    142 
    143  // Explicit type for backward compatibility with clang<7 / gcc<8
    144  using HandlerType =
    145      NativeThenHandler<decltype(onResolve), decltype(onReject),
    146                        std::tuple<nsCOMPtr<nsIGlobalObject>, RefPtr<Promise>>,
    147                        std::tuple<JS::HandleValue, JS::HandleObject>>;
    148  RefPtr<HandlerType> handler = new HandlerType(
    149      nullptr, Some(onResolve), Some(onReject),
    150      std::make_tuple(global, promise),
    151      std::make_tuple(JS::UndefinedHandleValue, JS::HandleObject(obj)));
    152 
    153  TraceCounts counts;
    154  NS_CYCLE_COLLECTION_PARTICIPANT(HandlerType)
    155      ->Trace(handler.get(), DummyCallbacks(), &counts);
    156 
    157  EXPECT_EQ(counts.mValue, 1);
    158  EXPECT_EQ(counts.mObject, 1);
    159 }