| Index: test/cctest/test-api.cc
|
| diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
|
| index dcb11be19d1c84a377b2381a7d3929aff4bbe3a1..4b0aa3bfaf397b32aa561cd2f72f77476b5087b5 100644
|
| --- a/test/cctest/test-api.cc
|
| +++ b/test/cctest/test-api.cc
|
| @@ -3193,6 +3193,124 @@ TEST(PersistentValueMap) {
|
| }
|
|
|
|
|
| +namespace {
|
| +
|
| +void* IntKeyToVoidPointer(int key) { return reinterpret_cast<void*>(key << 1); }
|
| +
|
| +
|
| +Local<v8::Object> NewObjectForIntKey(
|
| + v8::Isolate* isolate, const v8::Global<v8::ObjectTemplate>& templ,
|
| + int key) {
|
| + auto local = Local<v8::ObjectTemplate>::New(isolate, templ);
|
| + auto obj = local->NewInstance();
|
| + obj->SetAlignedPointerInInternalField(0, IntKeyToVoidPointer(key));
|
| + return obj;
|
| +}
|
| +
|
| +
|
| +template <typename K, typename V>
|
| +class PhantomStdMapTraits : public v8::StdMapTraits<K, V> {
|
| + public:
|
| + typedef typename v8::GlobalValueMap<K, V, PhantomStdMapTraits<K, V>> MapType;
|
| + static const v8::PersistentContainerCallbackType kCallbackType =
|
| + v8::kWeakWithInternalFields;
|
| + struct WeakCallbackDataType {
|
| + MapType* map;
|
| + K key;
|
| + };
|
| + static WeakCallbackDataType* WeakCallbackParameter(MapType* map, const K& key,
|
| + Local<V> value) {
|
| + WeakCallbackDataType* data = new WeakCallbackDataType;
|
| + data->map = map;
|
| + data->key = key;
|
| + return data;
|
| + }
|
| + static MapType* MapFromWeakCallbackInfo(
|
| + const v8::WeakCallbackInfo<WeakCallbackDataType>& data) {
|
| + return data.GetParameter()->map;
|
| + }
|
| + static K KeyFromWeakCallbackInfo(
|
| + const v8::WeakCallbackInfo<WeakCallbackDataType>& data) {
|
| + return data.GetParameter()->key;
|
| + }
|
| + static void DisposeCallbackData(WeakCallbackDataType* data) { delete data; }
|
| + static void Dispose(v8::Isolate* isolate, v8::Global<V> value, K key) {
|
| + CHECK_EQ(IntKeyToVoidPointer(key),
|
| + v8::Object::GetAlignedPointerFromInternalField(value, 0));
|
| + }
|
| + static void DisposeWeak(
|
| + v8::Isolate* isolate,
|
| + const v8::WeakCallbackInfo<WeakCallbackDataType>& info, K key) {
|
| + CHECK_EQ(IntKeyToVoidPointer(key), info.GetInternalField(0));
|
| + }
|
| +};
|
| +}
|
| +
|
| +
|
| +TEST(GlobalValueMap) {
|
| + typedef v8::GlobalValueMap<int, v8::Object,
|
| + PhantomStdMapTraits<int, v8::Object>> Map;
|
| + LocalContext env;
|
| + v8::Isolate* isolate = env->GetIsolate();
|
| + v8::Global<ObjectTemplate> templ;
|
| + {
|
| + HandleScope scope(isolate);
|
| + auto t = ObjectTemplate::New(isolate);
|
| + t->SetInternalFieldCount(1);
|
| + templ.Reset(isolate, t);
|
| + }
|
| + Map map(isolate);
|
| + v8::internal::GlobalHandles* global_handles =
|
| + reinterpret_cast<v8::internal::Isolate*>(isolate)->global_handles();
|
| + int initial_handle_count = global_handles->global_handles_count();
|
| + CHECK_EQ(0, static_cast<int>(map.Size()));
|
| + {
|
| + HandleScope scope(isolate);
|
| + Local<v8::Object> obj = map.Get(7);
|
| + CHECK(obj.IsEmpty());
|
| + Local<v8::Object> expected = v8::Object::New(isolate);
|
| + map.Set(7, expected);
|
| + CHECK_EQ(1, static_cast<int>(map.Size()));
|
| + obj = map.Get(7);
|
| + CHECK(expected->Equals(obj));
|
| + {
|
| + Map::PersistentValueReference ref = map.GetReference(7);
|
| + CHECK(expected->Equals(ref.NewLocal(isolate)));
|
| + }
|
| + v8::Global<v8::Object> removed = map.Remove(7);
|
| + CHECK_EQ(0, static_cast<int>(map.Size()));
|
| + CHECK(expected == removed);
|
| + removed = map.Remove(7);
|
| + CHECK(removed.IsEmpty());
|
| + map.Set(8, expected);
|
| + CHECK_EQ(1, static_cast<int>(map.Size()));
|
| + map.Set(8, expected);
|
| + CHECK_EQ(1, static_cast<int>(map.Size()));
|
| + {
|
| + Map::PersistentValueReference ref;
|
| + Local<v8::Object> expected2 = NewObjectForIntKey(isolate, templ, 8);
|
| + removed = map.Set(8, v8::Global<v8::Object>(isolate, expected2), &ref);
|
| + CHECK_EQ(1, static_cast<int>(map.Size()));
|
| + CHECK(expected == removed);
|
| + CHECK(expected2->Equals(ref.NewLocal(isolate)));
|
| + }
|
| + }
|
| + CHECK_EQ(initial_handle_count + 1, global_handles->global_handles_count());
|
| + CcTest::i_isolate()->heap()->CollectAllGarbage(
|
| + i::Heap::kAbortIncrementalMarkingMask);
|
| + CHECK_EQ(0, static_cast<int>(map.Size()));
|
| + CHECK_EQ(initial_handle_count, global_handles->global_handles_count());
|
| + {
|
| + HandleScope scope(isolate);
|
| + Local<v8::Object> value = NewObjectForIntKey(isolate, templ, 9);
|
| + map.Set(9, value);
|
| + map.Clear();
|
| + }
|
| + CHECK_EQ(0, static_cast<int>(map.Size()));
|
| + CHECK_EQ(initial_handle_count, global_handles->global_handles_count());
|
| +}
|
| +
|
| +
|
| TEST(PersistentValueVector) {
|
| LocalContext env;
|
| v8::Isolate* isolate = env->GetIsolate();
|
|
|