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 nullptr; |
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 nullptr; |
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 nullptr; |
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 nullptr; |
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 nullptr; |
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 nullptr; |
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 nullptr; |
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 nullptr; |
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 |