OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "webkit/plugins/ppapi/v8_var_converter.h" | 5 #include "webkit/plugins/ppapi/v8_var_converter.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/memory/ref_counted.h" | 10 #include "base/memory/ref_counted.h" |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 isolate, v8::Context::New(isolate, NULL, global)); | 147 isolate, v8::Context::New(isolate, NULL, global)); |
148 } | 148 } |
149 virtual void TearDown() { | 149 virtual void TearDown() { |
150 context_.Dispose(context_->GetIsolate()); | 150 context_.Dispose(context_->GetIsolate()); |
151 ASSERT_TRUE(PpapiGlobals::Get()->GetVarTracker()->GetLiveVars().empty()); | 151 ASSERT_TRUE(PpapiGlobals::Get()->GetVarTracker()->GetLiveVars().empty()); |
152 ProxyLock::Release(); | 152 ProxyLock::Release(); |
153 } | 153 } |
154 | 154 |
155 protected: | 155 protected: |
156 bool RoundTrip(const PP_Var& var, PP_Var* result) { | 156 bool RoundTrip(const PP_Var& var, PP_Var* result) { |
157 V8VarConverter converter; | |
158 v8::Context::Scope context_scope(context_); | 157 v8::Context::Scope context_scope(context_); |
159 v8::HandleScope handle_scope; | 158 v8::HandleScope handle_scope; |
160 v8::Handle<v8::Value> v8_result; | 159 v8::Handle<v8::Value> v8_result; |
161 if (!converter.ToV8Value(var, context_, &v8_result)) | 160 if (!V8VarConverter::ToV8Value(var, context_, &v8_result)) |
162 return false; | 161 return false; |
163 if (!Equals(var, v8_result)) | 162 if (!Equals(var, v8_result)) |
164 return false; | 163 return false; |
165 if (!converter.FromV8Value(v8_result, context_, result)) | 164 if (!V8VarConverter::FromV8Value(v8_result, context_, result)) |
166 return false; | 165 return false; |
167 return true; | 166 return true; |
168 } | 167 } |
169 | 168 |
170 // Assumes a ref for var. | 169 // Assumes a ref for var. |
171 bool RoundTripAndCompare(const PP_Var& var) { | 170 bool RoundTripAndCompare(const PP_Var& var) { |
172 ScopedPPVar expected(ScopedPPVar::PassRef(), var); | 171 ScopedPPVar expected(ScopedPPVar::PassRef(), var); |
173 PP_Var actual_var; | 172 PP_Var actual_var; |
174 if (!RoundTrip(expected.get(), &actual_var)) | 173 if (!RoundTrip(expected.get(), &actual_var)) |
175 return false; | 174 return false; |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
262 EXPECT_TRUE(RoundTripAndCompare(dictionary->GetPPVar())); | 261 EXPECT_TRUE(RoundTripAndCompare(dictionary->GetPPVar())); |
263 | 262 |
264 // Array with dictionary. | 263 // Array with dictionary. |
265 array->Set(index++, release_dictionary.get()); | 264 array->Set(index++, release_dictionary.get()); |
266 EXPECT_TRUE(RoundTripAndCompare(array->GetPPVar())); | 265 EXPECT_TRUE(RoundTripAndCompare(array->GetPPVar())); |
267 | 266 |
268 // Array with dictionary with array. | 267 // Array with dictionary with array. |
269 array2->Set(0, PP_MakeInt32(100)); | 268 array2->Set(0, PP_MakeInt32(100)); |
270 dictionary->SetWithStringKey("9", release_array2.get()); | 269 dictionary->SetWithStringKey("9", release_array2.get()); |
271 EXPECT_TRUE(RoundTripAndCompare(array->GetPPVar())); | 270 EXPECT_TRUE(RoundTripAndCompare(array->GetPPVar())); |
| 271 } |
272 | 272 |
273 // Array <-> dictionary cycle. | 273 TEST_F(V8VarConverterTest, Cycles) { |
274 dictionary->SetWithStringKey("10", release_array.get()); | 274 // Check that cycles aren't converted. |
275 PP_Var result_var; | 275 v8::Context::Scope context_scope(context_); |
276 EXPECT_TRUE(RoundTrip(release_dictionary.get(), &result_var)); | 276 v8::HandleScope handle_scope; |
277 ScopedPPVar result = ScopedPPVar(ScopedPPVar::PassRef(), result_var); | |
278 EXPECT_TRUE(TestEqual(release_dictionary.get(), result.get())); | |
279 // Break the cycle. | |
280 // TODO(raymes): We need some better machinery for releasing vars with | |
281 // cycles. Remove the code below once we have that. | |
282 dictionary->DeleteWithStringKey("10"); | |
283 DictionaryVar* result_dictionary = DictionaryVar::FromPPVar(result.get()); | |
284 result_dictionary->DeleteWithStringKey("10"); | |
285 | 277 |
286 // Array with self references. | 278 // Var->V8 conversion. |
287 array->Set(index, release_array.get()); | 279 { |
288 EXPECT_TRUE(RoundTrip(release_array.get(), &result_var)); | 280 scoped_refptr<DictionaryVar> dictionary(new DictionaryVar); |
289 result = ScopedPPVar(ScopedPPVar::PassRef(), result_var); | 281 ScopedPPVar release_dictionary(ScopedPPVar::PassRef(), |
290 EXPECT_TRUE(TestEqual(release_array.get(), result.get())); | 282 dictionary->GetPPVar()); |
291 // Break the self reference. | 283 scoped_refptr<ArrayVar> array(new ArrayVar); |
292 array->Set(index, PP_MakeUndefined()); | 284 ScopedPPVar release_array(ScopedPPVar::PassRef(), array->GetPPVar()); |
293 ArrayVar* result_array = ArrayVar::FromPPVar(result.get()); | 285 |
294 result_array->Set(index, PP_MakeUndefined()); | 286 dictionary->SetWithStringKey("1", release_array.get()); |
| 287 array->Set(0, release_dictionary.get()); |
| 288 |
| 289 v8::Handle<v8::Value> v8_result; |
| 290 |
| 291 // Array <-> dictionary cycle. |
| 292 dictionary->SetWithStringKey("1", release_array.get()); |
| 293 ASSERT_FALSE(V8VarConverter::ToV8Value(release_dictionary.get(), |
| 294 context_, &v8_result)); |
| 295 // Break the cycle. |
| 296 // TODO(raymes): We need some better machinery for releasing vars with |
| 297 // cycles. Remove the code below once we have that. |
| 298 dictionary->DeleteWithStringKey("1"); |
| 299 |
| 300 // Array with self reference. |
| 301 array->Set(0, release_array.get()); |
| 302 ASSERT_FALSE(V8VarConverter::ToV8Value(release_array.get(), |
| 303 context_, &v8_result)); |
| 304 // Break the self reference. |
| 305 array->Set(0, PP_MakeUndefined()); |
| 306 } |
| 307 |
| 308 // V8->Var conversion. |
| 309 { |
| 310 v8::Handle<v8::Object> object = v8::Object::New(); |
| 311 v8::Handle<v8::Array> array = v8::Array::New(); |
| 312 |
| 313 PP_Var var_result; |
| 314 |
| 315 // Array <-> dictionary cycle. |
| 316 std::string key = "1"; |
| 317 object->Set(v8::String::New(key.c_str(), key.length()), array); |
| 318 array->Set(0, object); |
| 319 |
| 320 ASSERT_FALSE(V8VarConverter::FromV8Value(object, context_, &var_result)); |
| 321 |
| 322 // Array with self reference. |
| 323 array->Set(0, array); |
| 324 ASSERT_FALSE(V8VarConverter::FromV8Value(array, context_, &var_result)); |
| 325 } |
295 } | 326 } |
296 | 327 |
297 TEST_F(V8VarConverterTest, StrangeDictionaryKeyTest) { | 328 TEST_F(V8VarConverterTest, StrangeDictionaryKeyTest) { |
298 { | 329 { |
299 // Test keys with '.'. | 330 // Test keys with '.'. |
300 scoped_refptr<DictionaryVar> dictionary(new DictionaryVar); | 331 scoped_refptr<DictionaryVar> dictionary(new DictionaryVar); |
301 dictionary->SetWithStringKey(".", PP_MakeUndefined()); | 332 dictionary->SetWithStringKey(".", PP_MakeUndefined()); |
302 dictionary->SetWithStringKey("x.y", PP_MakeUndefined()); | 333 dictionary->SetWithStringKey("x.y", PP_MakeUndefined()); |
303 EXPECT_TRUE(RoundTripAndCompare(dictionary->GetPPVar())); | 334 EXPECT_TRUE(RoundTripAndCompare(dictionary->GetPPVar())); |
304 } | 335 } |
(...skipping 11 matching lines...) Expand all Loading... |
316 "false: 'qux'," | 347 "false: 'qux'," |
317 "null: 'quux'," | 348 "null: 'quux'," |
318 "undefined: 'oops'" | 349 "undefined: 'oops'" |
319 "};" | 350 "};" |
320 "})();"; | 351 "})();"; |
321 | 352 |
322 v8::Handle<v8::Script> script(v8::Script::New(v8::String::New(source))); | 353 v8::Handle<v8::Script> script(v8::Script::New(v8::String::New(source))); |
323 v8::Handle<v8::Object> object = script->Run().As<v8::Object>(); | 354 v8::Handle<v8::Object> object = script->Run().As<v8::Object>(); |
324 ASSERT_FALSE(object.IsEmpty()); | 355 ASSERT_FALSE(object.IsEmpty()); |
325 | 356 |
326 V8VarConverter converter; | |
327 PP_Var actual; | 357 PP_Var actual; |
328 ASSERT_TRUE(converter.FromV8Value(object, context_, &actual)); | 358 ASSERT_TRUE(V8VarConverter::FromV8Value(object, context_, &actual)); |
329 ScopedPPVar release_actual(ScopedPPVar::PassRef(), actual); | 359 ScopedPPVar release_actual(ScopedPPVar::PassRef(), actual); |
330 | 360 |
331 scoped_refptr<DictionaryVar> expected(new DictionaryVar); | 361 scoped_refptr<DictionaryVar> expected(new DictionaryVar); |
332 ScopedPPVar foo(ScopedPPVar::PassRef(), StringVar::StringToPPVar("foo")); | 362 ScopedPPVar foo(ScopedPPVar::PassRef(), StringVar::StringToPPVar("foo")); |
333 expected->SetWithStringKey("1", foo.get()); | 363 expected->SetWithStringKey("1", foo.get()); |
334 ScopedPPVar bar(ScopedPPVar::PassRef(), StringVar::StringToPPVar("bar")); | 364 ScopedPPVar bar(ScopedPPVar::PassRef(), StringVar::StringToPPVar("bar")); |
335 expected->SetWithStringKey("2", bar.get()); | 365 expected->SetWithStringKey("2", bar.get()); |
336 ScopedPPVar baz(ScopedPPVar::PassRef(), StringVar::StringToPPVar("baz")); | 366 ScopedPPVar baz(ScopedPPVar::PassRef(), StringVar::StringToPPVar("baz")); |
337 expected->SetWithStringKey("true", baz.get()); | 367 expected->SetWithStringKey("true", baz.get()); |
338 ScopedPPVar qux(ScopedPPVar::PassRef(), StringVar::StringToPPVar("qux")); | 368 ScopedPPVar qux(ScopedPPVar::PassRef(), StringVar::StringToPPVar("qux")); |
339 expected->SetWithStringKey("false", qux.get()); | 369 expected->SetWithStringKey("false", qux.get()); |
340 ScopedPPVar quux(ScopedPPVar::PassRef(), StringVar::StringToPPVar("quux")); | 370 ScopedPPVar quux(ScopedPPVar::PassRef(), StringVar::StringToPPVar("quux")); |
341 expected->SetWithStringKey("null", quux.get()); | 371 expected->SetWithStringKey("null", quux.get()); |
342 ScopedPPVar oops(ScopedPPVar::PassRef(), StringVar::StringToPPVar("oops")); | 372 ScopedPPVar oops(ScopedPPVar::PassRef(), StringVar::StringToPPVar("oops")); |
343 expected->SetWithStringKey("undefined", oops.get()); | 373 expected->SetWithStringKey("undefined", oops.get()); |
344 ScopedPPVar release_expected( | 374 ScopedPPVar release_expected( |
345 ScopedPPVar::PassRef(), expected->GetPPVar()); | 375 ScopedPPVar::PassRef(), expected->GetPPVar()); |
346 | 376 |
347 ASSERT_TRUE(TestEqual(release_expected.get(), release_actual.get())); | 377 ASSERT_TRUE(TestEqual(release_expected.get(), release_actual.get())); |
348 } | 378 } |
349 } | 379 } |
350 | 380 |
351 } // namespace ppapi | 381 } // namespace ppapi |
352 } // namespace webkit | 382 } // namespace webkit |
OLD | NEW |