1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/vm/WeakMapPtr.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,129 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * vim: set ts=8 sts=4 et sw=4 tw=99: 1.6 + * This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "js/WeakMapPtr.h" 1.11 + 1.12 +#include "jsweakmap.h" 1.13 + 1.14 +// 1.15 +// Machinery for the externally-linkable JS::WeakMapPtr, which wraps js::WeakMap 1.16 +// for a few public data types. 1.17 +// 1.18 + 1.19 +using namespace js; 1.20 + 1.21 +namespace { 1.22 + 1.23 +template<typename T> 1.24 +struct DataType 1.25 +{ 1.26 +}; 1.27 + 1.28 +template<> 1.29 +struct DataType<JSObject*> 1.30 +{ 1.31 + typedef EncapsulatedPtrObject Encapsulated; 1.32 + static JSObject *NullValue() { return nullptr; } 1.33 +}; 1.34 + 1.35 +template<> 1.36 +struct DataType<JS::Value> 1.37 +{ 1.38 + typedef EncapsulatedValue Encapsulated; 1.39 + static JS::Value NullValue() { return JS::UndefinedValue(); } 1.40 +}; 1.41 + 1.42 +template <typename K, typename V> 1.43 +struct Utils 1.44 +{ 1.45 + typedef typename DataType<K>::Encapsulated KeyType; 1.46 + typedef typename DataType<V>::Encapsulated ValueType; 1.47 + typedef WeakMap<KeyType, ValueType> Type; 1.48 + typedef Type* PtrType; 1.49 + static PtrType cast(void *ptr) { return static_cast<PtrType>(ptr); } 1.50 +}; 1.51 + 1.52 +} /* namespace */ 1.53 + 1.54 +template <typename K, typename V> 1.55 +void 1.56 +JS::WeakMapPtr<K, V>::destroy() 1.57 +{ 1.58 + MOZ_ASSERT(initialized()); 1.59 + auto map = Utils<K, V>::cast(ptr); 1.60 + // If this destruction happens mid-GC, we might be in the compartment's list 1.61 + // of known live weakmaps. If we are, remove ourselves before deleting. 1.62 + if (map->isInList()) 1.63 + WeakMapBase::removeWeakMapFromList(map); 1.64 + map->check(); 1.65 + js_delete(map); 1.66 + ptr = nullptr; 1.67 +} 1.68 + 1.69 +template <typename K, typename V> 1.70 +bool 1.71 +JS::WeakMapPtr<K, V>::init(JSContext *cx) 1.72 +{ 1.73 + MOZ_ASSERT(!initialized()); 1.74 + typename Utils<K, V>::PtrType map = cx->runtime()->new_<typename Utils<K,V>::Type>(cx); 1.75 + if (!map || !map->init()) 1.76 + return false; 1.77 + ptr = map; 1.78 + return true; 1.79 +} 1.80 + 1.81 +template <typename K, typename V> 1.82 +void 1.83 +JS::WeakMapPtr<K, V>::trace(JSTracer *trc) 1.84 +{ 1.85 + MOZ_ASSERT(initialized()); 1.86 + return Utils<K, V>::cast(ptr)->trace(trc); 1.87 +} 1.88 + 1.89 +template <typename K, typename V> 1.90 +V 1.91 +JS::WeakMapPtr<K, V>::lookup(const K &key) 1.92 +{ 1.93 + MOZ_ASSERT(initialized()); 1.94 + typename Utils<K, V>::Type::Ptr result = Utils<K, V>::cast(ptr)->lookup(key); 1.95 + if (!result) 1.96 + return DataType<V>::NullValue(); 1.97 + return result->value(); 1.98 +} 1.99 + 1.100 +template <typename K, typename V> 1.101 +/* static */ void 1.102 +JS::WeakMapPtr<K, V>::keyMarkCallback(JSTracer *trc, K key, void *data) 1.103 +{ 1.104 + auto map = static_cast< JS::WeakMapPtr<K, V>* >(data); 1.105 + K prior = key; 1.106 + JS_CallObjectTracer(trc, &key, "WeakMapPtr key"); 1.107 + return Utils<K, V>::cast(map->ptr)->rekeyIfMoved(prior, key); 1.108 +} 1.109 + 1.110 +template <typename K, typename V> 1.111 +bool 1.112 +JS::WeakMapPtr<K, V>::put(JSContext *cx, const K &key, const V &value) 1.113 +{ 1.114 + MOZ_ASSERT(initialized()); 1.115 + if (!Utils<K, V>::cast(ptr)->put(key, value)) 1.116 + return false; 1.117 + JS_StoreObjectPostBarrierCallback(cx, keyMarkCallback, key, this); 1.118 + // Values do not need to be barriered because only put() is supported, 1.119 + // which is always an initializing write. 1.120 + return true; 1.121 +} 1.122 + 1.123 +// 1.124 +// Supported specializations of JS::WeakMap: 1.125 +// 1.126 + 1.127 +template class JS::WeakMapPtr<JSObject*, JSObject*>; 1.128 + 1.129 +#ifdef DEBUG 1.130 +// Nobody's using this at the moment, but we want to make sure it compiles. 1.131 +template class JS::WeakMapPtr<JSObject*, JS::Value>; 1.132 +#endif