OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project 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 "src/value-serializer.h" | 5 #include "src/value-serializer.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "include/v8.h" | 10 #include "include/v8.h" |
(...skipping 13 matching lines...) Expand all Loading... |
24 | 24 |
25 class ValueSerializerTest : public TestWithIsolate { | 25 class ValueSerializerTest : public TestWithIsolate { |
26 protected: | 26 protected: |
27 ValueSerializerTest() | 27 ValueSerializerTest() |
28 : serialization_context_(Context::New(isolate())), | 28 : serialization_context_(Context::New(isolate())), |
29 deserialization_context_(Context::New(isolate())) { | 29 deserialization_context_(Context::New(isolate())) { |
30 // Create a host object type that can be tested through | 30 // Create a host object type that can be tested through |
31 // serialization/deserialization delegates below. | 31 // serialization/deserialization delegates below. |
32 Local<FunctionTemplate> function_template = v8::FunctionTemplate::New( | 32 Local<FunctionTemplate> function_template = v8::FunctionTemplate::New( |
33 isolate(), [](const FunctionCallbackInfo<Value>& args) { | 33 isolate(), [](const FunctionCallbackInfo<Value>& args) { |
34 args.Holder()->SetInternalField(0, args[0]); | 34 args.Holder()->SetEmbedderField(0, args[0]); |
35 args.Holder()->SetInternalField(1, args[1]); | 35 args.Holder()->SetEmbedderField(1, args[1]); |
36 }); | 36 }); |
37 function_template->InstanceTemplate()->SetInternalFieldCount(2); | 37 function_template->InstanceTemplate()->SetEmbedderFieldCount(2); |
38 function_template->InstanceTemplate()->SetAccessor( | 38 function_template->InstanceTemplate()->SetAccessor( |
39 StringFromUtf8("value"), | 39 StringFromUtf8("value"), |
40 [](Local<String> property, const PropertyCallbackInfo<Value>& args) { | 40 [](Local<String> property, const PropertyCallbackInfo<Value>& args) { |
41 args.GetReturnValue().Set(args.Holder()->GetInternalField(0)); | 41 args.GetReturnValue().Set(args.Holder()->GetEmbedderField(0)); |
42 }); | 42 }); |
43 function_template->InstanceTemplate()->SetAccessor( | 43 function_template->InstanceTemplate()->SetAccessor( |
44 StringFromUtf8("value2"), | 44 StringFromUtf8("value2"), |
45 [](Local<String> property, const PropertyCallbackInfo<Value>& args) { | 45 [](Local<String> property, const PropertyCallbackInfo<Value>& args) { |
46 args.GetReturnValue().Set(args.Holder()->GetInternalField(1)); | 46 args.GetReturnValue().Set(args.Holder()->GetEmbedderField(1)); |
47 }); | 47 }); |
48 for (Local<Context> context : | 48 for (Local<Context> context : |
49 {serialization_context_, deserialization_context_}) { | 49 {serialization_context_, deserialization_context_}) { |
50 context->Global() | 50 context->Global() |
51 ->CreateDataProperty( | 51 ->CreateDataProperty( |
52 context, StringFromUtf8("ExampleHostObject"), | 52 context, StringFromUtf8("ExampleHostObject"), |
53 function_template->GetFunction(context).ToLocalChecked()) | 53 function_template->GetFunction(context).ToLocalChecked()) |
54 .ToChecked(); | 54 .ToChecked(); |
55 } | 55 } |
56 host_object_constructor_template_ = function_template; | 56 host_object_constructor_template_ = function_template; |
(...skipping 2315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2372 | 2372 |
2373 // This is a tag that is used in V8. Using this ensures that we have separate | 2373 // This is a tag that is used in V8. Using this ensures that we have separate |
2374 // tag namespaces. | 2374 // tag namespaces. |
2375 const uint8_t ValueSerializerTestWithHostObject::kExampleHostObjectTag = 'T'; | 2375 const uint8_t ValueSerializerTestWithHostObject::kExampleHostObjectTag = 'T'; |
2376 | 2376 |
2377 TEST_F(ValueSerializerTestWithHostObject, RoundTripUint32) { | 2377 TEST_F(ValueSerializerTestWithHostObject, RoundTripUint32) { |
2378 // The host can serialize data as uint32_t. | 2378 // The host can serialize data as uint32_t. |
2379 EXPECT_CALL(serializer_delegate_, WriteHostObject(isolate(), _)) | 2379 EXPECT_CALL(serializer_delegate_, WriteHostObject(isolate(), _)) |
2380 .WillRepeatedly(Invoke([this](Isolate*, Local<Object> object) { | 2380 .WillRepeatedly(Invoke([this](Isolate*, Local<Object> object) { |
2381 uint32_t value = 0; | 2381 uint32_t value = 0; |
2382 EXPECT_TRUE(object->GetInternalField(0) | 2382 EXPECT_TRUE(object->GetEmbedderField(0) |
2383 ->Uint32Value(serialization_context()) | 2383 ->Uint32Value(serialization_context()) |
2384 .To(&value)); | 2384 .To(&value)); |
2385 WriteExampleHostObjectTag(); | 2385 WriteExampleHostObjectTag(); |
2386 serializer_->WriteUint32(value); | 2386 serializer_->WriteUint32(value); |
2387 return Just(true); | 2387 return Just(true); |
2388 })); | 2388 })); |
2389 EXPECT_CALL(deserializer_delegate_, ReadHostObject(isolate())) | 2389 EXPECT_CALL(deserializer_delegate_, ReadHostObject(isolate())) |
2390 .WillRepeatedly(Invoke([this](Isolate*) { | 2390 .WillRepeatedly(Invoke([this](Isolate*) { |
2391 EXPECT_TRUE(ReadExampleHostObjectTag()); | 2391 EXPECT_TRUE(ReadExampleHostObjectTag()); |
2392 uint32_t value = 0; | 2392 uint32_t value = 0; |
2393 EXPECT_TRUE(deserializer_->ReadUint32(&value)); | 2393 EXPECT_TRUE(deserializer_->ReadUint32(&value)); |
2394 Local<Value> argv[] = {Integer::NewFromUnsigned(isolate(), value)}; | 2394 Local<Value> argv[] = {Integer::NewFromUnsigned(isolate(), value)}; |
2395 return NewHostObject(deserialization_context(), arraysize(argv), argv); | 2395 return NewHostObject(deserialization_context(), arraysize(argv), argv); |
2396 })); | 2396 })); |
2397 RoundTripTest("new ExampleHostObject(42)", [this](Local<Value> value) { | 2397 RoundTripTest("new ExampleHostObject(42)", [this](Local<Value> value) { |
2398 ASSERT_TRUE(value->IsObject()); | 2398 ASSERT_TRUE(value->IsObject()); |
2399 ASSERT_TRUE(Object::Cast(*value)->InternalFieldCount()); | 2399 ASSERT_TRUE(Object::Cast(*value)->EmbedderFieldCount()); |
2400 EXPECT_TRUE(EvaluateScriptForResultBool( | 2400 EXPECT_TRUE(EvaluateScriptForResultBool( |
2401 "Object.getPrototypeOf(result) === ExampleHostObject.prototype")); | 2401 "Object.getPrototypeOf(result) === ExampleHostObject.prototype")); |
2402 EXPECT_TRUE(EvaluateScriptForResultBool("result.value === 42")); | 2402 EXPECT_TRUE(EvaluateScriptForResultBool("result.value === 42")); |
2403 }); | 2403 }); |
2404 RoundTripTest( | 2404 RoundTripTest( |
2405 "new ExampleHostObject(0xCAFECAFE)", [this](Local<Value> value) { | 2405 "new ExampleHostObject(0xCAFECAFE)", [this](Local<Value> value) { |
2406 EXPECT_TRUE(EvaluateScriptForResultBool("result.value === 0xCAFECAFE")); | 2406 EXPECT_TRUE(EvaluateScriptForResultBool("result.value === 0xCAFECAFE")); |
2407 }); | 2407 }); |
2408 } | 2408 } |
2409 | 2409 |
2410 TEST_F(ValueSerializerTestWithHostObject, RoundTripUint64) { | 2410 TEST_F(ValueSerializerTestWithHostObject, RoundTripUint64) { |
2411 // The host can serialize data as uint64_t. | 2411 // The host can serialize data as uint64_t. |
2412 EXPECT_CALL(serializer_delegate_, WriteHostObject(isolate(), _)) | 2412 EXPECT_CALL(serializer_delegate_, WriteHostObject(isolate(), _)) |
2413 .WillRepeatedly(Invoke([this](Isolate*, Local<Object> object) { | 2413 .WillRepeatedly(Invoke([this](Isolate*, Local<Object> object) { |
2414 uint32_t value = 0, value2 = 0; | 2414 uint32_t value = 0, value2 = 0; |
2415 EXPECT_TRUE(object->GetInternalField(0) | 2415 EXPECT_TRUE(object->GetEmbedderField(0) |
2416 ->Uint32Value(serialization_context()) | 2416 ->Uint32Value(serialization_context()) |
2417 .To(&value)); | 2417 .To(&value)); |
2418 EXPECT_TRUE(object->GetInternalField(1) | 2418 EXPECT_TRUE(object->GetEmbedderField(1) |
2419 ->Uint32Value(serialization_context()) | 2419 ->Uint32Value(serialization_context()) |
2420 .To(&value2)); | 2420 .To(&value2)); |
2421 WriteExampleHostObjectTag(); | 2421 WriteExampleHostObjectTag(); |
2422 serializer_->WriteUint64((static_cast<uint64_t>(value) << 32) | value2); | 2422 serializer_->WriteUint64((static_cast<uint64_t>(value) << 32) | value2); |
2423 return Just(true); | 2423 return Just(true); |
2424 })); | 2424 })); |
2425 EXPECT_CALL(deserializer_delegate_, ReadHostObject(isolate())) | 2425 EXPECT_CALL(deserializer_delegate_, ReadHostObject(isolate())) |
2426 .WillRepeatedly(Invoke([this](Isolate*) { | 2426 .WillRepeatedly(Invoke([this](Isolate*) { |
2427 EXPECT_TRUE(ReadExampleHostObjectTag()); | 2427 EXPECT_TRUE(ReadExampleHostObjectTag()); |
2428 uint64_t value_packed; | 2428 uint64_t value_packed; |
2429 EXPECT_TRUE(deserializer_->ReadUint64(&value_packed)); | 2429 EXPECT_TRUE(deserializer_->ReadUint64(&value_packed)); |
2430 Local<Value> argv[] = { | 2430 Local<Value> argv[] = { |
2431 Integer::NewFromUnsigned(isolate(), | 2431 Integer::NewFromUnsigned(isolate(), |
2432 static_cast<uint32_t>(value_packed >> 32)), | 2432 static_cast<uint32_t>(value_packed >> 32)), |
2433 Integer::NewFromUnsigned(isolate(), | 2433 Integer::NewFromUnsigned(isolate(), |
2434 static_cast<uint32_t>(value_packed))}; | 2434 static_cast<uint32_t>(value_packed))}; |
2435 return NewHostObject(deserialization_context(), arraysize(argv), argv); | 2435 return NewHostObject(deserialization_context(), arraysize(argv), argv); |
2436 })); | 2436 })); |
2437 RoundTripTest("new ExampleHostObject(42, 0)", [this](Local<Value> value) { | 2437 RoundTripTest("new ExampleHostObject(42, 0)", [this](Local<Value> value) { |
2438 ASSERT_TRUE(value->IsObject()); | 2438 ASSERT_TRUE(value->IsObject()); |
2439 ASSERT_TRUE(Object::Cast(*value)->InternalFieldCount()); | 2439 ASSERT_TRUE(Object::Cast(*value)->EmbedderFieldCount()); |
2440 EXPECT_TRUE(EvaluateScriptForResultBool( | 2440 EXPECT_TRUE(EvaluateScriptForResultBool( |
2441 "Object.getPrototypeOf(result) === ExampleHostObject.prototype")); | 2441 "Object.getPrototypeOf(result) === ExampleHostObject.prototype")); |
2442 EXPECT_TRUE(EvaluateScriptForResultBool("result.value === 42")); | 2442 EXPECT_TRUE(EvaluateScriptForResultBool("result.value === 42")); |
2443 EXPECT_TRUE(EvaluateScriptForResultBool("result.value2 === 0")); | 2443 EXPECT_TRUE(EvaluateScriptForResultBool("result.value2 === 0")); |
2444 }); | 2444 }); |
2445 RoundTripTest( | 2445 RoundTripTest( |
2446 "new ExampleHostObject(0xFFFFFFFF, 0x12345678)", | 2446 "new ExampleHostObject(0xFFFFFFFF, 0x12345678)", |
2447 [this](Local<Value> value) { | 2447 [this](Local<Value> value) { |
2448 EXPECT_TRUE(EvaluateScriptForResultBool("result.value === 0xFFFFFFFF")); | 2448 EXPECT_TRUE(EvaluateScriptForResultBool("result.value === 0xFFFFFFFF")); |
2449 EXPECT_TRUE( | 2449 EXPECT_TRUE( |
2450 EvaluateScriptForResultBool("result.value2 === 0x12345678")); | 2450 EvaluateScriptForResultBool("result.value2 === 0x12345678")); |
2451 }); | 2451 }); |
2452 } | 2452 } |
2453 | 2453 |
2454 TEST_F(ValueSerializerTestWithHostObject, RoundTripDouble) { | 2454 TEST_F(ValueSerializerTestWithHostObject, RoundTripDouble) { |
2455 // The host can serialize data as double. | 2455 // The host can serialize data as double. |
2456 EXPECT_CALL(serializer_delegate_, WriteHostObject(isolate(), _)) | 2456 EXPECT_CALL(serializer_delegate_, WriteHostObject(isolate(), _)) |
2457 .WillRepeatedly(Invoke([this](Isolate*, Local<Object> object) { | 2457 .WillRepeatedly(Invoke([this](Isolate*, Local<Object> object) { |
2458 double value = 0; | 2458 double value = 0; |
2459 EXPECT_TRUE(object->GetInternalField(0) | 2459 EXPECT_TRUE(object->GetEmbedderField(0) |
2460 ->NumberValue(serialization_context()) | 2460 ->NumberValue(serialization_context()) |
2461 .To(&value)); | 2461 .To(&value)); |
2462 WriteExampleHostObjectTag(); | 2462 WriteExampleHostObjectTag(); |
2463 serializer_->WriteDouble(value); | 2463 serializer_->WriteDouble(value); |
2464 return Just(true); | 2464 return Just(true); |
2465 })); | 2465 })); |
2466 EXPECT_CALL(deserializer_delegate_, ReadHostObject(isolate())) | 2466 EXPECT_CALL(deserializer_delegate_, ReadHostObject(isolate())) |
2467 .WillRepeatedly(Invoke([this](Isolate*) { | 2467 .WillRepeatedly(Invoke([this](Isolate*) { |
2468 EXPECT_TRUE(ReadExampleHostObjectTag()); | 2468 EXPECT_TRUE(ReadExampleHostObjectTag()); |
2469 double value = 0; | 2469 double value = 0; |
2470 EXPECT_TRUE(deserializer_->ReadDouble(&value)); | 2470 EXPECT_TRUE(deserializer_->ReadDouble(&value)); |
2471 Local<Value> argv[] = {Number::New(isolate(), value)}; | 2471 Local<Value> argv[] = {Number::New(isolate(), value)}; |
2472 return NewHostObject(deserialization_context(), arraysize(argv), argv); | 2472 return NewHostObject(deserialization_context(), arraysize(argv), argv); |
2473 })); | 2473 })); |
2474 RoundTripTest("new ExampleHostObject(-3.5)", [this](Local<Value> value) { | 2474 RoundTripTest("new ExampleHostObject(-3.5)", [this](Local<Value> value) { |
2475 ASSERT_TRUE(value->IsObject()); | 2475 ASSERT_TRUE(value->IsObject()); |
2476 ASSERT_TRUE(Object::Cast(*value)->InternalFieldCount()); | 2476 ASSERT_TRUE(Object::Cast(*value)->EmbedderFieldCount()); |
2477 EXPECT_TRUE(EvaluateScriptForResultBool( | 2477 EXPECT_TRUE(EvaluateScriptForResultBool( |
2478 "Object.getPrototypeOf(result) === ExampleHostObject.prototype")); | 2478 "Object.getPrototypeOf(result) === ExampleHostObject.prototype")); |
2479 EXPECT_TRUE(EvaluateScriptForResultBool("result.value === -3.5")); | 2479 EXPECT_TRUE(EvaluateScriptForResultBool("result.value === -3.5")); |
2480 }); | 2480 }); |
2481 RoundTripTest("new ExampleHostObject(NaN)", [this](Local<Value> value) { | 2481 RoundTripTest("new ExampleHostObject(NaN)", [this](Local<Value> value) { |
2482 EXPECT_TRUE(EvaluateScriptForResultBool("Number.isNaN(result.value)")); | 2482 EXPECT_TRUE(EvaluateScriptForResultBool("Number.isNaN(result.value)")); |
2483 }); | 2483 }); |
2484 RoundTripTest("new ExampleHostObject(Infinity)", [this](Local<Value> value) { | 2484 RoundTripTest("new ExampleHostObject(Infinity)", [this](Local<Value> value) { |
2485 EXPECT_TRUE(EvaluateScriptForResultBool("result.value === Infinity")); | 2485 EXPECT_TRUE(EvaluateScriptForResultBool("result.value === Infinity")); |
2486 }); | 2486 }); |
(...skipping 22 matching lines...) Expand all Loading... |
2509 const void* copied_data = nullptr; | 2509 const void* copied_data = nullptr; |
2510 EXPECT_TRUE( | 2510 EXPECT_TRUE( |
2511 deserializer_->ReadRawBytes(sizeof(sample_data), &copied_data)); | 2511 deserializer_->ReadRawBytes(sizeof(sample_data), &copied_data)); |
2512 if (copied_data) { | 2512 if (copied_data) { |
2513 EXPECT_EQ(0, memcmp(&sample_data, copied_data, sizeof(sample_data))); | 2513 EXPECT_EQ(0, memcmp(&sample_data, copied_data, sizeof(sample_data))); |
2514 } | 2514 } |
2515 return NewHostObject(deserialization_context(), 0, nullptr); | 2515 return NewHostObject(deserialization_context(), 0, nullptr); |
2516 })); | 2516 })); |
2517 RoundTripTest("new ExampleHostObject()", [this](Local<Value> value) { | 2517 RoundTripTest("new ExampleHostObject()", [this](Local<Value> value) { |
2518 ASSERT_TRUE(value->IsObject()); | 2518 ASSERT_TRUE(value->IsObject()); |
2519 ASSERT_TRUE(Object::Cast(*value)->InternalFieldCount()); | 2519 ASSERT_TRUE(Object::Cast(*value)->EmbedderFieldCount()); |
2520 EXPECT_TRUE(EvaluateScriptForResultBool( | 2520 EXPECT_TRUE(EvaluateScriptForResultBool( |
2521 "Object.getPrototypeOf(result) === ExampleHostObject.prototype")); | 2521 "Object.getPrototypeOf(result) === ExampleHostObject.prototype")); |
2522 }); | 2522 }); |
2523 } | 2523 } |
2524 | 2524 |
2525 TEST_F(ValueSerializerTestWithHostObject, RoundTripSameObject) { | 2525 TEST_F(ValueSerializerTestWithHostObject, RoundTripSameObject) { |
2526 // If the same object exists in two places, the delegate should be invoked | 2526 // If the same object exists in two places, the delegate should be invoked |
2527 // only once, and the objects should be the same (by reference equality) on | 2527 // only once, and the objects should be the same (by reference equality) on |
2528 // the other side. | 2528 // the other side. |
2529 EXPECT_CALL(serializer_delegate_, WriteHostObject(isolate(), _)) | 2529 EXPECT_CALL(serializer_delegate_, WriteHostObject(isolate(), _)) |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2744 InvalidDecodeTest(raw); | 2744 InvalidDecodeTest(raw); |
2745 } | 2745 } |
2746 | 2746 |
2747 TEST_F(ValueSerializerTestWithWasm, DecodeWasmModuleWithInvalidDataLength) { | 2747 TEST_F(ValueSerializerTestWithWasm, DecodeWasmModuleWithInvalidDataLength) { |
2748 InvalidDecodeTest({0xff, 0x09, 0x3f, 0x00, 0x57, 0x79, 0x7f, 0x00}); | 2748 InvalidDecodeTest({0xff, 0x09, 0x3f, 0x00, 0x57, 0x79, 0x7f, 0x00}); |
2749 InvalidDecodeTest({0xff, 0x09, 0x3f, 0x00, 0x57, 0x79, 0x00, 0x7f}); | 2749 InvalidDecodeTest({0xff, 0x09, 0x3f, 0x00, 0x57, 0x79, 0x00, 0x7f}); |
2750 } | 2750 } |
2751 | 2751 |
2752 } // namespace | 2752 } // namespace |
2753 } // namespace v8 | 2753 } // namespace v8 |
OLD | NEW |