diff options
Diffstat (limited to 'js/src/vm/WeakMapPtr.cpp')
-rw-r--r-- | js/src/vm/WeakMapPtr.cpp | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/js/src/vm/WeakMapPtr.cpp b/js/src/vm/WeakMapPtr.cpp new file mode 100644 index 000000000..628a08ede --- /dev/null +++ b/js/src/vm/WeakMapPtr.cpp @@ -0,0 +1,110 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=8 sts=4 et sw=4 tw=99: + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "js/WeakMapPtr.h" + +#include "jsweakmap.h" + +// +// Machinery for the externally-linkable JS::WeakMapPtr, which wraps js::WeakMap +// for a few public data types. +// + +using namespace js; + +namespace details { + +template<typename T> +struct DataType +{ +}; + +template<> +struct DataType<JSObject*> +{ + using BarrieredType = HeapPtr<JSObject*>; + using HasherType = MovableCellHasher<BarrieredType>; + static JSObject* NullValue() { return nullptr; } +}; + +template<> +struct DataType<JS::Value> +{ + using BarrieredType = HeapPtr<Value>; + static JS::Value NullValue() { return JS::UndefinedValue(); } +}; + +template <typename K, typename V> +struct Utils +{ + typedef typename DataType<K>::BarrieredType KeyType; + typedef typename DataType<K>::HasherType HasherType; + typedef typename DataType<V>::BarrieredType ValueType; + typedef WeakMap<KeyType, ValueType, HasherType> Type; + typedef Type* PtrType; + static PtrType cast(void* ptr) { return static_cast<PtrType>(ptr); } +}; + +} /* namespace */ + +template <typename K, typename V> +void +JS::WeakMapPtr<K, V>::destroy() +{ + MOZ_ASSERT(initialized()); + js_delete(details::Utils<K, V>::cast(ptr)); + ptr = nullptr; +} + +template <typename K, typename V> +bool +JS::WeakMapPtr<K, V>::init(JSContext* cx) +{ + MOZ_ASSERT(!initialized()); + typename details::Utils<K, V>::PtrType map = cx->runtime()->new_<typename details::Utils<K,V>::Type>(cx); + if (!map || !map->init()) + return false; + ptr = map; + return true; +} + +template <typename K, typename V> +void +JS::WeakMapPtr<K, V>::trace(JSTracer* trc) +{ + MOZ_ASSERT(initialized()); + return details::Utils<K, V>::cast(ptr)->trace(trc); +} + +template <typename K, typename V> +V +JS::WeakMapPtr<K, V>::lookup(const K& key) +{ + MOZ_ASSERT(initialized()); + typename details::Utils<K, V>::Type::Ptr result = details::Utils<K, V>::cast(ptr)->lookup(key); + if (!result) + return details::DataType<V>::NullValue(); + return result->value(); +} + +template <typename K, typename V> +bool +JS::WeakMapPtr<K, V>::put(JSContext* cx, const K& key, const V& value) +{ + MOZ_ASSERT(initialized()); + return details::Utils<K, V>::cast(ptr)->put(key, value); +} + +// +// Supported specializations of JS::WeakMap: +// + +template class JS_PUBLIC_API(JS::WeakMapPtr)<JSObject*, JSObject*>; + +#ifdef DEBUG +// Nobody's using this at the moment, but we want to make sure it compiles. +template class JS_PUBLIC_API(JS::WeakMapPtr)<JSObject*, JS::Value>; +#endif |