15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "fake_ppapi/fake_var_manager.h" 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "gtest/gtest.h" 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)FakeVarManager::FakeVarManager() : debug(false), next_id_(1) {} 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)FakeVarManager::~FakeVarManager() { 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The ref counts for all vars should be zero. 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (VarMap::const_iterator iter = var_map_.begin(); iter != var_map_.end(); 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ++iter) { 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const FakeVarData& var_data = iter->second; 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0, var_data.ref_count) << "Non-zero refcount on " 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << Describe(var_data); 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)FakeVarData* FakeVarManager::CreateVarData() { 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Id id = next_id_++; 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FakeVarData data; 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) data.id = id; 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) data.ref_count = 1; 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var_map_[id] = data; 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return &var_map_[id]; 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void FakeVarManager::AddRef(PP_Var var) { 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // From ppb_var.h: 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // AddRef() adds a reference to the given var. If this is not a refcounted 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // object, this function will do nothing so you can always call it no matter 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // what the type. 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FakeVarData* var_data = GetVarData(var); 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!var_data) 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_GT(var_data->ref_count, 0) 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << "AddRefing freed " << Describe(*var_data); 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var_data->ref_count++; 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (debug) 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) printf("AddRef of %s [new refcount=%d]\n", 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Describe(*var_data).c_str(), 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var_data->ref_count); 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string FakeVarManager::Describe(const FakeVarData& var_data) { 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::stringstream rtn; 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) switch (var_data.type) { 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case PP_VARTYPE_STRING: 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rtn << "String with id " << var_data.id << 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " with value \"" << var_data.string_value << "\""; 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case PP_VARTYPE_ARRAY: 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rtn << "Array of size " << var_data.array_value.size() 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << " with id " << var_data.id; 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case PP_VARTYPE_ARRAY_BUFFER: 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rtn << "ArrayBuffer of size " << var_data.buffer_value.length 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << " with id " << var_data.id; 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 64f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) case PP_VARTYPE_DICTIONARY: 65f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) rtn << "Dictionary of size " << var_data.dict_value.size() << " with id " 66f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) << var_data.id; 67f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) break; 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) default: 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rtn << "resource of type " << var_data.type 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << " with id " << var_data.id; 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return rtn.str(); 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void FakeVarManager::DestroyVarData(FakeVarData* var_data) { 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Release each PP_Var in the array 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) switch (var_data->type) { 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case PP_VARTYPE_ARRAY: { 810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch FakeArrayType& vector = var_data->array_value; 820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch for (FakeArrayType::iterator it = vector.begin(); 830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch it != vector.end(); ++it) { 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Release(*it); 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) vector.clear(); 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch case PP_VARTYPE_ARRAY_BUFFER: { 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) free(var_data->buffer_value.ptr); 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var_data->buffer_value.ptr = NULL; 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var_data->buffer_value.length = 0; 930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch break; 940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch case PP_VARTYPE_DICTIONARY: { 960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch FakeDictType& dict = var_data->dict_value; 970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch for (FakeDictType::iterator it = dict.begin(); 980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch it != dict.end(); it++) { 990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Release(it->second); 1000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch dict.clear(); 1020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch break; 1030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) default: 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)FakeVarData* FakeVarManager::GetVarData(PP_Var var) { 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) switch (var.type) { 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // These types don't have any var data as their data 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // is stored directly in the var's value union. 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case PP_VARTYPE_UNDEFINED: 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case PP_VARTYPE_NULL: 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case PP_VARTYPE_BOOL: 116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case PP_VARTYPE_INT32: 117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case PP_VARTYPE_DOUBLE: 118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return NULL; 119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) default: 120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VarMap::iterator iter = var_map_.find(var.value.as_id); 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (iter == var_map_.end()) 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return NULL; 1260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch FakeVarData* var_data = &iter->second; 1270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_GT(var_data->ref_count, 0) 1280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch << "Accessing freed " << Describe(*var_data); 1290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return var_data; 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void FakeVarManager::Release(PP_Var var) { 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // From ppb_var.h: 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Release() removes a reference to given var, deleting it if the internal 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // reference count becomes 0. If the given var is not a refcounted object, 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // this function will do nothing so you can always call it no matter what 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // the type. 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FakeVarData* var_data = GetVarData(var); 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!var_data) { 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (debug) 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) printf("Releasing simple var\n"); 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_GT(var_data->ref_count, 0) 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << "Releasing freed " << Describe(*var_data); 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var_data->ref_count--; 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (debug) 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) printf("Released %s [new refcount=%d]\n", 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Describe(*var_data).c_str(), 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var_data->ref_count); 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (var_data->ref_count == 0) 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DestroyVarData(var_data); 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 157