Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ppapi/proxy/raw_var_data.h" | 5 #include "ppapi/proxy/raw_var_data.h" |
| 6 | 6 |
| 7 #include <stack> | 7 #include <stack> |
| 8 | 8 |
| 9 #include "base/containers/hash_tables.h" | 9 #include "base/containers/hash_tables.h" |
| 10 #include "base/memory/ptr_util.h" | |
| 10 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
| 11 #include "ipc/ipc_message.h" | 12 #include "ipc/ipc_message.h" |
| 12 #include "ppapi/proxy/ppapi_param_traits.h" | 13 #include "ppapi/proxy/ppapi_param_traits.h" |
| 13 #include "ppapi/shared_impl/array_var.h" | 14 #include "ppapi/shared_impl/array_var.h" |
| 14 #include "ppapi/shared_impl/dictionary_var.h" | 15 #include "ppapi/shared_impl/dictionary_var.h" |
| 15 #include "ppapi/shared_impl/ppapi_globals.h" | 16 #include "ppapi/shared_impl/ppapi_globals.h" |
| 16 #include "ppapi/shared_impl/resource_var.h" | 17 #include "ppapi/shared_impl/resource_var.h" |
| 17 #include "ppapi/shared_impl/scoped_pp_var.h" | 18 #include "ppapi/shared_impl/scoped_pp_var.h" |
| 18 #include "ppapi/shared_impl/var.h" | 19 #include "ppapi/shared_impl/var.h" |
| 19 #include "ppapi/shared_impl/var_tracker.h" | 20 #include "ppapi/shared_impl/var_tracker.h" |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 37 PP_Var var; | 38 PP_Var var; |
| 38 size_t data_index; | 39 size_t data_index; |
| 39 }; | 40 }; |
| 40 | 41 |
| 41 // For a given PP_Var, returns the RawVarData associated with it, or creates a | 42 // For a given PP_Var, returns the RawVarData associated with it, or creates a |
| 42 // new one if there is no existing one. The data is appended to |data| if it | 43 // new one if there is no existing one. The data is appended to |data| if it |
| 43 // is newly created. The index into |data| pointing to the result is returned. | 44 // is newly created. The index into |data| pointing to the result is returned. |
| 44 // |visited_map| keeps track of RawVarDatas that have already been created. | 45 // |visited_map| keeps track of RawVarDatas that have already been created. |
| 45 size_t GetOrCreateRawVarData(const PP_Var& var, | 46 size_t GetOrCreateRawVarData(const PP_Var& var, |
| 46 base::hash_map<int64_t, size_t>* visited_map, | 47 base::hash_map<int64_t, size_t>* visited_map, |
| 47 std::vector<scoped_ptr<RawVarData>>* data) { | 48 std::vector<std::unique_ptr<RawVarData>>* data) { |
| 48 if (VarTracker::IsVarTypeRefcounted(var.type)) { | 49 if (VarTracker::IsVarTypeRefcounted(var.type)) { |
| 49 base::hash_map<int64_t, size_t>::iterator it = visited_map->find( | 50 base::hash_map<int64_t, size_t>::iterator it = visited_map->find( |
| 50 var.value.as_id); | 51 var.value.as_id); |
| 51 if (it != visited_map->end()) { | 52 if (it != visited_map->end()) { |
| 52 return it->second; | 53 return it->second; |
| 53 } else { | 54 } else { |
| 54 data->push_back(make_scoped_ptr(RawVarData::Create(var.type))); | 55 data->push_back(base::WrapUnique(RawVarData::Create(var.type))); |
| 55 (*visited_map)[var.value.as_id] = data->size() - 1; | 56 (*visited_map)[var.value.as_id] = data->size() - 1; |
| 56 } | 57 } |
| 57 } else { | 58 } else { |
| 58 data->push_back(make_scoped_ptr(RawVarData::Create(var.type))); | 59 data->push_back(base::WrapUnique(RawVarData::Create(var.type))); |
| 59 } | 60 } |
| 60 return data->size() - 1; | 61 return data->size() - 1; |
| 61 } | 62 } |
| 62 | 63 |
| 63 bool CanHaveChildren(PP_Var var) { | 64 bool CanHaveChildren(PP_Var var) { |
| 64 return var.type == PP_VARTYPE_ARRAY || var.type == PP_VARTYPE_DICTIONARY; | 65 return var.type == PP_VARTYPE_ARRAY || var.type == PP_VARTYPE_DICTIONARY; |
| 65 } | 66 } |
| 66 | 67 |
| 67 } // namespace | 68 } // namespace |
| 68 | 69 |
| 69 // RawVarDataGraph ------------------------------------------------------------ | 70 // RawVarDataGraph ------------------------------------------------------------ |
| 70 RawVarDataGraph::RawVarDataGraph() { | 71 RawVarDataGraph::RawVarDataGraph() { |
| 71 } | 72 } |
| 72 | 73 |
| 73 RawVarDataGraph::~RawVarDataGraph() { | 74 RawVarDataGraph::~RawVarDataGraph() { |
| 74 } | 75 } |
| 75 | 76 |
| 76 // This function uses a stack-based DFS search to traverse the var graph. Each | 77 // This function uses a stack-based DFS search to traverse the var graph. Each |
| 77 // iteration, the top node on the stack examined. If the node has not been | 78 // iteration, the top node on the stack examined. If the node has not been |
| 78 // visited yet (i.e. !initialized()) then it is added to the list of | 79 // visited yet (i.e. !initialized()) then it is added to the list of |
| 79 // |parent_ids| which contains all of the nodes on the path from the start node | 80 // |parent_ids| which contains all of the nodes on the path from the start node |
| 80 // to the current node. Each of that nodes children are examined. If they appear | 81 // to the current node. Each of that nodes children are examined. If they appear |
| 81 // in the list of |parent_ids| it means we have a cycle and we return NULL. | 82 // in the list of |parent_ids| it means we have a cycle and we return NULL. |
| 82 // Otherwise, if they haven't been visited yet we add them to the stack, If the | 83 // Otherwise, if they haven't been visited yet we add them to the stack, If the |
| 83 // node at the top of the stack has already been visited, then we pop it off the | 84 // node at the top of the stack has already been visited, then we pop it off the |
| 84 // stack and erase it from |parent_ids|. | 85 // stack and erase it from |parent_ids|. |
| 85 // static | 86 // static |
| 86 scoped_ptr<RawVarDataGraph> RawVarDataGraph::Create(const PP_Var& var, | 87 std::unique_ptr<RawVarDataGraph> RawVarDataGraph::Create(const PP_Var& var, |
| 87 PP_Instance instance) { | 88 PP_Instance instance) { |
| 88 scoped_ptr<RawVarDataGraph> graph(new RawVarDataGraph); | 89 std::unique_ptr<RawVarDataGraph> graph(new RawVarDataGraph); |
| 89 // Map of |var.value.as_id| to a RawVarData index in RawVarDataGraph. | 90 // Map of |var.value.as_id| to a RawVarData index in RawVarDataGraph. |
| 90 base::hash_map<int64_t, size_t> visited_map; | 91 base::hash_map<int64_t, size_t> visited_map; |
| 91 base::hash_set<int64_t> parent_ids; | 92 base::hash_set<int64_t> parent_ids; |
| 92 | 93 |
| 93 std::stack<StackEntry> stack; | 94 std::stack<StackEntry> stack; |
| 94 stack.push(StackEntry(var, GetOrCreateRawVarData(var, &visited_map, | 95 stack.push(StackEntry(var, GetOrCreateRawVarData(var, &visited_map, |
| 95 &graph->data_))); | 96 &graph->data_))); |
| 96 | 97 |
| 97 while (!stack.empty()) { | 98 while (!stack.empty()) { |
| 98 PP_Var current_var = stack.top().var; | 99 PP_Var current_var = stack.top().var; |
| 99 RawVarData* current_var_data = graph->data_[stack.top().data_index].get(); | 100 RawVarData* current_var_data = graph->data_[stack.top().data_index].get(); |
| 100 | 101 |
| 101 if (current_var_data->initialized()) { | 102 if (current_var_data->initialized()) { |
| 102 stack.pop(); | 103 stack.pop(); |
| 103 if (CanHaveChildren(current_var)) | 104 if (CanHaveChildren(current_var)) |
| 104 parent_ids.erase(current_var.value.as_id); | 105 parent_ids.erase(current_var.value.as_id); |
| 105 continue; | 106 continue; |
| 106 } | 107 } |
| 107 | 108 |
| 108 if (CanHaveChildren(current_var)) | 109 if (CanHaveChildren(current_var)) |
| 109 parent_ids.insert(current_var.value.as_id); | 110 parent_ids.insert(current_var.value.as_id); |
| 110 if (!current_var_data->Init(current_var, instance)) { | 111 if (!current_var_data->Init(current_var, instance)) { |
| 111 NOTREACHED(); | 112 NOTREACHED(); |
| 112 return scoped_ptr<RawVarDataGraph>(); | 113 return std::unique_ptr<RawVarDataGraph>(); |
|
piman
2016/04/06 21:25:03
nit: nullptr, here and below?
dcheng
2016/04/06 21:29:05
Done.
| |
| 113 } | 114 } |
| 114 | 115 |
| 115 // Add child nodes to the stack. | 116 // Add child nodes to the stack. |
| 116 if (current_var.type == PP_VARTYPE_ARRAY) { | 117 if (current_var.type == PP_VARTYPE_ARRAY) { |
| 117 ArrayVar* array_var = ArrayVar::FromPPVar(current_var); | 118 ArrayVar* array_var = ArrayVar::FromPPVar(current_var); |
| 118 if (!array_var) { | 119 if (!array_var) { |
| 119 NOTREACHED(); | 120 NOTREACHED(); |
| 120 return scoped_ptr<RawVarDataGraph>(); | 121 return std::unique_ptr<RawVarDataGraph>(); |
| 121 } | 122 } |
| 122 for (ArrayVar::ElementVector::const_iterator iter = | 123 for (ArrayVar::ElementVector::const_iterator iter = |
| 123 array_var->elements().begin(); | 124 array_var->elements().begin(); |
| 124 iter != array_var->elements().end(); | 125 iter != array_var->elements().end(); |
| 125 ++iter) { | 126 ++iter) { |
| 126 const PP_Var& child = iter->get(); | 127 const PP_Var& child = iter->get(); |
| 127 // If a child of this node is already in parent_ids, we have a cycle so | 128 // If a child of this node is already in parent_ids, we have a cycle so |
| 128 // we just return null. | 129 // we just return null. |
| 129 if (CanHaveChildren(child) && parent_ids.count(child.value.as_id) != 0) | 130 if (CanHaveChildren(child) && parent_ids.count(child.value.as_id) != 0) |
| 130 return scoped_ptr<RawVarDataGraph>(); | 131 return std::unique_ptr<RawVarDataGraph>(); |
| 131 size_t child_id = GetOrCreateRawVarData(child, &visited_map, | 132 size_t child_id = GetOrCreateRawVarData(child, &visited_map, |
| 132 &graph->data_); | 133 &graph->data_); |
| 133 static_cast<ArrayRawVarData*>(current_var_data)->AddChild(child_id); | 134 static_cast<ArrayRawVarData*>(current_var_data)->AddChild(child_id); |
| 134 if (!graph->data_[child_id]->initialized()) | 135 if (!graph->data_[child_id]->initialized()) |
| 135 stack.push(StackEntry(child, child_id)); | 136 stack.push(StackEntry(child, child_id)); |
| 136 } | 137 } |
| 137 } else if (current_var.type == PP_VARTYPE_DICTIONARY) { | 138 } else if (current_var.type == PP_VARTYPE_DICTIONARY) { |
| 138 DictionaryVar* dict_var = DictionaryVar::FromPPVar(current_var); | 139 DictionaryVar* dict_var = DictionaryVar::FromPPVar(current_var); |
| 139 if (!dict_var) { | 140 if (!dict_var) { |
| 140 NOTREACHED(); | 141 NOTREACHED(); |
| 141 return scoped_ptr<RawVarDataGraph>(); | 142 return std::unique_ptr<RawVarDataGraph>(); |
| 142 } | 143 } |
| 143 for (DictionaryVar::KeyValueMap::const_iterator iter = | 144 for (DictionaryVar::KeyValueMap::const_iterator iter = |
| 144 dict_var->key_value_map().begin(); | 145 dict_var->key_value_map().begin(); |
| 145 iter != dict_var->key_value_map().end(); | 146 iter != dict_var->key_value_map().end(); |
| 146 ++iter) { | 147 ++iter) { |
| 147 const PP_Var& child = iter->second.get(); | 148 const PP_Var& child = iter->second.get(); |
| 148 if (CanHaveChildren(child) && parent_ids.count(child.value.as_id) != 0) | 149 if (CanHaveChildren(child) && parent_ids.count(child.value.as_id) != 0) |
| 149 return scoped_ptr<RawVarDataGraph>(); | 150 return std::unique_ptr<RawVarDataGraph>(); |
| 150 size_t child_id = GetOrCreateRawVarData(child, &visited_map, | 151 size_t child_id = GetOrCreateRawVarData(child, &visited_map, |
| 151 &graph->data_); | 152 &graph->data_); |
| 152 static_cast<DictionaryRawVarData*>( | 153 static_cast<DictionaryRawVarData*>( |
| 153 current_var_data)->AddChild(iter->first, child_id); | 154 current_var_data)->AddChild(iter->first, child_id); |
| 154 if (!graph->data_[child_id]->initialized()) | 155 if (!graph->data_[child_id]->initialized()) |
| 155 stack.push(StackEntry(child, child_id)); | 156 stack.push(StackEntry(child, child_id)); |
| 156 } | 157 } |
| 157 } | 158 } |
| 158 } | 159 } |
| 159 return graph; | 160 return graph; |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 177 const HandleWriter& handle_writer) { | 178 const HandleWriter& handle_writer) { |
| 178 // Write the size, followed by each node in the graph. | 179 // Write the size, followed by each node in the graph. |
| 179 m->WriteUInt32(static_cast<uint32_t>(data_.size())); | 180 m->WriteUInt32(static_cast<uint32_t>(data_.size())); |
| 180 for (size_t i = 0; i < data_.size(); ++i) { | 181 for (size_t i = 0; i < data_.size(); ++i) { |
| 181 m->WriteInt(data_[i]->Type()); | 182 m->WriteInt(data_[i]->Type()); |
| 182 data_[i]->Write(m, handle_writer); | 183 data_[i]->Write(m, handle_writer); |
| 183 } | 184 } |
| 184 } | 185 } |
| 185 | 186 |
| 186 // static | 187 // static |
| 187 scoped_ptr<RawVarDataGraph> RawVarDataGraph::Read(const base::Pickle* m, | 188 std::unique_ptr<RawVarDataGraph> RawVarDataGraph::Read( |
| 188 base::PickleIterator* iter) { | 189 const base::Pickle* m, |
| 189 scoped_ptr<RawVarDataGraph> result(new RawVarDataGraph); | 190 base::PickleIterator* iter) { |
| 191 std::unique_ptr<RawVarDataGraph> result(new RawVarDataGraph); | |
| 190 uint32_t size = 0; | 192 uint32_t size = 0; |
| 191 if (!iter->ReadUInt32(&size)) | 193 if (!iter->ReadUInt32(&size)) |
| 192 return scoped_ptr<RawVarDataGraph>(); | 194 return std::unique_ptr<RawVarDataGraph>(); |
|
piman
2016/04/06 21:25:03
(also here and below)
dcheng
2016/04/06 21:29:05
FWIW, I'm cautiously optimistic that clang-tidy wi
| |
| 193 for (uint32_t i = 0; i < size; ++i) { | 195 for (uint32_t i = 0; i < size; ++i) { |
| 194 int32_t type; | 196 int32_t type; |
| 195 if (!iter->ReadInt(&type)) | 197 if (!iter->ReadInt(&type)) |
| 196 return scoped_ptr<RawVarDataGraph>(); | 198 return std::unique_ptr<RawVarDataGraph>(); |
| 197 PP_VarType var_type = static_cast<PP_VarType>(type); | 199 PP_VarType var_type = static_cast<PP_VarType>(type); |
| 198 result->data_.push_back(make_scoped_ptr(RawVarData::Create(var_type))); | 200 result->data_.push_back(base::WrapUnique(RawVarData::Create(var_type))); |
| 199 if (!result->data_.back()->Read(var_type, m, iter)) | 201 if (!result->data_.back()->Read(var_type, m, iter)) |
| 200 return scoped_ptr<RawVarDataGraph>(); | 202 return std::unique_ptr<RawVarDataGraph>(); |
| 201 } | 203 } |
| 202 return result; | 204 return result; |
| 203 } | 205 } |
| 204 | 206 |
| 205 std::vector<SerializedHandle*> RawVarDataGraph::GetHandles() { | 207 std::vector<SerializedHandle*> RawVarDataGraph::GetHandles() { |
| 206 std::vector<SerializedHandle*> result; | 208 std::vector<SerializedHandle*> result; |
| 207 for (size_t i = 0; i < data_.size(); ++i) { | 209 for (size_t i = 0; i < data_.size(); ++i) { |
| 208 SerializedHandle* handle = data_[i]->GetHandle(); | 210 SerializedHandle* handle = data_[i]->GetHandle(); |
| 209 if (handle) | 211 if (handle) |
| 210 result.push_back(handle); | 212 result.push_back(handle); |
| (...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 738 if (!IPC::ReadParam(m, iter, creation_message_.get())) | 740 if (!IPC::ReadParam(m, iter, creation_message_.get())) |
| 739 return false; | 741 return false; |
| 740 } else { | 742 } else { |
| 741 creation_message_.reset(); | 743 creation_message_.reset(); |
| 742 } | 744 } |
| 743 return true; | 745 return true; |
| 744 } | 746 } |
| 745 | 747 |
| 746 } // namespace proxy | 748 } // namespace proxy |
| 747 } // namespace ppapi | 749 } // namespace ppapi |
| OLD | NEW |