зеркало из https://github.com/mozilla/gecko-dev.git
Bug 973780 - Expose a wrapper for the internal WeakMap class outside of the engine. r=mccr8,terrence
This commit is contained in:
Родитель
5b8bccef6f
Коммит
b71db74ff5
|
@ -0,0 +1,46 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
#ifndef js_WeakMapPtr_h
|
||||
#define js_WeakMapPtr_h
|
||||
|
||||
#include "jspubtd.h"
|
||||
|
||||
#include "js/TypeDecls.h"
|
||||
|
||||
namespace JS {
|
||||
|
||||
// A wrapper around the internal C++ representation of SpiderMonkey WeakMaps,
|
||||
// usable outside the engine.
|
||||
//
|
||||
// The supported template specializations are enumerated in WeakMapPtr.cpp. If
|
||||
// you want to use this class for a different key/value combination, add it to
|
||||
// the list and the compiler will generate the relevant machinery.
|
||||
template <typename K, typename V>
|
||||
class JS_PUBLIC_API(WeakMapPtr)
|
||||
{
|
||||
public:
|
||||
WeakMapPtr() : ptr(nullptr) {};
|
||||
bool init(JSContext *cx);
|
||||
bool initialized() { return ptr != nullptr; };
|
||||
void destroy();
|
||||
virtual ~WeakMapPtr() { MOZ_ASSERT(!initialized()); }
|
||||
void trace(JSTracer *tracer);
|
||||
|
||||
V lookup(const K &key);
|
||||
bool put(const K &key, const V &value);
|
||||
|
||||
private:
|
||||
void *ptr;
|
||||
|
||||
// WeakMapPtr is neither copyable nor assignable.
|
||||
WeakMapPtr(const WeakMapPtr &wmp) MOZ_DELETE;
|
||||
WeakMapPtr &operator=(const WeakMapPtr &wmp) MOZ_DELETE;
|
||||
};
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
#endif /* js_WeakMapPtr_h */
|
|
@ -37,6 +37,7 @@
|
|||
#include "js/Utility.h"
|
||||
#include "js/Value.h"
|
||||
#include "js/Vector.h"
|
||||
#include "js/WeakMapPtr.h"
|
||||
#include "jsapi-tests/tests.h"
|
||||
|
||||
/*
|
||||
|
|
|
@ -85,7 +85,8 @@ class WeakMapBase {
|
|||
// Trace all delayed weak map bindings. Used by the cycle collector.
|
||||
static void traceAllMappings(WeakMapTracer *tracer);
|
||||
|
||||
void check() { JS_ASSERT(next == WeakMapNotInList); }
|
||||
bool isInList() { return next != WeakMapNotInList; }
|
||||
void check() { JS_ASSERT(!isInList()); }
|
||||
|
||||
// Remove everything from the weak map list for a compartment.
|
||||
static void resetCompartmentWeakMapList(JSCompartment *c);
|
||||
|
|
|
@ -88,6 +88,7 @@ EXPORTS.js += [
|
|||
'../public/Utility.h',
|
||||
'../public/Value.h',
|
||||
'../public/Vector.h',
|
||||
'../public/WeakMapPtr.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
|
@ -189,6 +190,7 @@ UNIFIED_SOURCES += [
|
|||
'vm/TypedArrayObject.cpp',
|
||||
'vm/Unicode.cpp',
|
||||
'vm/Value.cpp',
|
||||
'vm/WeakMapPtr.cpp',
|
||||
'vm/Xdr.cpp',
|
||||
'yarr/PageBlock.cpp',
|
||||
'yarr/YarrCanonicalizeUCS2.cpp',
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
/* -*- 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 {
|
||||
|
||||
template<typename T>
|
||||
struct DataType
|
||||
{
|
||||
};
|
||||
|
||||
template<>
|
||||
struct DataType<JSObject*>
|
||||
{
|
||||
typedef EncapsulatedPtrObject Encapsulated;
|
||||
static JSObject *NullValue() { return nullptr; }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct DataType<JS::Value>
|
||||
{
|
||||
typedef EncapsulatedValue Encapsulated;
|
||||
static JS::Value NullValue() { return JS::UndefinedValue(); }
|
||||
};
|
||||
|
||||
template <typename K, typename V>
|
||||
struct Utils
|
||||
{
|
||||
typedef typename DataType<K>::Encapsulated KeyType;
|
||||
typedef typename DataType<V>::Encapsulated ValueType;
|
||||
typedef WeakMap<KeyType, ValueType> 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());
|
||||
auto map = Utils<K, V>::cast(ptr);
|
||||
// If this destruction happens mid-GC, we might be in the compartment's list
|
||||
// of known live weakmaps. If we are, remove ourselves before deleting.
|
||||
if (map->isInList())
|
||||
WeakMapBase::removeWeakMapFromList(map);
|
||||
map->check();
|
||||
js_delete(map);
|
||||
ptr = nullptr;
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
bool
|
||||
JS::WeakMapPtr<K, V>::init(JSContext *cx)
|
||||
{
|
||||
MOZ_ASSERT(!initialized());
|
||||
typename Utils<K, V>::PtrType map = cx->runtime()->new_<typename 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 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 Utils<K, V>::Type::Ptr result = Utils<K, V>::cast(ptr)->lookup(key);
|
||||
if (!result)
|
||||
return DataType<V>::NullValue();
|
||||
return result->value();
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
bool
|
||||
JS::WeakMapPtr<K, V>::put(const K &key, const V &value)
|
||||
{
|
||||
MOZ_ASSERT(initialized());
|
||||
return Utils<K, V>::cast(ptr)->put(key, value);
|
||||
}
|
||||
|
||||
//
|
||||
// Supported specializations of JS::WeakMap:
|
||||
//
|
||||
|
||||
template class JS::WeakMapPtr<JSObject*, JSObject*>;
|
||||
|
||||
#ifdef DEBUG
|
||||
// Nobody's using this at the moment, but we want to make sure it compiles.
|
||||
template class JS::WeakMapPtr<JSObject*, JS::Value>;
|
||||
#endif
|
Загрузка…
Ссылка в новой задаче