Chromium Code Reviews| Index: test/cctest/test-api.cc |
| diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc |
| index dcb11be19d1c84a377b2381a7d3929aff4bbe3a1..26f36b4674ee0cb831c1a112017218b807725ed4 100644 |
| --- a/test/cctest/test-api.cc |
| +++ b/test/cctest/test-api.cc |
| @@ -3193,6 +3193,125 @@ 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.GetInternalField1()); |
|
Erik Corry
2015/03/24 12:16:20
The test only uses the deprecated version, not the
|
| + } |
| +}; |
| +} |
| + |
| + |
| +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)); |
| + { |
| + typename 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())); |
| + { |
| + typename 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(); |