Revision: 20341
Author: [email protected]
Date: Mon Mar 31 10:03:20 2014 UTC
Log: Implement PersistentValueVector, analogous to PersistentValueMap.
BUG=
[email protected]
Review URL: https://codereview.chromium.org/216973002
Patch from Daniel Vogelheim <[email protected]>.
http://code.google.com/p/v8/source/detail?r=20341
Modified:
/branches/bleeding_edge/include/v8-util.h
/branches/bleeding_edge/include/v8.h
/branches/bleeding_edge/test/cctest/test-api.cc
=======================================
--- /branches/bleeding_edge/include/v8-util.h Fri Mar 28 09:35:50 2014 UTC
+++ /branches/bleeding_edge/include/v8-util.h Mon Mar 31 10:03:20 2014 UTC
@@ -30,6 +30,7 @@
#include "v8.h"
#include <map>
+#include <vector>
/**
* Support for Persistent containers.
@@ -386,6 +387,123 @@
: PersistentValueMap<K, V, Traits>(isolate) {}
};
+
+class DefaultPersistentValueVectorTraits {
+ public:
+ typedef std::vector<PersistentContainerValue> Impl;
+
+ static void Append(Impl* impl, PersistentContainerValue value) {
+ impl->push_back(value);
+ }
+ static bool IsEmpty(const Impl* impl) {
+ return impl->empty();
+ }
+ static size_t Size(const Impl* impl) {
+ return impl->size();
+ }
+ static PersistentContainerValue Get(const Impl* impl, size_t i) {
+ return (i < impl->size()) ? impl->at(i) : kPersistentContainerNotFound;
+ }
+ static void ReserveCapacity(Impl* impl, size_t capacity) {
+ impl->reserve(capacity);
+ }
+ static void Clear(Impl* impl) {
+ impl->clear();
+ }
+};
+
+
+/**
+ * A vector wrapper that safely stores UniquePersistent values.
+ * C++11 embedders don't need this class, as they can use UniquePersistent
+ * directly in std containers.
+ *
+ * This class relies on a backing vector implementation, whose type and
methods
+ * are described by the Traits class. The backing map will handle values
of type
+ * PersistentContainerValue, with all conversion into and out of V8
+ * handles being transparently handled by this class.
+ */
+template<typename V, typename Traits = DefaultPersistentValueVectorTraits>
+class PersistentValueVector {
+ public:
+ explicit PersistentValueVector(Isolate* isolate) : isolate_(isolate) { }
+
+ ~PersistentValueVector() {
+ Clear();
+ }
+
+ /**
+ * Append a value to the vector.
+ */
+ void Append(Local<V> value) {
+ UniquePersistent<V> persistent(isolate_, value);
+ Traits::Append(&impl_, ClearAndLeak(&persistent));
+ }
+
+ /**
+ * Append a persistent's value to the vector.
+ */
+ void Append(UniquePersistent<V> persistent) {
+ Traits::Append(&impl_, ClearAndLeak(&persistent));
+ };
+
+ /**
+ * Are there any values in the vector?
+ */
+ bool IsEmpty() const {
+ return Traits::IsEmpty(&impl_);
+ }
+
+ /**
+ * How many elements are in the vector?
+ */
+ size_t Size() const {
+ return Traits::Size(&impl_);
+ }
+
+ /**
+ * Retrieve the i-th value in the vector.
+ */
+ Local<V> Get(size_t index) const {
+ return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, index)));
+ }
+
+ /**
+ * Remove all elements from the vector.
+ */
+ void Clear() {
+ size_t length = Traits::Size(&impl_);
+ for (size_t i = 0; i < length; i++) {
+ UniquePersistent<V> p;
+ p.val_ = FromVal(Traits::Get(&impl_, i));
+ }
+ Traits::Clear(&impl_);
+ }
+
+ /**
+ * Reserve capacity in the vector.
+ * (Efficiency gains depend on the backing implementation.)
+ */
+ void ReserveCapacity(size_t capacity) {
+ Traits::ReserveCapacity(&impl_, capacity);
+ }
+
+ private:
+ static PersistentContainerValue ClearAndLeak(
+ UniquePersistent<V>* persistent) {
+ V* v = persistent->val_;
+ persistent->val_ = 0;
+ return reinterpret_cast<PersistentContainerValue>(v);
+ }
+
+ static V* FromVal(PersistentContainerValue v) {
+ return reinterpret_cast<V*>(v);
+ }
+
+ Isolate* isolate_;
+ typename Traits::Impl impl_;
+};
+
} // namespace v8
#endif // V8_UTIL_H_
=======================================
--- /branches/bleeding_edge/include/v8.h Wed Mar 26 12:50:13 2014 UTC
+++ /branches/bleeding_edge/include/v8.h Mon Mar 31 10:03:20 2014 UTC
@@ -129,6 +129,7 @@
class M = NonCopyablePersistentTraits<T> > class Persistent;
template<class T> class UniquePersistent;
template<class K, class V, class T> class PersistentValueMap;
+template<class V, class T> class PersistentValueVector;
template<class T, class P> class WeakCallbackObject;
class FunctionTemplate;
class ObjectTemplate;
@@ -417,6 +418,7 @@
friend class HandleScope;
friend class EscapableHandleScope;
template<class F1, class F2, class F3> friend class PersistentValueMap;
+ template<class F1, class F2> friend class PersistentValueVector;
V8_INLINE static Local<T> New(Isolate* isolate, T* that);
};
@@ -586,6 +588,7 @@
template<class F> friend class PersistentBase;
template<class F> friend class ReturnValue;
template<class F1, class F2, class F3> friend class PersistentValueMap;
+ template<class F1, class F2> friend class PersistentValueVector;
friend class Object;
explicit V8_INLINE PersistentBase(T* val) : val_(val) {}
=======================================
--- /branches/bleeding_edge/test/cctest/test-api.cc Fri Mar 28 15:25:24
2014 UTC
+++ /branches/bleeding_edge/test/cctest/test-api.cc Mon Mar 31 10:03:20
2014 UTC
@@ -3590,6 +3590,49 @@
WeakStdMapTraits<int, v8::Object> > WeakPersistentValueMap;
TestPersistentValueMap<WeakPersistentValueMap>();
}
+
+
+TEST(PersistentValueVector) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::internal::GlobalHandles* global_handles =
+ reinterpret_cast<v8::internal::Isolate*>(isolate)->global_handles();
+ int handle_count = global_handles->global_handles_count();
+ HandleScope scope(isolate);
+
+ v8::PersistentValueVector<v8::Object> vector(isolate);
+
+ Local<v8::Object> obj1 = v8::Object::New(isolate);
+ Local<v8::Object> obj2 = v8::Object::New(isolate);
+ v8::UniquePersistent<v8::Object> obj3(isolate, v8::Object::New(isolate));
+
+ CHECK(vector.IsEmpty());
+ CHECK_EQ(0, static_cast<int>(vector.Size()));
+
+ vector.ReserveCapacity(3);
+ CHECK(vector.IsEmpty());
+
+ vector.Append(obj1);
+ vector.Append(obj2);
+ vector.Append(obj1);
+ vector.Append(obj3.Pass());
+ vector.Append(obj1);
+
+ CHECK(!vector.IsEmpty());
+ CHECK_EQ(5, static_cast<int>(vector.Size()));
+ CHECK(obj3.IsEmpty());
+ CHECK_EQ(obj1, vector.Get(0));
+ CHECK_EQ(obj1, vector.Get(2));
+ CHECK_EQ(obj1, vector.Get(4));
+ CHECK_EQ(obj2, vector.Get(1));
+
+ CHECK_EQ(5 + handle_count, global_handles->global_handles_count());
+
+ vector.Clear();
+ CHECK(vector.IsEmpty());
+ CHECK_EQ(0, static_cast<int>(vector.Size()));
+ CHECK_EQ(handle_count, global_handles->global_handles_count());
+}
THREADED_TEST(GlobalHandleUpcast) {
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.