OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/base/utils/random-number-generator.h" | 5 #include "src/base/utils/random-number-generator.h" |
6 #include "src/ic/stub-cache.h" | 6 #include "src/ic/stub-cache.h" |
7 #include "src/isolate.h" | 7 #include "src/isolate.h" |
8 #include "test/cctest/compiler/code-assembler-tester.h" | 8 #include "test/cctest/compiler/code-assembler-tester.h" |
9 #include "test/cctest/compiler/function-tester.h" | 9 #include "test/cctest/compiler/function-tester.h" |
10 | 10 |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
225 | 225 |
226 enum Result { kFound, kNotFound }; | 226 enum Result { kFound, kNotFound }; |
227 { | 227 { |
228 Node* dictionary = m.Parameter(0); | 228 Node* dictionary = m.Parameter(0); |
229 Node* unique_name = m.Parameter(1); | 229 Node* unique_name = m.Parameter(1); |
230 Node* expected_result = m.Parameter(2); | 230 Node* expected_result = m.Parameter(2); |
231 Node* expected_arg = m.Parameter(3); | 231 Node* expected_arg = m.Parameter(3); |
232 | 232 |
233 Label passed(&m), failed(&m); | 233 Label passed(&m), failed(&m); |
234 Label if_found(&m), if_not_found(&m); | 234 Label if_found(&m), if_not_found(&m); |
235 Variable var_entry(&m, MachineRepresentation::kWord32); | 235 Variable var_name_index(&m, MachineRepresentation::kWord32); |
236 | 236 |
237 m.NameDictionaryLookup<Dictionary>(dictionary, unique_name, &if_found, | 237 m.NameDictionaryLookup<Dictionary>(dictionary, unique_name, &if_found, |
238 &var_entry, &if_not_found); | 238 &var_name_index, &if_not_found); |
239 m.Bind(&if_found); | 239 m.Bind(&if_found); |
240 m.GotoUnless( | 240 m.GotoUnless( |
241 m.WordEqual(expected_result, m.SmiConstant(Smi::FromInt(kFound))), | 241 m.WordEqual(expected_result, m.SmiConstant(Smi::FromInt(kFound))), |
242 &failed); | 242 &failed); |
243 m.Branch(m.Word32Equal(m.SmiToWord32(expected_arg), var_entry.value()), | 243 m.Branch(m.Word32Equal(m.SmiToWord32(expected_arg), var_name_index.value()), |
244 &passed, &failed); | 244 &passed, &failed); |
245 | 245 |
246 m.Bind(&if_not_found); | 246 m.Bind(&if_not_found); |
247 m.Branch( | 247 m.Branch( |
248 m.WordEqual(expected_result, m.SmiConstant(Smi::FromInt(kNotFound))), | 248 m.WordEqual(expected_result, m.SmiConstant(Smi::FromInt(kNotFound))), |
249 &passed, &failed); | 249 &passed, &failed); |
250 | 250 |
251 m.Bind(&passed); | 251 m.Bind(&passed); |
252 m.Return(m.BooleanConstant(true)); | 252 m.Return(m.BooleanConstant(true)); |
253 | 253 |
(...skipping 23 matching lines...) Expand all Loading... |
277 factory->NewPrivateSymbol(), | 277 factory->NewPrivateSymbol(), |
278 }; | 278 }; |
279 | 279 |
280 for (size_t i = 0; i < arraysize(keys); i++) { | 280 for (size_t i = 0; i < arraysize(keys); i++) { |
281 Handle<Object> value = factory->NewPropertyCell(); | 281 Handle<Object> value = factory->NewPropertyCell(); |
282 dictionary = Dictionary::Add(dictionary, keys[i], value, fake_details); | 282 dictionary = Dictionary::Add(dictionary, keys[i], value, fake_details); |
283 } | 283 } |
284 | 284 |
285 for (size_t i = 0; i < arraysize(keys); i++) { | 285 for (size_t i = 0; i < arraysize(keys); i++) { |
286 int entry = dictionary->FindEntry(keys[i]); | 286 int entry = dictionary->FindEntry(keys[i]); |
| 287 int name_index = |
| 288 Dictionary::EntryToIndex(entry) + Dictionary::kEntryKeyIndex; |
287 CHECK_NE(Dictionary::kNotFound, entry); | 289 CHECK_NE(Dictionary::kNotFound, entry); |
288 | 290 |
289 Handle<Object> expected_entry(Smi::FromInt(entry), isolate); | 291 Handle<Object> expected_name_index(Smi::FromInt(name_index), isolate); |
290 ft.CheckTrue(dictionary, keys[i], expect_found, expected_entry); | 292 ft.CheckTrue(dictionary, keys[i], expect_found, expected_name_index); |
291 } | 293 } |
292 | 294 |
293 Handle<Name> non_existing_keys[] = { | 295 Handle<Name> non_existing_keys[] = { |
294 factory->InternalizeUtf8String("1"), | 296 factory->InternalizeUtf8String("1"), |
295 factory->InternalizeUtf8String("-42"), | 297 factory->InternalizeUtf8String("-42"), |
296 factory->InternalizeUtf8String("153"), | 298 factory->InternalizeUtf8String("153"), |
297 factory->InternalizeUtf8String("-1.0"), | 299 factory->InternalizeUtf8String("-1.0"), |
298 factory->InternalizeUtf8String("1.3"), | 300 factory->InternalizeUtf8String("1.3"), |
299 factory->InternalizeUtf8String("a"), | 301 factory->InternalizeUtf8String("a"), |
300 factory->InternalizeUtf8String("boom"), | 302 factory->InternalizeUtf8String("boom"), |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 } | 413 } |
412 | 414 |
413 TEST(UnseededNumberDictionaryLookup) { | 415 TEST(UnseededNumberDictionaryLookup) { |
414 TestNumberDictionaryLookup<UnseededNumberDictionary>(); | 416 TestNumberDictionaryLookup<UnseededNumberDictionary>(); |
415 } | 417 } |
416 | 418 |
417 namespace { | 419 namespace { |
418 | 420 |
419 void AddProperties(Handle<JSObject> object, Handle<Name> names[], | 421 void AddProperties(Handle<JSObject> object, Handle<Name> names[], |
420 size_t count) { | 422 size_t count) { |
421 Handle<Object> value(Smi::FromInt(42), object->GetIsolate()); | 423 Isolate* isolate = object->GetIsolate(); |
422 for (size_t i = 0; i < count; i++) { | 424 for (size_t i = 0; i < count; i++) { |
| 425 Handle<Object> value(Smi::FromInt(static_cast<int>(42 + i)), isolate); |
423 JSObject::AddProperty(object, names[i], value, NONE); | 426 JSObject::AddProperty(object, names[i], value, NONE); |
424 } | 427 } |
425 } | 428 } |
426 | 429 |
| 430 Handle<AccessorPair> CreateAccessorPair(FunctionTester* ft, |
| 431 const char* getter_body, |
| 432 const char* setter_body) { |
| 433 Handle<AccessorPair> pair = ft->isolate->factory()->NewAccessorPair(); |
| 434 if (getter_body) { |
| 435 pair->set_getter(*ft->NewFunction(getter_body)); |
| 436 } |
| 437 if (setter_body) { |
| 438 pair->set_setter(*ft->NewFunction(setter_body)); |
| 439 } |
| 440 return pair; |
| 441 } |
| 442 |
| 443 void AddProperties(Handle<JSObject> object, Handle<Name> names[], |
| 444 size_t names_count, Handle<Object> values[], |
| 445 size_t values_count, int seed = 0) { |
| 446 Isolate* isolate = object->GetIsolate(); |
| 447 for (size_t i = 0; i < names_count; i++) { |
| 448 Handle<Object> value = values[(seed + i) % values_count]; |
| 449 if (value->IsAccessorPair()) { |
| 450 Handle<AccessorPair> pair = Handle<AccessorPair>::cast(value); |
| 451 Handle<Object> getter(pair->getter(), isolate); |
| 452 Handle<Object> setter(pair->setter(), isolate); |
| 453 JSObject::DefineAccessor(object, names[i], getter, setter, NONE).Check(); |
| 454 } else { |
| 455 JSObject::AddProperty(object, names[i], value, NONE); |
| 456 } |
| 457 } |
| 458 } |
| 459 |
427 } // namespace | 460 } // namespace |
428 | 461 |
429 TEST(TryLookupProperty) { | 462 TEST(TryHasOwnProperty) { |
430 typedef CodeStubAssembler::Label Label; | 463 typedef CodeStubAssembler::Label Label; |
431 Isolate* isolate(CcTest::InitIsolateOnce()); | 464 Isolate* isolate(CcTest::InitIsolateOnce()); |
432 | 465 |
433 const int kNumParams = 4; | 466 const int kNumParams = 4; |
434 CodeStubAssemblerTester m(isolate, kNumParams); | 467 CodeStubAssemblerTester m(isolate, kNumParams); |
435 | 468 |
436 enum Result { kFound, kNotFound, kBailout }; | 469 enum Result { kFound, kNotFound, kBailout }; |
437 { | 470 { |
438 Node* object = m.Parameter(0); | 471 Node* object = m.Parameter(0); |
439 Node* unique_name = m.Parameter(1); | 472 Node* unique_name = m.Parameter(1); |
440 Node* expected_result = m.Parameter(2); | 473 Node* expected_result = m.Parameter(2); |
441 | 474 |
442 Label passed(&m), failed(&m); | 475 Label passed(&m), failed(&m); |
443 Label if_found(&m), if_not_found(&m), if_bailout(&m); | 476 Label if_found(&m), if_not_found(&m), if_bailout(&m); |
444 | 477 |
445 Node* map = m.LoadMap(object); | 478 Node* map = m.LoadMap(object); |
446 Node* instance_type = m.LoadMapInstanceType(map); | 479 Node* instance_type = m.LoadMapInstanceType(map); |
447 | 480 |
448 m.TryLookupProperty(object, map, instance_type, unique_name, &if_found, | 481 m.TryHasOwnProperty(object, map, instance_type, unique_name, &if_found, |
449 &if_not_found, &if_bailout); | 482 &if_not_found, &if_bailout); |
450 | 483 |
451 m.Bind(&if_found); | 484 m.Bind(&if_found); |
452 m.Branch(m.WordEqual(expected_result, m.SmiConstant(Smi::FromInt(kFound))), | 485 m.Branch(m.WordEqual(expected_result, m.SmiConstant(Smi::FromInt(kFound))), |
453 &passed, &failed); | 486 &passed, &failed); |
454 | 487 |
455 m.Bind(&if_not_found); | 488 m.Bind(&if_not_found); |
456 m.Branch( | 489 m.Branch( |
457 m.WordEqual(expected_result, m.SmiConstant(Smi::FromInt(kNotFound))), | 490 m.WordEqual(expected_result, m.SmiConstant(Smi::FromInt(kNotFound))), |
458 &passed, &failed); | 491 &passed, &failed); |
(...skipping 11 matching lines...) Expand all Loading... |
470 } | 503 } |
471 | 504 |
472 Handle<Code> code = m.GenerateCode(); | 505 Handle<Code> code = m.GenerateCode(); |
473 FunctionTester ft(code, kNumParams); | 506 FunctionTester ft(code, kNumParams); |
474 | 507 |
475 Handle<Object> expect_found(Smi::FromInt(kFound), isolate); | 508 Handle<Object> expect_found(Smi::FromInt(kFound), isolate); |
476 Handle<Object> expect_not_found(Smi::FromInt(kNotFound), isolate); | 509 Handle<Object> expect_not_found(Smi::FromInt(kNotFound), isolate); |
477 Handle<Object> expect_bailout(Smi::FromInt(kBailout), isolate); | 510 Handle<Object> expect_bailout(Smi::FromInt(kBailout), isolate); |
478 | 511 |
479 Factory* factory = isolate->factory(); | 512 Factory* factory = isolate->factory(); |
| 513 |
| 514 Handle<Name> deleted_property_name = |
| 515 factory->InternalizeUtf8String("deleted"); |
| 516 |
480 Handle<Name> names[] = { | 517 Handle<Name> names[] = { |
481 factory->InternalizeUtf8String("a"), | 518 factory->InternalizeUtf8String("a"), |
482 factory->InternalizeUtf8String("bb"), | 519 factory->InternalizeUtf8String("bb"), |
483 factory->InternalizeUtf8String("ccc"), | 520 factory->InternalizeUtf8String("ccc"), |
484 factory->InternalizeUtf8String("dddd"), | 521 factory->InternalizeUtf8String("dddd"), |
485 factory->InternalizeUtf8String("eeeee"), | 522 factory->InternalizeUtf8String("eeeee"), |
486 factory->InternalizeUtf8String(""), | 523 factory->InternalizeUtf8String(""), |
487 factory->InternalizeUtf8String("name"), | 524 factory->InternalizeUtf8String("name"), |
488 factory->NewSymbol(), | 525 factory->NewSymbol(), |
489 factory->NewPrivateSymbol(), | 526 factory->NewPrivateSymbol(), |
490 }; | 527 }; |
491 | 528 |
492 std::vector<Handle<JSObject>> objects; | 529 std::vector<Handle<JSObject>> objects; |
493 | 530 |
494 { | 531 { |
495 Handle<JSFunction> function = factory->NewFunction(factory->empty_string()); | 532 // Fast object, no inobject properties. |
496 Handle<JSObject> object = factory->NewJSObject(function); | 533 int inobject_properties = 0; |
| 534 Handle<Map> map = Map::Create(isolate, inobject_properties); |
| 535 Handle<JSObject> object = factory->NewJSObjectFromMap(map); |
497 AddProperties(object, names, arraysize(names)); | 536 AddProperties(object, names, arraysize(names)); |
498 CHECK_EQ(JS_OBJECT_TYPE, object->map()->instance_type()); | 537 CHECK_EQ(JS_OBJECT_TYPE, object->map()->instance_type()); |
| 538 CHECK_EQ(inobject_properties, object->map()->GetInObjectProperties()); |
499 CHECK(!object->map()->is_dictionary_map()); | 539 CHECK(!object->map()->is_dictionary_map()); |
500 objects.push_back(object); | 540 objects.push_back(object); |
501 } | 541 } |
502 | 542 |
503 { | 543 { |
| 544 // Fast object, all inobject properties. |
| 545 int inobject_properties = arraysize(names) * 2; |
| 546 Handle<Map> map = Map::Create(isolate, inobject_properties); |
| 547 Handle<JSObject> object = factory->NewJSObjectFromMap(map); |
| 548 AddProperties(object, names, arraysize(names)); |
| 549 CHECK_EQ(JS_OBJECT_TYPE, object->map()->instance_type()); |
| 550 CHECK_EQ(inobject_properties, object->map()->GetInObjectProperties()); |
| 551 CHECK(!object->map()->is_dictionary_map()); |
| 552 objects.push_back(object); |
| 553 } |
| 554 |
| 555 { |
| 556 // Fast object, half inobject properties. |
| 557 int inobject_properties = arraysize(names) / 2; |
| 558 Handle<Map> map = Map::Create(isolate, inobject_properties); |
| 559 Handle<JSObject> object = factory->NewJSObjectFromMap(map); |
| 560 AddProperties(object, names, arraysize(names)); |
| 561 CHECK_EQ(JS_OBJECT_TYPE, object->map()->instance_type()); |
| 562 CHECK_EQ(inobject_properties, object->map()->GetInObjectProperties()); |
| 563 CHECK(!object->map()->is_dictionary_map()); |
| 564 objects.push_back(object); |
| 565 } |
| 566 |
| 567 { |
| 568 // Dictionary mode object. |
504 Handle<JSFunction> function = factory->NewFunction(factory->empty_string()); | 569 Handle<JSFunction> function = factory->NewFunction(factory->empty_string()); |
505 Handle<JSObject> object = factory->NewJSObject(function); | 570 Handle<JSObject> object = factory->NewJSObject(function); |
506 AddProperties(object, names, arraysize(names)); | 571 AddProperties(object, names, arraysize(names)); |
507 JSObject::NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0, "test"); | 572 JSObject::NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0, "test"); |
| 573 |
| 574 JSObject::AddProperty(object, deleted_property_name, object, NONE); |
| 575 CHECK(JSObject::DeleteProperty(object, deleted_property_name, SLOPPY) |
| 576 .FromJust()); |
| 577 |
508 CHECK_EQ(JS_OBJECT_TYPE, object->map()->instance_type()); | 578 CHECK_EQ(JS_OBJECT_TYPE, object->map()->instance_type()); |
509 CHECK(object->map()->is_dictionary_map()); | 579 CHECK(object->map()->is_dictionary_map()); |
510 objects.push_back(object); | 580 objects.push_back(object); |
511 } | 581 } |
512 | 582 |
513 { | 583 { |
| 584 // Global object. |
514 Handle<JSFunction> function = factory->NewFunction(factory->empty_string()); | 585 Handle<JSFunction> function = factory->NewFunction(factory->empty_string()); |
515 JSFunction::EnsureHasInitialMap(function); | 586 JSFunction::EnsureHasInitialMap(function); |
516 function->initial_map()->set_instance_type(JS_GLOBAL_OBJECT_TYPE); | 587 function->initial_map()->set_instance_type(JS_GLOBAL_OBJECT_TYPE); |
517 function->initial_map()->set_is_prototype_map(true); | 588 function->initial_map()->set_is_prototype_map(true); |
518 function->initial_map()->set_dictionary_map(true); | 589 function->initial_map()->set_dictionary_map(true); |
519 Handle<JSObject> object = factory->NewJSGlobalObject(function); | 590 Handle<JSObject> object = factory->NewJSGlobalObject(function); |
520 AddProperties(object, names, arraysize(names)); | 591 AddProperties(object, names, arraysize(names)); |
| 592 |
| 593 JSObject::AddProperty(object, deleted_property_name, object, NONE); |
| 594 CHECK(JSObject::DeleteProperty(object, deleted_property_name, SLOPPY) |
| 595 .FromJust()); |
| 596 |
521 CHECK_EQ(JS_GLOBAL_OBJECT_TYPE, object->map()->instance_type()); | 597 CHECK_EQ(JS_GLOBAL_OBJECT_TYPE, object->map()->instance_type()); |
522 CHECK(object->map()->is_dictionary_map()); | 598 CHECK(object->map()->is_dictionary_map()); |
523 objects.push_back(object); | 599 objects.push_back(object); |
524 } | 600 } |
525 | 601 |
526 { | 602 { |
527 for (Handle<JSObject> object : objects) { | 603 for (Handle<JSObject> object : objects) { |
528 for (size_t name_index = 0; name_index < arraysize(names); name_index++) { | 604 for (size_t name_index = 0; name_index < arraysize(names); name_index++) { |
529 Handle<Name> name = names[name_index]; | 605 Handle<Name> name = names[name_index]; |
530 CHECK(JSReceiver::HasProperty(object, name).FromJust()); | 606 CHECK(JSReceiver::HasProperty(object, name).FromJust()); |
531 ft.CheckTrue(object, name, expect_found); | 607 ft.CheckTrue(object, name, expect_found); |
532 } | 608 } |
533 } | 609 } |
534 } | 610 } |
535 | 611 |
536 { | 612 { |
537 Handle<Name> non_existing_names[] = { | 613 Handle<Name> non_existing_names[] = { |
| 614 factory->NewSymbol(), |
538 factory->InternalizeUtf8String("ne_a"), | 615 factory->InternalizeUtf8String("ne_a"), |
539 factory->InternalizeUtf8String("ne_bb"), | 616 factory->InternalizeUtf8String("ne_bb"), |
| 617 factory->NewPrivateSymbol(), |
540 factory->InternalizeUtf8String("ne_ccc"), | 618 factory->InternalizeUtf8String("ne_ccc"), |
541 factory->InternalizeUtf8String("ne_dddd"), | 619 factory->InternalizeUtf8String("ne_dddd"), |
| 620 deleted_property_name, |
542 }; | 621 }; |
543 for (Handle<JSObject> object : objects) { | 622 for (Handle<JSObject> object : objects) { |
544 for (size_t key_index = 0; key_index < arraysize(non_existing_names); | 623 for (size_t key_index = 0; key_index < arraysize(non_existing_names); |
545 key_index++) { | 624 key_index++) { |
546 Handle<Name> key = non_existing_names[key_index]; | 625 Handle<Name> name = non_existing_names[key_index]; |
547 CHECK(!JSReceiver::HasProperty(object, key).FromJust()); | 626 CHECK(!JSReceiver::HasProperty(object, name).FromJust()); |
548 ft.CheckTrue(object, key, expect_not_found); | 627 ft.CheckTrue(object, name, expect_not_found); |
549 } | 628 } |
550 } | 629 } |
551 } | 630 } |
552 | 631 |
553 { | 632 { |
554 Handle<JSFunction> function = factory->NewFunction(factory->empty_string()); | 633 Handle<JSFunction> function = factory->NewFunction(factory->empty_string()); |
555 Handle<JSProxy> object = factory->NewJSProxy(function, objects[0]); | 634 Handle<JSProxy> object = factory->NewJSProxy(function, objects[0]); |
556 CHECK_EQ(JS_PROXY_TYPE, object->map()->instance_type()); | 635 CHECK_EQ(JS_PROXY_TYPE, object->map()->instance_type()); |
557 ft.CheckTrue(object, names[0], expect_bailout); | 636 ft.CheckTrue(object, names[0], expect_bailout); |
558 } | 637 } |
559 | 638 |
560 { | 639 { |
561 Handle<JSObject> object = isolate->global_proxy(); | 640 Handle<JSObject> object = isolate->global_proxy(); |
562 CHECK_EQ(JS_GLOBAL_PROXY_TYPE, object->map()->instance_type()); | 641 CHECK_EQ(JS_GLOBAL_PROXY_TYPE, object->map()->instance_type()); |
563 ft.CheckTrue(object, names[0], expect_bailout); | 642 ft.CheckTrue(object, names[0], expect_bailout); |
564 } | 643 } |
565 } | 644 } |
566 | 645 |
| 646 TEST(TryGetOwnProperty) { |
| 647 typedef CodeStubAssembler::Label Label; |
| 648 typedef CodeStubAssembler::Variable Variable; |
| 649 Isolate* isolate(CcTest::InitIsolateOnce()); |
| 650 Factory* factory = isolate->factory(); |
| 651 |
| 652 const int kNumParams = 2; |
| 653 CodeStubAssemblerTester m(isolate, kNumParams); |
| 654 |
| 655 Handle<Symbol> not_found_symbol = factory->NewSymbol(); |
| 656 Handle<Symbol> bailout_symbol = factory->NewSymbol(); |
| 657 { |
| 658 Node* object = m.Parameter(0); |
| 659 Node* unique_name = m.Parameter(1); |
| 660 Node* context = m.Parameter(kNumParams + 2); |
| 661 |
| 662 Variable var_value(&m, MachineRepresentation::kTagged); |
| 663 Label if_found(&m), if_not_found(&m), if_bailout(&m); |
| 664 |
| 665 Node* map = m.LoadMap(object); |
| 666 Node* instance_type = m.LoadMapInstanceType(map); |
| 667 |
| 668 m.TryGetOwnProperty(context, object, object, map, instance_type, |
| 669 unique_name, &if_found, &var_value, &if_not_found, |
| 670 &if_bailout); |
| 671 |
| 672 m.Bind(&if_found); |
| 673 m.Return(var_value.value()); |
| 674 |
| 675 m.Bind(&if_not_found); |
| 676 m.Return(m.HeapConstant(not_found_symbol)); |
| 677 |
| 678 m.Bind(&if_bailout); |
| 679 m.Return(m.HeapConstant(bailout_symbol)); |
| 680 } |
| 681 |
| 682 Handle<Code> code = m.GenerateCode(); |
| 683 FunctionTester ft(code, kNumParams); |
| 684 |
| 685 Handle<Name> deleted_property_name = |
| 686 factory->InternalizeUtf8String("deleted"); |
| 687 |
| 688 Handle<Name> names[] = { |
| 689 factory->InternalizeUtf8String("bb"), |
| 690 factory->NewSymbol(), |
| 691 factory->InternalizeUtf8String("a"), |
| 692 factory->InternalizeUtf8String("ccc"), |
| 693 factory->InternalizeUtf8String("esajefe"), |
| 694 factory->NewPrivateSymbol(), |
| 695 factory->InternalizeUtf8String("eeeee"), |
| 696 factory->InternalizeUtf8String("p1"), |
| 697 factory->InternalizeUtf8String("acshw23e"), |
| 698 factory->InternalizeUtf8String(""), |
| 699 factory->InternalizeUtf8String("dddd"), |
| 700 factory->NewPrivateSymbol(), |
| 701 factory->InternalizeUtf8String("name"), |
| 702 factory->InternalizeUtf8String("p2"), |
| 703 factory->InternalizeUtf8String("p3"), |
| 704 factory->InternalizeUtf8String("p4"), |
| 705 factory->NewPrivateSymbol(), |
| 706 }; |
| 707 Handle<Object> values[] = { |
| 708 factory->NewFunction(factory->empty_string()), |
| 709 factory->NewSymbol(), |
| 710 factory->InternalizeUtf8String("a"), |
| 711 CreateAccessorPair(&ft, "() => 188;", "() => 199;"), |
| 712 factory->NewFunction(factory->InternalizeUtf8String("bb")), |
| 713 factory->InternalizeUtf8String("ccc"), |
| 714 CreateAccessorPair(&ft, "() => 88;", nullptr), |
| 715 handle(Smi::FromInt(1), isolate), |
| 716 factory->InternalizeUtf8String(""), |
| 717 CreateAccessorPair(&ft, nullptr, "() => 99;"), |
| 718 factory->NewHeapNumber(4.2), |
| 719 handle(Smi::FromInt(153), isolate), |
| 720 factory->NewJSObject(factory->NewFunction(factory->empty_string())), |
| 721 factory->NewPrivateSymbol(), |
| 722 }; |
| 723 STATIC_ASSERT(arraysize(values) < arraysize(names)); |
| 724 |
| 725 base::RandomNumberGenerator rand_gen(FLAG_random_seed); |
| 726 |
| 727 std::vector<Handle<JSObject>> objects; |
| 728 |
| 729 { |
| 730 // Fast object, no inobject properties. |
| 731 int inobject_properties = 0; |
| 732 Handle<Map> map = Map::Create(isolate, inobject_properties); |
| 733 Handle<JSObject> object = factory->NewJSObjectFromMap(map); |
| 734 AddProperties(object, names, arraysize(names), values, arraysize(values), |
| 735 rand_gen.NextInt()); |
| 736 CHECK_EQ(JS_OBJECT_TYPE, object->map()->instance_type()); |
| 737 CHECK_EQ(inobject_properties, object->map()->GetInObjectProperties()); |
| 738 CHECK(!object->map()->is_dictionary_map()); |
| 739 objects.push_back(object); |
| 740 } |
| 741 |
| 742 { |
| 743 // Fast object, all inobject properties. |
| 744 int inobject_properties = arraysize(names) * 2; |
| 745 Handle<Map> map = Map::Create(isolate, inobject_properties); |
| 746 Handle<JSObject> object = factory->NewJSObjectFromMap(map); |
| 747 AddProperties(object, names, arraysize(names), values, arraysize(values), |
| 748 rand_gen.NextInt()); |
| 749 CHECK_EQ(JS_OBJECT_TYPE, object->map()->instance_type()); |
| 750 CHECK_EQ(inobject_properties, object->map()->GetInObjectProperties()); |
| 751 CHECK(!object->map()->is_dictionary_map()); |
| 752 objects.push_back(object); |
| 753 } |
| 754 |
| 755 { |
| 756 // Fast object, half inobject properties. |
| 757 int inobject_properties = arraysize(names) / 2; |
| 758 Handle<Map> map = Map::Create(isolate, inobject_properties); |
| 759 Handle<JSObject> object = factory->NewJSObjectFromMap(map); |
| 760 AddProperties(object, names, arraysize(names), values, arraysize(values), |
| 761 rand_gen.NextInt()); |
| 762 CHECK_EQ(JS_OBJECT_TYPE, object->map()->instance_type()); |
| 763 CHECK_EQ(inobject_properties, object->map()->GetInObjectProperties()); |
| 764 CHECK(!object->map()->is_dictionary_map()); |
| 765 objects.push_back(object); |
| 766 } |
| 767 |
| 768 { |
| 769 // Dictionary mode object. |
| 770 Handle<JSFunction> function = factory->NewFunction(factory->empty_string()); |
| 771 Handle<JSObject> object = factory->NewJSObject(function); |
| 772 AddProperties(object, names, arraysize(names), values, arraysize(values), |
| 773 rand_gen.NextInt()); |
| 774 JSObject::NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0, "test"); |
| 775 |
| 776 JSObject::AddProperty(object, deleted_property_name, object, NONE); |
| 777 CHECK(JSObject::DeleteProperty(object, deleted_property_name, SLOPPY) |
| 778 .FromJust()); |
| 779 |
| 780 CHECK_EQ(JS_OBJECT_TYPE, object->map()->instance_type()); |
| 781 CHECK(object->map()->is_dictionary_map()); |
| 782 objects.push_back(object); |
| 783 } |
| 784 |
| 785 { |
| 786 // Global object. |
| 787 Handle<JSGlobalObject> object = isolate->global_object(); |
| 788 AddProperties(object, names, arraysize(names), values, arraysize(values), |
| 789 rand_gen.NextInt()); |
| 790 |
| 791 JSObject::AddProperty(object, deleted_property_name, object, NONE); |
| 792 CHECK(JSObject::DeleteProperty(object, deleted_property_name, SLOPPY) |
| 793 .FromJust()); |
| 794 |
| 795 CHECK_EQ(JS_GLOBAL_OBJECT_TYPE, object->map()->instance_type()); |
| 796 CHECK(object->map()->is_dictionary_map()); |
| 797 objects.push_back(object); |
| 798 } |
| 799 |
| 800 // TODO(ishell): test proxy and interceptors when they are supported. |
| 801 |
| 802 { |
| 803 for (Handle<JSObject> object : objects) { |
| 804 for (size_t name_index = 0; name_index < arraysize(names); name_index++) { |
| 805 Handle<Name> name = names[name_index]; |
| 806 Handle<Object> expected_value = |
| 807 JSReceiver::GetProperty(object, name).ToHandleChecked(); |
| 808 Handle<Object> value = ft.Call(object, name).ToHandleChecked(); |
| 809 CHECK(expected_value->SameValue(*value)); |
| 810 } |
| 811 } |
| 812 } |
| 813 |
| 814 { |
| 815 Handle<Name> non_existing_names[] = { |
| 816 factory->NewSymbol(), |
| 817 factory->InternalizeUtf8String("ne_a"), |
| 818 factory->InternalizeUtf8String("ne_bb"), |
| 819 factory->NewPrivateSymbol(), |
| 820 factory->InternalizeUtf8String("ne_ccc"), |
| 821 factory->InternalizeUtf8String("ne_dddd"), |
| 822 deleted_property_name, |
| 823 }; |
| 824 for (Handle<JSObject> object : objects) { |
| 825 for (size_t key_index = 0; key_index < arraysize(non_existing_names); |
| 826 key_index++) { |
| 827 Handle<Name> name = non_existing_names[key_index]; |
| 828 Handle<Object> expected_value = |
| 829 JSReceiver::GetProperty(object, name).ToHandleChecked(); |
| 830 CHECK(expected_value->IsUndefined(isolate)); |
| 831 Handle<Object> value = ft.Call(object, name).ToHandleChecked(); |
| 832 CHECK_EQ(*not_found_symbol, *value); |
| 833 } |
| 834 } |
| 835 } |
| 836 |
| 837 { |
| 838 Handle<JSFunction> function = factory->NewFunction(factory->empty_string()); |
| 839 Handle<JSProxy> object = factory->NewJSProxy(function, objects[0]); |
| 840 CHECK_EQ(JS_PROXY_TYPE, object->map()->instance_type()); |
| 841 Handle<Object> value = ft.Call(object, names[0]).ToHandleChecked(); |
| 842 // Proxies are not supported yet. |
| 843 CHECK_EQ(*bailout_symbol, *value); |
| 844 } |
| 845 |
| 846 { |
| 847 Handle<JSObject> object = isolate->global_proxy(); |
| 848 CHECK_EQ(JS_GLOBAL_PROXY_TYPE, object->map()->instance_type()); |
| 849 // Global proxies are not supported yet. |
| 850 Handle<Object> value = ft.Call(object, names[0]).ToHandleChecked(); |
| 851 CHECK_EQ(*bailout_symbol, *value); |
| 852 } |
| 853 } |
| 854 |
567 namespace { | 855 namespace { |
568 | 856 |
569 void AddElement(Handle<JSObject> object, uint32_t index, Handle<Object> value, | 857 void AddElement(Handle<JSObject> object, uint32_t index, Handle<Object> value, |
570 PropertyAttributes attributes = NONE) { | 858 PropertyAttributes attributes = NONE) { |
571 JSObject::AddDataElement(object, index, value, attributes).ToHandleChecked(); | 859 JSObject::AddDataElement(object, index, value, attributes).ToHandleChecked(); |
572 } | 860 } |
573 | 861 |
574 } // namespace | 862 } // namespace |
575 | 863 |
576 TEST(TryLookupElement) { | 864 TEST(TryLookupElement) { |
577 typedef CodeStubAssembler::Label Label; | 865 typedef CodeStubAssembler::Label Label; |
578 Isolate* isolate(CcTest::InitIsolateOnce()); | 866 Isolate* isolate(CcTest::InitIsolateOnce()); |
579 | 867 |
580 const int kNumParams = 4; | 868 const int kNumParams = 3; |
581 CodeStubAssemblerTester m(isolate, kNumParams); | 869 CodeStubAssemblerTester m(isolate, kNumParams); |
582 | 870 |
583 enum Result { kFound, kNotFound, kBailout }; | 871 enum Result { kFound, kNotFound, kBailout }; |
584 { | 872 { |
585 Node* object = m.Parameter(0); | 873 Node* object = m.Parameter(0); |
586 Node* index = m.SmiToWord32(m.Parameter(1)); | 874 Node* index = m.SmiToWord32(m.Parameter(1)); |
587 Node* expected_result = m.Parameter(2); | 875 Node* expected_result = m.Parameter(2); |
588 | 876 |
589 Label passed(&m), failed(&m); | 877 Label passed(&m), failed(&m); |
590 Label if_found(&m), if_not_found(&m), if_bailout(&m); | 878 Label if_found(&m), if_not_found(&m), if_bailout(&m); |
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1078 | 1366 |
1079 Handle<Code> expected_handler(handler, isolate); | 1367 Handle<Code> expected_handler(handler, isolate); |
1080 ft.CheckTrue(receiver, name, expected_handler); | 1368 ft.CheckTrue(receiver, name, expected_handler); |
1081 } | 1369 } |
1082 // Ensure we performed both kind of queries. | 1370 // Ensure we performed both kind of queries. |
1083 CHECK(queried_existing && queried_non_existing); | 1371 CHECK(queried_existing && queried_non_existing); |
1084 } | 1372 } |
1085 | 1373 |
1086 } // namespace internal | 1374 } // namespace internal |
1087 } // namespace v8 | 1375 } // namespace v8 |
OLD | NEW |