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 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
145 context_.Reset(isolate_, v8::Context::New(isolate_, NULL, global)); | 145 context_.Reset(isolate_, v8::Context::New(isolate_, NULL, global)); |
146 } | 146 } |
147 virtual void TearDown() { | 147 virtual void TearDown() { |
148 context_.Dispose(); | 148 context_.Dispose(); |
149 ASSERT_TRUE(PpapiGlobals::Get()->GetVarTracker()->GetLiveVars().empty()); | 149 ASSERT_TRUE(PpapiGlobals::Get()->GetVarTracker()->GetLiveVars().empty()); |
150 ProxyLock::Release(); | 150 ProxyLock::Release(); |
151 } | 151 } |
152 | 152 |
153 protected: | 153 protected: |
154 bool RoundTrip(const PP_Var& var, PP_Var* result) { | 154 bool RoundTrip(const PP_Var& var, PP_Var* result) { |
155 V8VarConverter converter; | 155 V8VarConverter converter; |
dmichael (off chromium)
2013/06/18 16:27:02
It's weird that you create this before setting up
raymes
2013/06/18 16:40:20
This was a merge bug which I fixed in the latest p
| |
156 v8::HandleScope handle_scope(isolate_); | 156 v8::HandleScope handle_scope(isolate_); |
157 v8::Context::Scope context_scope(isolate_, context_); | 157 v8::Context::Scope context_scope(isolate_, context_); |
158 v8::Local<v8::Context> context = | 158 v8::Local<v8::Context> context = |
159 v8::Local<v8::Context>::New(isolate_, context_); | 159 v8::Local<v8::Context>::New(isolate_, context_); |
dmichael (off chromium)
2013/06/18 16:27:02
I don't have a very strong grasp on the v8 embeddi
raymes
2013/06/18 16:40:20
marja@ updated this in https://chromiumcodereview.
dmichael (off chromium)
2013/06/18 16:51:34
Nevermind, I was reading it incorrectly. |context|
| |
160 v8::Handle<v8::Value> v8_result; | 160 v8::Handle<v8::Value> v8_result; |
161 if (!converter.ToV8Value(var, context, &v8_result)) | 161 if (!V8VarConverter::ToV8Value(var, context, &v8_result)) |
162 return false; | 162 return false; |
163 if (!Equals(var, v8_result)) | 163 if (!Equals(var, v8_result)) |
164 return false; | 164 return false; |
165 if (!converter.FromV8Value(v8_result, context, result)) | 165 if (!V8VarConverter::FromV8Value(v8_result, context, result)) |
166 return false; | 166 return false; |
167 return true; | 167 return true; |
168 } | 168 } |
169 | 169 |
170 // Assumes a ref for var. | 170 // Assumes a ref for var. |
171 bool RoundTripAndCompare(const PP_Var& var) { | 171 bool RoundTripAndCompare(const PP_Var& var) { |
172 ScopedPPVar expected(ScopedPPVar::PassRef(), var); | 172 ScopedPPVar expected(ScopedPPVar::PassRef(), var); |
173 PP_Var actual_var; | 173 PP_Var actual_var; |
174 if (!RoundTrip(expected.get(), &actual_var)) | 174 if (!RoundTrip(expected.get(), &actual_var)) |
175 return false; | 175 return false; |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
264 EXPECT_TRUE(RoundTripAndCompare(dictionary->GetPPVar())); | 264 EXPECT_TRUE(RoundTripAndCompare(dictionary->GetPPVar())); |
265 | 265 |
266 // Array with dictionary. | 266 // Array with dictionary. |
267 array->Set(index++, release_dictionary.get()); | 267 array->Set(index++, release_dictionary.get()); |
268 EXPECT_TRUE(RoundTripAndCompare(array->GetPPVar())); | 268 EXPECT_TRUE(RoundTripAndCompare(array->GetPPVar())); |
269 | 269 |
270 // Array with dictionary with array. | 270 // Array with dictionary with array. |
271 array2->Set(0, PP_MakeInt32(100)); | 271 array2->Set(0, PP_MakeInt32(100)); |
272 dictionary->SetWithStringKey("9", release_array2.get()); | 272 dictionary->SetWithStringKey("9", release_array2.get()); |
273 EXPECT_TRUE(RoundTripAndCompare(array->GetPPVar())); | 273 EXPECT_TRUE(RoundTripAndCompare(array->GetPPVar())); |
274 } | |
274 | 275 |
275 // Array <-> dictionary cycle. | 276 TEST_F(V8VarConverterTest, Cycles) { |
276 dictionary->SetWithStringKey("10", release_array.get()); | 277 // Check that cycles aren't converted. |
277 PP_Var result_var; | 278 v8::Context::Scope context_scope(context_); |
278 EXPECT_TRUE(RoundTrip(release_dictionary.get(), &result_var)); | 279 v8::HandleScope handle_scope; |
279 ScopedPPVar result = ScopedPPVar(ScopedPPVar::PassRef(), result_var); | |
280 EXPECT_TRUE(TestEqual(release_dictionary.get(), result.get())); | |
281 // Break the cycle. | |
282 // TODO(raymes): We need some better machinery for releasing vars with | |
283 // cycles. Remove the code below once we have that. | |
284 dictionary->DeleteWithStringKey("10"); | |
285 DictionaryVar* result_dictionary = DictionaryVar::FromPPVar(result.get()); | |
286 result_dictionary->DeleteWithStringKey("10"); | |
287 | 280 |
288 // Array with self references. | 281 // Var->V8 conversion. |
289 array->Set(index, release_array.get()); | 282 { |
290 EXPECT_TRUE(RoundTrip(release_array.get(), &result_var)); | 283 scoped_refptr<DictionaryVar> dictionary(new DictionaryVar); |
291 result = ScopedPPVar(ScopedPPVar::PassRef(), result_var); | 284 ScopedPPVar release_dictionary(ScopedPPVar::PassRef(), |
292 EXPECT_TRUE(TestEqual(release_array.get(), result.get())); | 285 dictionary->GetPPVar()); |
293 // Break the self reference. | 286 scoped_refptr<ArrayVar> array(new ArrayVar); |
294 array->Set(index, PP_MakeUndefined()); | 287 ScopedPPVar release_array(ScopedPPVar::PassRef(), array->GetPPVar()); |
295 ArrayVar* result_array = ArrayVar::FromPPVar(result.get()); | 288 |
296 result_array->Set(index, PP_MakeUndefined()); | 289 dictionary->SetWithStringKey("1", release_array.get()); |
290 array->Set(0, release_dictionary.get()); | |
291 | |
292 v8::Handle<v8::Value> v8_result; | |
293 | |
294 // Array <-> dictionary cycle. | |
295 dictionary->SetWithStringKey("1", release_array.get()); | |
296 ASSERT_FALSE(V8VarConverter::ToV8Value(release_dictionary.get(), | |
297 context_, &v8_result)); | |
298 // Break the cycle. | |
299 // TODO(raymes): We need some better machinery for releasing vars with | |
300 // cycles. Remove the code below once we have that. | |
301 dictionary->DeleteWithStringKey("1"); | |
302 | |
303 // Array with self reference. | |
304 array->Set(0, release_array.get()); | |
305 ASSERT_FALSE(V8VarConverter::ToV8Value(release_array.get(), | |
306 context_, &v8_result)); | |
307 // Break the self reference. | |
308 array->Set(0, PP_MakeUndefined()); | |
309 } | |
310 | |
311 // V8->Var conversion. | |
312 { | |
313 v8::Handle<v8::Object> object = v8::Object::New(); | |
314 v8::Handle<v8::Array> array = v8::Array::New(); | |
315 | |
316 PP_Var var_result; | |
317 | |
318 // Array <-> dictionary cycle. | |
319 std::string key = "1"; | |
320 object->Set(v8::String::New(key.c_str(), key.length()), array); | |
321 array->Set(0, object); | |
322 | |
323 ASSERT_FALSE(V8VarConverter::FromV8Value(object, context_, &var_result)); | |
324 | |
325 // Array with self reference. | |
326 array->Set(0, array); | |
327 ASSERT_FALSE(V8VarConverter::FromV8Value(array, context_, &var_result)); | |
328 } | |
297 } | 329 } |
298 | 330 |
299 TEST_F(V8VarConverterTest, StrangeDictionaryKeyTest) { | 331 TEST_F(V8VarConverterTest, StrangeDictionaryKeyTest) { |
300 { | 332 { |
301 // Test keys with '.'. | 333 // Test keys with '.'. |
302 scoped_refptr<DictionaryVar> dictionary(new DictionaryVar); | 334 scoped_refptr<DictionaryVar> dictionary(new DictionaryVar); |
303 dictionary->SetWithStringKey(".", PP_MakeUndefined()); | 335 dictionary->SetWithStringKey(".", PP_MakeUndefined()); |
304 dictionary->SetWithStringKey("x.y", PP_MakeUndefined()); | 336 dictionary->SetWithStringKey("x.y", PP_MakeUndefined()); |
305 EXPECT_TRUE(RoundTripAndCompare(dictionary->GetPPVar())); | 337 EXPECT_TRUE(RoundTripAndCompare(dictionary->GetPPVar())); |
306 } | 338 } |
(...skipping 11 matching lines...) Expand all Loading... | |
318 "false: 'qux'," | 350 "false: 'qux'," |
319 "null: 'quux'," | 351 "null: 'quux'," |
320 "undefined: 'oops'" | 352 "undefined: 'oops'" |
321 "};" | 353 "};" |
322 "})();"; | 354 "})();"; |
323 | 355 |
324 v8::Handle<v8::Script> script(v8::Script::New(v8::String::New(source))); | 356 v8::Handle<v8::Script> script(v8::Script::New(v8::String::New(source))); |
325 v8::Handle<v8::Object> object = script->Run().As<v8::Object>(); | 357 v8::Handle<v8::Object> object = script->Run().As<v8::Object>(); |
326 ASSERT_FALSE(object.IsEmpty()); | 358 ASSERT_FALSE(object.IsEmpty()); |
327 | 359 |
328 V8VarConverter converter; | |
329 PP_Var actual; | 360 PP_Var actual; |
330 ASSERT_TRUE(converter.FromV8Value( | 361 ASSERT_TRUE(V8VarConverter::FromV8Value(object, |
331 object, v8::Local<v8::Context>::New(isolate_, context_), &actual)); | 362 v8::Local<v8::Context>::New(isolate_, context_), &actual)); |
332 ScopedPPVar release_actual(ScopedPPVar::PassRef(), actual); | 363 ScopedPPVar release_actual(ScopedPPVar::PassRef(), actual); |
333 | 364 |
334 scoped_refptr<DictionaryVar> expected(new DictionaryVar); | 365 scoped_refptr<DictionaryVar> expected(new DictionaryVar); |
335 ScopedPPVar foo(ScopedPPVar::PassRef(), StringVar::StringToPPVar("foo")); | 366 ScopedPPVar foo(ScopedPPVar::PassRef(), StringVar::StringToPPVar("foo")); |
336 expected->SetWithStringKey("1", foo.get()); | 367 expected->SetWithStringKey("1", foo.get()); |
337 ScopedPPVar bar(ScopedPPVar::PassRef(), StringVar::StringToPPVar("bar")); | 368 ScopedPPVar bar(ScopedPPVar::PassRef(), StringVar::StringToPPVar("bar")); |
338 expected->SetWithStringKey("2", bar.get()); | 369 expected->SetWithStringKey("2", bar.get()); |
339 ScopedPPVar baz(ScopedPPVar::PassRef(), StringVar::StringToPPVar("baz")); | 370 ScopedPPVar baz(ScopedPPVar::PassRef(), StringVar::StringToPPVar("baz")); |
340 expected->SetWithStringKey("true", baz.get()); | 371 expected->SetWithStringKey("true", baz.get()); |
341 ScopedPPVar qux(ScopedPPVar::PassRef(), StringVar::StringToPPVar("qux")); | 372 ScopedPPVar qux(ScopedPPVar::PassRef(), StringVar::StringToPPVar("qux")); |
342 expected->SetWithStringKey("false", qux.get()); | 373 expected->SetWithStringKey("false", qux.get()); |
343 ScopedPPVar quux(ScopedPPVar::PassRef(), StringVar::StringToPPVar("quux")); | 374 ScopedPPVar quux(ScopedPPVar::PassRef(), StringVar::StringToPPVar("quux")); |
344 expected->SetWithStringKey("null", quux.get()); | 375 expected->SetWithStringKey("null", quux.get()); |
345 ScopedPPVar oops(ScopedPPVar::PassRef(), StringVar::StringToPPVar("oops")); | 376 ScopedPPVar oops(ScopedPPVar::PassRef(), StringVar::StringToPPVar("oops")); |
346 expected->SetWithStringKey("undefined", oops.get()); | 377 expected->SetWithStringKey("undefined", oops.get()); |
347 ScopedPPVar release_expected( | 378 ScopedPPVar release_expected( |
348 ScopedPPVar::PassRef(), expected->GetPPVar()); | 379 ScopedPPVar::PassRef(), expected->GetPPVar()); |
349 | 380 |
350 ASSERT_TRUE(TestEqual(release_expected.get(), release_actual.get())); | 381 ASSERT_TRUE(TestEqual(release_expected.get(), release_actual.get())); |
351 } | 382 } |
352 } | 383 } |
353 | 384 |
354 } // namespace ppapi | 385 } // namespace ppapi |
355 } // namespace webkit | 386 } // namespace webkit |
OLD | NEW |