WeakMapPtr.cpp (2987B)
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 "js/WeakMapPtr.h" 8 9 #include "gc/WeakMap-inl.h" 10 11 // 12 // Machinery for the externally-linkable JS::WeakMapPtr, which wraps js::WeakMap 13 // for a few public data types. 14 // 15 16 using namespace js; 17 18 namespace WeakMapDetails { 19 20 template <typename T> 21 struct DataType {}; 22 23 template <> 24 struct DataType<JSObject*> { 25 static JSObject* NullValue() { return nullptr; } 26 }; 27 28 template <> 29 struct DataType<JS::Value> { 30 static JS::Value NullValue() { return JS::UndefinedValue(); } 31 }; 32 33 template <typename K, typename V> 34 struct Utils { 35 using KeyType = K; 36 using ValueType = V; 37 using Type = WeakMap<KeyType, ValueType, ZoneAllocPolicy>; 38 using PtrType = Type*; 39 static PtrType cast(void* ptr) { return static_cast<PtrType>(ptr); } 40 }; 41 42 } // namespace WeakMapDetails 43 44 template <typename K, typename V> 45 void JS::WeakMapPtr<K, V>::destroy() { 46 MOZ_ASSERT(initialized()); 47 js_delete(WeakMapDetails::Utils<K, V>::cast(ptr)); 48 ptr = nullptr; 49 } 50 51 template <typename K, typename V> 52 bool JS::WeakMapPtr<K, V>::init(JSContext* cx) { 53 MOZ_ASSERT(!initialized()); 54 typename WeakMapDetails::Utils<K, V>::PtrType map = 55 cx->new_<typename WeakMapDetails::Utils<K, V>::Type>(cx); 56 if (!map) { 57 return false; 58 } 59 ptr = map; 60 return true; 61 } 62 63 template <typename K, typename V> 64 void JS::WeakMapPtr<K, V>::trace(JSTracer* trc) { 65 MOZ_ASSERT(initialized()); 66 return WeakMapDetails::Utils<K, V>::cast(ptr)->trace(trc); 67 } 68 69 template <typename K, typename V> 70 V JS::WeakMapPtr<K, V>::lookup(const K& key) { 71 MOZ_ASSERT(initialized()); 72 typename WeakMapDetails::Utils<K, V>::Type::Ptr result = 73 WeakMapDetails::Utils<K, V>::cast(ptr)->lookup(key); 74 if (!result) { 75 return WeakMapDetails::DataType<V>::NullValue(); 76 } 77 return result->value(); 78 } 79 80 template <typename K, typename V> 81 bool JS::WeakMapPtr<K, V>::put(JSContext* cx, const K& key, const V& value) { 82 MOZ_ASSERT(initialized()); 83 return WeakMapDetails::Utils<K, V>::cast(ptr)->put(key, value); 84 } 85 86 template <typename K, typename V> 87 V JS::WeakMapPtr<K, V>::removeValue(const K& key) { 88 using Map = typename WeakMapDetails::Utils<K, V>::Type; 89 using Ptr = typename Map::Ptr; 90 91 MOZ_ASSERT(initialized()); 92 93 Map* map = WeakMapDetails::Utils<K, V>::cast(ptr); 94 if (Ptr result = map->lookup(key)) { 95 V value = result->value(); 96 map->remove(result); 97 return value; 98 } 99 return WeakMapDetails::DataType<V>::NullValue(); 100 } 101 102 // 103 // Supported specializations of JS::WeakMap: 104 // 105 106 template class JS_PUBLIC_API JS::WeakMapPtr<JSObject*, JSObject*>; 107 108 #ifdef DEBUG 109 // Nobody's using this at the moment, but we want to make sure it compiles. 110 template class JS_PUBLIC_API JS::WeakMapPtr<JSObject*, JS::Value>; 111 #endif