Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(64)

Side by Side Diff: src/objects.cc

Issue 146213004: A64: Synchronize with r16849. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 } 448 }
449 449
450 450
451 Handle<Object> JSProxy::SetElementWithHandler(Handle<JSProxy> proxy, 451 Handle<Object> JSProxy::SetElementWithHandler(Handle<JSProxy> proxy,
452 Handle<JSReceiver> receiver, 452 Handle<JSReceiver> receiver,
453 uint32_t index, 453 uint32_t index,
454 Handle<Object> value, 454 Handle<Object> value,
455 StrictModeFlag strict_mode) { 455 StrictModeFlag strict_mode) {
456 Isolate* isolate = proxy->GetIsolate(); 456 Isolate* isolate = proxy->GetIsolate();
457 Handle<String> name = isolate->factory()->Uint32ToString(index); 457 Handle<String> name = isolate->factory()->Uint32ToString(index);
458 CALL_HEAP_FUNCTION(isolate, 458 return SetPropertyWithHandler(
459 proxy->SetPropertyWithHandler( 459 proxy, receiver, name, value, NONE, strict_mode);
460 *receiver, *name, *value, NONE, strict_mode),
461 Object);
462 } 460 }
463 461
464 462
465 bool JSProxy::HasElementWithHandler(uint32_t index) { 463 bool JSProxy::HasElementWithHandler(Handle<JSProxy> proxy, uint32_t index) {
466 String* name; 464 Isolate* isolate = proxy->GetIsolate();
467 MaybeObject* maybe = GetHeap()->Uint32ToString(index); 465 Handle<String> name = isolate->factory()->Uint32ToString(index);
468 if (!maybe->To<String>(&name)) return maybe; 466 return HasPropertyWithHandler(proxy, name);
469 return HasPropertyWithHandler(name);
470 } 467 }
471 468
472 469
473 MaybeObject* Object::GetPropertyWithDefinedGetter(Object* receiver, 470 MaybeObject* Object::GetPropertyWithDefinedGetter(Object* receiver,
474 JSReceiver* getter) { 471 JSReceiver* getter) {
475 Isolate* isolate = getter->GetIsolate(); 472 Isolate* isolate = getter->GetIsolate();
476 HandleScope scope(isolate); 473 HandleScope scope(isolate);
477 Handle<JSReceiver> fun(getter); 474 Handle<JSReceiver> fun(getter);
478 Handle<Object> self(receiver, isolate); 475 Handle<Object> self(receiver, isolate);
479 #ifdef ENABLE_DEBUGGER_SUPPORT 476 #ifdef ENABLE_DEBUGGER_SUPPORT
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
636 ASSERT(!HasFastProperties()); 633 ASSERT(!HasFastProperties());
637 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); 634 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry());
638 if (IsGlobalObject()) { 635 if (IsGlobalObject()) {
639 value = PropertyCell::cast(value)->value(); 636 value = PropertyCell::cast(value)->value();
640 } 637 }
641 ASSERT(!value->IsPropertyCell() && !value->IsCell()); 638 ASSERT(!value->IsPropertyCell() && !value->IsCell());
642 return value; 639 return value;
643 } 640 }
644 641
645 642
646 Handle<Object> JSObject::SetNormalizedProperty(Handle<JSObject> object, 643 void JSObject::SetNormalizedProperty(Handle<JSObject> object,
647 LookupResult* result, 644 LookupResult* result,
648 Handle<Object> value) { 645 Handle<Object> value) {
649 CALL_HEAP_FUNCTION(object->GetIsolate(), 646 ASSERT(!object->HasFastProperties());
650 object->SetNormalizedProperty(result, *value), 647 NameDictionary* property_dictionary = object->property_dictionary();
651 Object); 648 if (object->IsGlobalObject()) {
649 Handle<PropertyCell> cell(PropertyCell::cast(
650 property_dictionary->ValueAt(result->GetDictionaryEntry())));
651 PropertyCell::SetValueInferType(cell, value);
652 } else {
653 property_dictionary->ValueAtPut(result->GetDictionaryEntry(), *value);
654 }
652 } 655 }
653 656
654 657
655 MaybeObject* JSObject::SetNormalizedProperty(LookupResult* result, 658 // TODO(mstarzinger): Temporary wrapper until handlified.
656 Object* value) { 659 static Handle<NameDictionary> NameDictionaryAdd(Handle<NameDictionary> dict,
657 ASSERT(!HasFastProperties()); 660 Handle<Name> name,
658 if (IsGlobalObject()) { 661 Handle<Object> value,
659 PropertyCell* cell = PropertyCell::cast( 662 PropertyDetails details) {
660 property_dictionary()->ValueAt(result->GetDictionaryEntry())); 663 CALL_HEAP_FUNCTION(dict->GetIsolate(),
661 MaybeObject* maybe_type = cell->SetValueInferType(value); 664 dict->Add(*name, *value, details),
662 if (maybe_type->IsFailure()) return maybe_type; 665 NameDictionary);
663 } else {
664 property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value);
665 }
666 return value;
667 } 666 }
668 667
669 668
670 Handle<Object> JSObject::SetNormalizedProperty(Handle<JSObject> object, 669 void JSObject::SetNormalizedProperty(Handle<JSObject> object,
671 Handle<Name> key, 670 Handle<Name> name,
672 Handle<Object> value, 671 Handle<Object> value,
673 PropertyDetails details) { 672 PropertyDetails details) {
674 CALL_HEAP_FUNCTION(object->GetIsolate(), 673 ASSERT(!object->HasFastProperties());
675 object->SetNormalizedProperty(*key, *value, details), 674 Handle<NameDictionary> property_dictionary(object->property_dictionary());
676 Object); 675 int entry = property_dictionary->FindEntry(*name);
677 }
678
679
680 MaybeObject* JSObject::SetNormalizedProperty(Name* name,
681 Object* value,
682 PropertyDetails details) {
683 ASSERT(!HasFastProperties());
684 int entry = property_dictionary()->FindEntry(name);
685 if (entry == NameDictionary::kNotFound) { 676 if (entry == NameDictionary::kNotFound) {
686 Object* store_value = value; 677 Handle<Object> store_value = value;
687 if (IsGlobalObject()) { 678 if (object->IsGlobalObject()) {
688 Heap* heap = name->GetHeap(); 679 store_value = object->GetIsolate()->factory()->NewPropertyCell(value);
689 MaybeObject* maybe_store_value = heap->AllocatePropertyCell(value);
690 if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value;
691 } 680 }
692 Object* dict; 681 property_dictionary =
693 { MaybeObject* maybe_dict = 682 NameDictionaryAdd(property_dictionary, name, store_value, details);
694 property_dictionary()->Add(name, store_value, details); 683 object->set_properties(*property_dictionary);
695 if (!maybe_dict->ToObject(&dict)) return maybe_dict; 684 return;
696 }
697 set_properties(NameDictionary::cast(dict));
698 return value;
699 } 685 }
700 686
701 PropertyDetails original_details = property_dictionary()->DetailsAt(entry); 687 PropertyDetails original_details = property_dictionary->DetailsAt(entry);
702 int enumeration_index; 688 int enumeration_index;
703 // Preserve the enumeration index unless the property was deleted. 689 // Preserve the enumeration index unless the property was deleted.
704 if (original_details.IsDeleted()) { 690 if (original_details.IsDeleted()) {
705 enumeration_index = property_dictionary()->NextEnumerationIndex(); 691 enumeration_index = property_dictionary->NextEnumerationIndex();
706 property_dictionary()->SetNextEnumerationIndex(enumeration_index + 1); 692 property_dictionary->SetNextEnumerationIndex(enumeration_index + 1);
707 } else { 693 } else {
708 enumeration_index = original_details.dictionary_index(); 694 enumeration_index = original_details.dictionary_index();
709 ASSERT(enumeration_index > 0); 695 ASSERT(enumeration_index > 0);
710 } 696 }
711 697
712 details = PropertyDetails( 698 details = PropertyDetails(
713 details.attributes(), details.type(), enumeration_index); 699 details.attributes(), details.type(), enumeration_index);
714 700
715 if (IsGlobalObject()) { 701 if (object->IsGlobalObject()) {
716 PropertyCell* cell = 702 Handle<PropertyCell> cell(
717 PropertyCell::cast(property_dictionary()->ValueAt(entry)); 703 PropertyCell::cast(property_dictionary->ValueAt(entry)));
718 MaybeObject* maybe_type = cell->SetValueInferType(value); 704 PropertyCell::SetValueInferType(cell, value);
719 if (maybe_type->IsFailure()) return maybe_type;
720 // Please note we have to update the property details. 705 // Please note we have to update the property details.
721 property_dictionary()->DetailsAtPut(entry, details); 706 property_dictionary->DetailsAtPut(entry, details);
722 } else { 707 } else {
723 property_dictionary()->SetEntry(entry, name, value, details); 708 property_dictionary->SetEntry(entry, *name, *value, details);
724 } 709 }
725 return value;
726 } 710 }
727 711
728 712
729 // TODO(mstarzinger): Temporary wrapper until target is handlified. 713 // TODO(mstarzinger): Temporary wrapper until target is handlified.
730 Handle<NameDictionary> NameDictionaryShrink(Handle<NameDictionary> dict, 714 Handle<NameDictionary> NameDictionaryShrink(Handle<NameDictionary> dict,
731 Handle<Name> name) { 715 Handle<Name> name) {
732 CALL_HEAP_FUNCTION(dict->GetIsolate(), dict->Shrink(*name), NameDictionary); 716 CALL_HEAP_FUNCTION(dict->GetIsolate(), dict->Shrink(*name), NameDictionary);
733 } 717 }
734 718
735 719
736 static void CellSetValueInferType(Handle<PropertyCell> cell,
737 Handle<Object> value) {
738 CALL_HEAP_FUNCTION_VOID(cell->GetIsolate(), cell->SetValueInferType(*value));
739 }
740
741
742 Handle<Object> JSObject::DeleteNormalizedProperty(Handle<JSObject> object, 720 Handle<Object> JSObject::DeleteNormalizedProperty(Handle<JSObject> object,
743 Handle<Name> name, 721 Handle<Name> name,
744 DeleteMode mode) { 722 DeleteMode mode) {
745 ASSERT(!object->HasFastProperties()); 723 ASSERT(!object->HasFastProperties());
746 Isolate* isolate = object->GetIsolate(); 724 Isolate* isolate = object->GetIsolate();
747 Handle<NameDictionary> dictionary(object->property_dictionary()); 725 Handle<NameDictionary> dictionary(object->property_dictionary());
748 int entry = dictionary->FindEntry(*name); 726 int entry = dictionary->FindEntry(*name);
749 if (entry != NameDictionary::kNotFound) { 727 if (entry != NameDictionary::kNotFound) {
750 // If we have a global object set the cell to the hole. 728 // If we have a global object set the cell to the hole.
751 if (object->IsGlobalObject()) { 729 if (object->IsGlobalObject()) {
752 PropertyDetails details = dictionary->DetailsAt(entry); 730 PropertyDetails details = dictionary->DetailsAt(entry);
753 if (details.IsDontDelete()) { 731 if (details.IsDontDelete()) {
754 if (mode != FORCE_DELETION) return isolate->factory()->false_value(); 732 if (mode != FORCE_DELETION) return isolate->factory()->false_value();
755 // When forced to delete global properties, we have to make a 733 // When forced to delete global properties, we have to make a
756 // map change to invalidate any ICs that think they can load 734 // map change to invalidate any ICs that think they can load
757 // from the DontDelete cell without checking if it contains 735 // from the DontDelete cell without checking if it contains
758 // the hole value. 736 // the hole value.
759 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); 737 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map()));
760 ASSERT(new_map->is_dictionary_map()); 738 ASSERT(new_map->is_dictionary_map());
761 object->set_map(*new_map); 739 object->set_map(*new_map);
762 } 740 }
763 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); 741 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry)));
764 CellSetValueInferType(cell, isolate->factory()->the_hole_value()); 742 Handle<Object> value = isolate->factory()->the_hole_value();
743 PropertyCell::SetValueInferType(cell, value);
765 dictionary->DetailsAtPut(entry, details.AsDeleted()); 744 dictionary->DetailsAtPut(entry, details.AsDeleted());
766 } else { 745 } else {
767 Handle<Object> deleted(dictionary->DeleteProperty(entry, mode), isolate); 746 Handle<Object> deleted(dictionary->DeleteProperty(entry, mode), isolate);
768 if (*deleted == isolate->heap()->true_value()) { 747 if (*deleted == isolate->heap()->true_value()) {
769 Handle<NameDictionary> new_properties = 748 Handle<NameDictionary> new_properties =
770 NameDictionaryShrink(dictionary, name); 749 NameDictionaryShrink(dictionary, name);
771 object->set_properties(*new_properties); 750 object->set_properties(*new_properties);
772 } 751 }
773 return deleted; 752 return deleted;
774 } 753 }
(...skipping 1089 matching lines...) Expand 10 before | Expand all | Expand 10 after
1864 // If the constructor is not present, return "Object". 1843 // If the constructor is not present, return "Object".
1865 return GetHeap()->Object_string(); 1844 return GetHeap()->Object_string();
1866 } 1845 }
1867 1846
1868 1847
1869 String* JSReceiver::constructor_name() { 1848 String* JSReceiver::constructor_name() {
1870 return map()->constructor_name(); 1849 return map()->constructor_name();
1871 } 1850 }
1872 1851
1873 1852
1874 MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map, 1853 // TODO(mstarzinger): Temporary wrapper until handlified.
1875 Name* name, 1854 static Handle<Object> NewStorageFor(Isolate* isolate,
1876 Object* value, 1855 Handle<Object> object,
1877 int field_index, 1856 Representation representation) {
1878 Representation representation) { 1857 Heap* heap = isolate->heap();
1858 CALL_HEAP_FUNCTION(isolate,
1859 object->AllocateNewStorageFor(heap, representation),
1860 Object);
1861 }
1862
1863
1864 void JSObject::AddFastPropertyUsingMap(Handle<JSObject> object,
1865 Handle<Map> new_map,
1866 Handle<Name> name,
1867 Handle<Object> value,
1868 int field_index,
1869 Representation representation) {
1870 Isolate* isolate = object->GetIsolate();
1871
1879 // This method is used to transition to a field. If we are transitioning to a 1872 // This method is used to transition to a field. If we are transitioning to a
1880 // double field, allocate new storage. 1873 // double field, allocate new storage.
1881 Object* storage; 1874 Handle<Object> storage = NewStorageFor(isolate, value, representation);
1882 MaybeObject* maybe_storage = 1875
1883 value->AllocateNewStorageFor(GetHeap(), representation); 1876 if (object->map()->unused_property_fields() == 0) {
1884 if (!maybe_storage->To(&storage)) return maybe_storage;
1885
1886 if (map()->unused_property_fields() == 0) {
1887 int new_unused = new_map->unused_property_fields(); 1877 int new_unused = new_map->unused_property_fields();
1888 FixedArray* values; 1878 Handle<FixedArray> properties(object->properties());
1889 MaybeObject* maybe_values = 1879 Handle<FixedArray> values = isolate->factory()->CopySizeFixedArray(
1890 properties()->CopySize(properties()->length() + new_unused + 1); 1880 properties, properties->length() + new_unused + 1);
1891 if (!maybe_values->To(&values)) return maybe_values; 1881 object->set_properties(*values);
1892 1882 }
1893 set_properties(values); 1883
1894 } 1884 object->set_map(*new_map);
1895 1885 object->FastPropertyAtPut(field_index, *storage);
1896 set_map(new_map); 1886 }
1897 1887
1898 FastPropertyAtPut(field_index, storage); 1888
1899 return value; 1889 static MaybeObject* CopyAddFieldDescriptor(Map* map,
1900 } 1890 Name* name,
1901 1891 int index,
1902 1892 PropertyAttributes attributes,
1903 MaybeObject* JSObject::AddFastProperty(Name* name, 1893 Representation representation,
1904 Object* value, 1894 TransitionFlag flag) {
1905 PropertyAttributes attributes, 1895 Map* new_map;
1906 StoreFromKeyed store_mode, 1896 FieldDescriptor new_field_desc(name, index, attributes, representation);
1907 ValueType value_type, 1897 MaybeObject* maybe_map = map->CopyAddDescriptor(&new_field_desc, flag);
1908 TransitionFlag flag) { 1898 if (!maybe_map->To(&new_map)) return maybe_map;
1909 ASSERT(!IsJSGlobalProxy()); 1899 int unused_property_fields = map->unused_property_fields() - 1;
1900 if (unused_property_fields < 0) {
1901 unused_property_fields += JSObject::kFieldsAdded;
1902 }
1903 new_map->set_unused_property_fields(unused_property_fields);
1904 return new_map;
1905 }
1906
1907
1908 static Handle<Map> CopyAddFieldDescriptor(Handle<Map> map,
1909 Handle<Name> name,
1910 int index,
1911 PropertyAttributes attributes,
1912 Representation representation,
1913 TransitionFlag flag) {
1914 CALL_HEAP_FUNCTION(map->GetIsolate(),
1915 CopyAddFieldDescriptor(
1916 *map, *name, index, attributes, representation, flag),
1917 Map);
1918 }
1919
1920
1921 void JSObject::AddFastProperty(Handle<JSObject> object,
1922 Handle<Name> name,
1923 Handle<Object> value,
1924 PropertyAttributes attributes,
1925 StoreFromKeyed store_mode,
1926 ValueType value_type,
1927 TransitionFlag flag) {
1928 ASSERT(!object->IsJSGlobalProxy());
1910 ASSERT(DescriptorArray::kNotFound == 1929 ASSERT(DescriptorArray::kNotFound ==
1911 map()->instance_descriptors()->Search( 1930 object->map()->instance_descriptors()->Search(
1912 name, map()->NumberOfOwnDescriptors())); 1931 *name, object->map()->NumberOfOwnDescriptors()));
1913 1932
1914 // Normalize the object if the name is an actual name (not the 1933 // Normalize the object if the name is an actual name (not the
1915 // hidden strings) and is not a real identifier. 1934 // hidden strings) and is not a real identifier.
1916 // Normalize the object if it will have too many fast properties. 1935 // Normalize the object if it will have too many fast properties.
1917 Isolate* isolate = GetHeap()->isolate(); 1936 Isolate* isolate = object->GetIsolate();
1918 if (!name->IsCacheable(isolate) || TooManyFastProperties(store_mode)) { 1937 if (!name->IsCacheable(isolate) ||
1919 MaybeObject* maybe_failure = 1938 object->TooManyFastProperties(store_mode)) {
1920 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); 1939 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
1921 if (maybe_failure->IsFailure()) return maybe_failure; 1940 AddSlowProperty(object, name, value, attributes);
1922 return AddSlowProperty(name, value, attributes); 1941 return;
1923 } 1942 }
1924 1943
1925 // Compute the new index for new field. 1944 // Compute the new index for new field.
1926 int index = map()->NextFreePropertyIndex(); 1945 int index = object->map()->NextFreePropertyIndex();
1927 1946
1928 // Allocate new instance descriptors with (name, index) added 1947 // Allocate new instance descriptors with (name, index) added
1929 if (IsJSContextExtensionObject()) value_type = FORCE_TAGGED; 1948 if (object->IsJSContextExtensionObject()) value_type = FORCE_TAGGED;
1930 Representation representation = value->OptimalRepresentation(value_type); 1949 Representation representation = value->OptimalRepresentation(value_type);
1931 1950 Handle<Map> new_map = CopyAddFieldDescriptor(
1932 FieldDescriptor new_field(name, index, attributes, representation); 1951 handle(object->map()), name, index, attributes, representation, flag);
1933 1952
1934 Map* new_map; 1953 AddFastPropertyUsingMap(object, new_map, name, value, index, representation);
1935 MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&new_field, flag); 1954 }
1936 if (!maybe_new_map->To(&new_map)) return maybe_new_map; 1955
1937 1956
1938 int unused_property_fields = map()->unused_property_fields() - 1; 1957 static MaybeObject* CopyAddConstantDescriptor(Map* map,
1939 if (unused_property_fields < 0) { 1958 Name* name,
1940 unused_property_fields += kFieldsAdded; 1959 Object* value,
1941 } 1960 PropertyAttributes attributes,
1942 new_map->set_unused_property_fields(unused_property_fields); 1961 TransitionFlag flag) {
1943 1962 ConstantDescriptor new_constant_desc(name, value, attributes);
1944 return AddFastPropertyUsingMap(new_map, name, value, index, representation); 1963 return map->CopyAddDescriptor(&new_constant_desc, flag);
1945 } 1964 }
1946 1965
1947 1966
1948 MaybeObject* JSObject::AddConstantProperty( 1967 static Handle<Map> CopyAddConstantDescriptor(Handle<Map> map,
1949 Name* name, 1968 Handle<Name> name,
1950 Object* constant, 1969 Handle<Object> value,
1951 PropertyAttributes attributes, 1970 PropertyAttributes attributes,
1952 TransitionFlag initial_flag) { 1971 TransitionFlag flag) {
1953 // Allocate new instance descriptors with (name, constant) added 1972 CALL_HEAP_FUNCTION(map->GetIsolate(),
1954 ConstantDescriptor d(name, constant, attributes); 1973 CopyAddConstantDescriptor(
1955 1974 *map, *name, *value, attributes, flag),
1975 Map);
1976 }
1977
1978
1979 void JSObject::AddConstantProperty(Handle<JSObject> object,
1980 Handle<Name> name,
1981 Handle<Object> constant,
1982 PropertyAttributes attributes,
1983 TransitionFlag initial_flag) {
1956 TransitionFlag flag = 1984 TransitionFlag flag =
1957 // Do not add transitions to global objects. 1985 // Do not add transitions to global objects.
1958 (IsGlobalObject() || 1986 (object->IsGlobalObject() ||
1959 // Don't add transitions to special properties with non-trivial 1987 // Don't add transitions to special properties with non-trivial
1960 // attributes. 1988 // attributes.
1961 attributes != NONE) 1989 attributes != NONE)
1962 ? OMIT_TRANSITION 1990 ? OMIT_TRANSITION
1963 : initial_flag; 1991 : initial_flag;
1964 1992
1965 Map* new_map; 1993 // Allocate new instance descriptors with (name, constant) added.
1966 MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&d, flag); 1994 Handle<Map> new_map = CopyAddConstantDescriptor(
1967 if (!maybe_new_map->To(&new_map)) return maybe_new_map; 1995 handle(object->map()), name, constant, attributes, flag);
1968 1996
1969 set_map(new_map); 1997 object->set_map(*new_map);
1970 return constant; 1998 }
1971 } 1999
1972 2000
1973 2001 void JSObject::AddSlowProperty(Handle<JSObject> object,
1974 // Add property in slow mode 2002 Handle<Name> name,
1975 MaybeObject* JSObject::AddSlowProperty(Name* name, 2003 Handle<Object> value,
1976 Object* value, 2004 PropertyAttributes attributes) {
1977 PropertyAttributes attributes) { 2005 ASSERT(!object->HasFastProperties());
1978 ASSERT(!HasFastProperties()); 2006 Isolate* isolate = object->GetIsolate();
1979 NameDictionary* dict = property_dictionary(); 2007 Handle<NameDictionary> dict(object->property_dictionary());
1980 Object* store_value = value; 2008 if (object->IsGlobalObject()) {
1981 if (IsGlobalObject()) {
1982 // In case name is an orphaned property reuse the cell. 2009 // In case name is an orphaned property reuse the cell.
1983 int entry = dict->FindEntry(name); 2010 int entry = dict->FindEntry(*name);
1984 if (entry != NameDictionary::kNotFound) { 2011 if (entry != NameDictionary::kNotFound) {
1985 store_value = dict->ValueAt(entry); 2012 Handle<PropertyCell> cell(PropertyCell::cast(dict->ValueAt(entry)));
1986 MaybeObject* maybe_type = 2013 PropertyCell::SetValueInferType(cell, value);
1987 PropertyCell::cast(store_value)->SetValueInferType(value);
1988 if (maybe_type->IsFailure()) return maybe_type;
1989 // Assign an enumeration index to the property and update 2014 // Assign an enumeration index to the property and update
1990 // SetNextEnumerationIndex. 2015 // SetNextEnumerationIndex.
1991 int index = dict->NextEnumerationIndex(); 2016 int index = dict->NextEnumerationIndex();
1992 PropertyDetails details = PropertyDetails(attributes, NORMAL, index); 2017 PropertyDetails details = PropertyDetails(attributes, NORMAL, index);
1993 dict->SetNextEnumerationIndex(index + 1); 2018 dict->SetNextEnumerationIndex(index + 1);
1994 dict->SetEntry(entry, name, store_value, details); 2019 dict->SetEntry(entry, *name, *cell, details);
1995 return value; 2020 return;
1996 } 2021 }
1997 Heap* heap = GetHeap(); 2022 Handle<PropertyCell> cell = isolate->factory()->NewPropertyCell(value);
1998 { MaybeObject* maybe_store_value = 2023 PropertyCell::SetValueInferType(cell, value);
1999 heap->AllocatePropertyCell(value); 2024 value = cell;
2000 if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value;
2001 }
2002 MaybeObject* maybe_type =
2003 PropertyCell::cast(store_value)->SetValueInferType(value);
2004 if (maybe_type->IsFailure()) return maybe_type;
2005 } 2025 }
2006 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0); 2026 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0);
2007 Object* result; 2027 Handle<NameDictionary> result = NameDictionaryAdd(dict, name, value, details);
2008 { MaybeObject* maybe_result = dict->Add(name, store_value, details); 2028 if (*dict != *result) object->set_properties(*result);
2009 if (!maybe_result->ToObject(&result)) return maybe_result; 2029 }
2010 } 2030
2011 if (dict != result) set_properties(NameDictionary::cast(result)); 2031
2012 return value; 2032 Handle<Object> JSObject::AddProperty(Handle<JSObject> object,
2013 } 2033 Handle<Name> name,
2014 2034 Handle<Object> value,
2015 2035 PropertyAttributes attributes,
2016 MaybeObject* JSObject::AddProperty(Name* name, 2036 StrictModeFlag strict_mode,
2017 Object* value, 2037 JSReceiver::StoreFromKeyed store_mode,
2018 PropertyAttributes attributes, 2038 ExtensibilityCheck extensibility_check,
2019 StrictModeFlag strict_mode, 2039 ValueType value_type,
2020 JSReceiver::StoreFromKeyed store_mode, 2040 StoreMode mode,
2021 ExtensibilityCheck extensibility_check, 2041 TransitionFlag transition_flag) {
2022 ValueType value_type, 2042 ASSERT(!object->IsJSGlobalProxy());
2023 StoreMode mode, 2043 Isolate* isolate = object->GetIsolate();
2024 TransitionFlag transition_flag) {
2025 ASSERT(!IsJSGlobalProxy());
2026 Map* map_of_this = map();
2027 Heap* heap = GetHeap();
2028 Isolate* isolate = heap->isolate();
2029 MaybeObject* result;
2030 if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK && 2044 if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK &&
2031 !map_of_this->is_extensible()) { 2045 !object->map()->is_extensible()) {
2032 if (strict_mode == kNonStrictMode) { 2046 if (strict_mode == kNonStrictMode) {
2033 return value; 2047 return value;
2034 } else { 2048 } else {
2035 Handle<Object> args[1] = {Handle<Name>(name)}; 2049 Handle<Object> args[1] = { name };
2036 return isolate->Throw( 2050 Handle<Object> error = isolate->factory()->NewTypeError(
2037 *isolate->factory()->NewTypeError("object_not_extensible", 2051 "object_not_extensible", HandleVector(args, ARRAY_SIZE(args)));
2038 HandleVector(args, 1))); 2052 isolate->Throw(*error);
2053 return Handle<Object>();
2039 } 2054 }
2040 } 2055 }
2041 2056
2042 if (HasFastProperties()) { 2057 if (object->HasFastProperties()) {
2043 // Ensure the descriptor array does not get too big. 2058 // Ensure the descriptor array does not get too big.
2044 if (map_of_this->NumberOfOwnDescriptors() < 2059 if (object->map()->NumberOfOwnDescriptors() <
2045 DescriptorArray::kMaxNumberOfDescriptors) { 2060 DescriptorArray::kMaxNumberOfDescriptors) {
2046 // TODO(verwaest): Support other constants. 2061 // TODO(verwaest): Support other constants.
2047 // if (mode == ALLOW_AS_CONSTANT && 2062 // if (mode == ALLOW_AS_CONSTANT &&
2048 // !value->IsTheHole() && 2063 // !value->IsTheHole() &&
2049 // !value->IsConsString()) { 2064 // !value->IsConsString()) {
2050 if (value->IsJSFunction()) { 2065 if (value->IsJSFunction()) {
2051 result = AddConstantProperty(name, value, attributes, transition_flag); 2066 AddConstantProperty(object, name, value, attributes, transition_flag);
2052 } else { 2067 } else {
2053 result = AddFastProperty( 2068 AddFastProperty(object, name, value, attributes, store_mode,
2054 name, value, attributes, store_mode, value_type, transition_flag); 2069 value_type, transition_flag);
2055 } 2070 }
2056 } else { 2071 } else {
2057 // Normalize the object to prevent very large instance descriptors. 2072 // Normalize the object to prevent very large instance descriptors.
2058 // This eliminates unwanted N^2 allocation and lookup behavior. 2073 // This eliminates unwanted N^2 allocation and lookup behavior.
2059 Object* obj; 2074 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
2060 MaybeObject* maybe = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); 2075 AddSlowProperty(object, name, value, attributes);
2061 if (!maybe->To(&obj)) return maybe;
2062 result = AddSlowProperty(name, value, attributes);
2063 } 2076 }
2064 } else { 2077 } else {
2065 result = AddSlowProperty(name, value, attributes); 2078 AddSlowProperty(object, name, value, attributes);
2066 } 2079 }
2067 2080
2068 Handle<Object> hresult; 2081 if (FLAG_harmony_observation && object->map()->is_observed()) {
2069 if (!result->ToHandle(&hresult, isolate)) return result; 2082 Handle<Object> old_value = isolate->factory()->the_hole_value();
2070 2083 EnqueueChangeRecord(object, "new", name, old_value);
2071 if (FLAG_harmony_observation && map()->is_observed()) { 2084 }
2072 EnqueueChangeRecord(handle(this, isolate), 2085
2073 "new", 2086 return value;
2074 handle(name, isolate), 2087 }
2075 handle(heap->the_hole_value(), isolate)); 2088
2076 } 2089
2077
2078 return *hresult;
2079 }
2080
2081
2082 void JSObject::EnqueueChangeRecord(Handle<JSObject> object, 2090 void JSObject::EnqueueChangeRecord(Handle<JSObject> object,
2083 const char* type_str, 2091 const char* type_str,
2084 Handle<Name> name, 2092 Handle<Name> name,
2085 Handle<Object> old_value) { 2093 Handle<Object> old_value) {
2086 Isolate* isolate = object->GetIsolate(); 2094 Isolate* isolate = object->GetIsolate();
2087 HandleScope scope(isolate); 2095 HandleScope scope(isolate);
2088 Handle<String> type = isolate->factory()->InternalizeUtf8String(type_str); 2096 Handle<String> type = isolate->factory()->InternalizeUtf8String(type_str);
2089 if (object->IsJSGlobalObject()) { 2097 if (object->IsJSGlobalObject()) {
2090 object = handle(JSGlobalObject::cast(*object)->global_receiver(), isolate); 2098 object = handle(JSGlobalObject::cast(*object)->global_receiver(), isolate);
2091 } 2099 }
(...skipping 16 matching lines...) Expand all
2108 isolate->observers_deliver_changes(), 2116 isolate->observers_deliver_changes(),
2109 isolate->factory()->undefined_value(), 2117 isolate->factory()->undefined_value(),
2110 0, 2118 0,
2111 NULL, 2119 NULL,
2112 &threw); 2120 &threw);
2113 ASSERT(!threw); 2121 ASSERT(!threw);
2114 isolate->set_observer_delivery_pending(false); 2122 isolate->set_observer_delivery_pending(false);
2115 } 2123 }
2116 2124
2117 2125
2118 MaybeObject* JSObject::SetPropertyPostInterceptor( 2126 Handle<Object> JSObject::SetPropertyPostInterceptor(
2119 Name* name, 2127 Handle<JSObject> object,
2120 Object* value, 2128 Handle<Name> name,
2129 Handle<Object> value,
2121 PropertyAttributes attributes, 2130 PropertyAttributes attributes,
2122 StrictModeFlag strict_mode, 2131 StrictModeFlag strict_mode) {
2123 StoreMode mode) {
2124 // Check local property, ignore interceptor. 2132 // Check local property, ignore interceptor.
2125 LookupResult result(GetIsolate()); 2133 LookupResult result(object->GetIsolate());
2126 LocalLookupRealNamedProperty(name, &result); 2134 object->LocalLookupRealNamedProperty(*name, &result);
2127 if (!result.IsFound()) map()->LookupTransition(this, name, &result); 2135 if (!result.IsFound()) {
2136 object->map()->LookupTransition(*object, *name, &result);
2137 }
2128 if (result.IsFound()) { 2138 if (result.IsFound()) {
2129 // An existing property or a map transition was found. Use set property to 2139 // An existing property or a map transition was found. Use set property to
2130 // handle all these cases. 2140 // handle all these cases.
2131 return SetProperty(&result, name, value, attributes, strict_mode); 2141 return SetPropertyForResult(object, &result, name, value, attributes,
2142 strict_mode, MAY_BE_STORE_FROM_KEYED);
2132 } 2143 }
2133 bool done = false; 2144 bool done = false;
2134 MaybeObject* result_object = 2145 Handle<Object> result_object = SetPropertyViaPrototypes(
2135 SetPropertyViaPrototypes(name, value, attributes, strict_mode, &done); 2146 object, name, value, attributes, strict_mode, &done);
2136 if (done) return result_object; 2147 if (done) return result_object;
2137 // Add a new real property. 2148 // Add a new real property.
2138 return AddProperty(name, value, attributes, strict_mode, 2149 return AddProperty(object, name, value, attributes, strict_mode);
2139 MAY_BE_STORE_FROM_KEYED, PERFORM_EXTENSIBILITY_CHECK,
2140 OPTIMAL_REPRESENTATION, mode);
2141 } 2150 }
2142 2151
2143 2152
2144 MaybeObject* JSObject::ReplaceSlowProperty(Name* name, 2153 static void ReplaceSlowProperty(Handle<JSObject> object,
2145 Object* value, 2154 Handle<Name> name,
2146 PropertyAttributes attributes) { 2155 Handle<Object> value,
2147 NameDictionary* dictionary = property_dictionary(); 2156 PropertyAttributes attributes) {
2148 int old_index = dictionary->FindEntry(name); 2157 NameDictionary* dictionary = object->property_dictionary();
2158 int old_index = dictionary->FindEntry(*name);
2149 int new_enumeration_index = 0; // 0 means "Use the next available index." 2159 int new_enumeration_index = 0; // 0 means "Use the next available index."
2150 if (old_index != -1) { 2160 if (old_index != -1) {
2151 // All calls to ReplaceSlowProperty have had all transitions removed. 2161 // All calls to ReplaceSlowProperty have had all transitions removed.
2152 new_enumeration_index = dictionary->DetailsAt(old_index).dictionary_index(); 2162 new_enumeration_index = dictionary->DetailsAt(old_index).dictionary_index();
2153 } 2163 }
2154 2164
2155 PropertyDetails new_details(attributes, NORMAL, new_enumeration_index); 2165 PropertyDetails new_details(attributes, NORMAL, new_enumeration_index);
2156 return SetNormalizedProperty(name, value, new_details); 2166 JSObject::SetNormalizedProperty(object, name, value, new_details);
2157 } 2167 }
2158 2168
2159 2169
2160 const char* Representation::Mnemonic() const { 2170 const char* Representation::Mnemonic() const {
2161 switch (kind_) { 2171 switch (kind_) {
2162 case kNone: return "v"; 2172 case kNone: return "v";
2163 case kTagged: return "t"; 2173 case kTagged: return "t";
2164 case kSmi: return "s"; 2174 case kSmi: return "s";
2165 case kDouble: return "d"; 2175 case kDouble: return "d";
2166 case kInteger32: return "i"; 2176 case kInteger32: return "i";
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
2253 ASSERT(target_inobject < inobject_properties()); 2263 ASSERT(target_inobject < inobject_properties());
2254 if (target_number_of_fields <= target_inobject) { 2264 if (target_number_of_fields <= target_inobject) {
2255 ASSERT(target_number_of_fields + target_unused == target_inobject); 2265 ASSERT(target_number_of_fields + target_unused == target_inobject);
2256 return false; 2266 return false;
2257 } 2267 }
2258 // Otherwise, properties will need to be moved to the backing store. 2268 // Otherwise, properties will need to be moved to the backing store.
2259 return true; 2269 return true;
2260 } 2270 }
2261 2271
2262 2272
2273 void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) {
2274 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), object->MigrateToMap(*new_map));
2275 }
2276
2277
2263 // To migrate an instance to a map: 2278 // To migrate an instance to a map:
2264 // - First check whether the instance needs to be rewritten. If not, simply 2279 // - First check whether the instance needs to be rewritten. If not, simply
2265 // change the map. 2280 // change the map.
2266 // - Otherwise, allocate a fixed array large enough to hold all fields, in 2281 // - Otherwise, allocate a fixed array large enough to hold all fields, in
2267 // addition to unused space. 2282 // addition to unused space.
2268 // - Copy all existing properties in, in the following order: backing store 2283 // - Copy all existing properties in, in the following order: backing store
2269 // properties, unused fields, inobject properties. 2284 // properties, unused fields, inobject properties.
2270 // - If all allocation succeeded, commit the state atomically: 2285 // - If all allocation succeeded, commit the state atomically:
2271 // * Copy inobject properties from the backing store back into the object. 2286 // * Copy inobject properties from the backing store back into the object.
2272 // * Trim the difference in instance size of the object. This also cleanly 2287 // * Trim the difference in instance size of the object. This also cleanly
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
2354 RightTrimFixedArray<FROM_MUTATOR>(heap, array, inobject); 2369 RightTrimFixedArray<FROM_MUTATOR>(heap, array, inobject);
2355 set_properties(array); 2370 set_properties(array);
2356 } 2371 }
2357 2372
2358 set_map(new_map); 2373 set_map(new_map);
2359 2374
2360 return this; 2375 return this;
2361 } 2376 }
2362 2377
2363 2378
2364 MaybeObject* JSObject::GeneralizeFieldRepresentation( 2379 void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object,
2365 int modify_index, 2380 int modify_index,
2366 Representation new_representation, 2381 Representation new_representation,
2367 StoreMode store_mode) { 2382 StoreMode store_mode) {
2368 Map* new_map; 2383 Handle<Map> new_map = Map::GeneralizeRepresentation(
2369 MaybeObject* maybe_new_map = map()->GeneralizeRepresentation( 2384 handle(object->map()), modify_index, new_representation, store_mode);
2370 modify_index, new_representation, store_mode); 2385 if (object->map() == *new_map) return;
2371 if (!maybe_new_map->To(&new_map)) return maybe_new_map; 2386 return MigrateToMap(object, new_map);
2372 if (map() == new_map) return this;
2373
2374 return MigrateToMap(new_map);
2375 } 2387 }
2376 2388
2377 2389
2378 int Map::NumberOfFields() { 2390 int Map::NumberOfFields() {
2379 DescriptorArray* descriptors = instance_descriptors(); 2391 DescriptorArray* descriptors = instance_descriptors();
2380 int result = 0; 2392 int result = 0;
2381 for (int i = 0; i < NumberOfOwnDescriptors(); i++) { 2393 for (int i = 0; i < NumberOfOwnDescriptors(); i++) {
2382 if (descriptors->GetDetails(i).type() == FIELD) result++; 2394 if (descriptors->GetDetails(i).type() == FIELD) result++;
2383 } 2395 }
2384 return result; 2396 return result;
2385 } 2397 }
2386 2398
2387 2399
2388 MaybeObject* Map::CopyGeneralizeAllRepresentations( 2400 Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map,
2389 int modify_index, 2401 int modify_index,
2390 StoreMode store_mode, 2402 StoreMode store_mode,
2391 PropertyAttributes attributes, 2403 PropertyAttributes attributes,
2392 const char* reason) { 2404 const char* reason) {
2393 Map* new_map; 2405 Handle<Map> new_map = Copy(map);
2394 MaybeObject* maybe_map = this->Copy();
2395 if (!maybe_map->To(&new_map)) return maybe_map;
2396 2406
2397 DescriptorArray* descriptors = new_map->instance_descriptors(); 2407 DescriptorArray* descriptors = new_map->instance_descriptors();
2398 descriptors->InitializeRepresentations(Representation::Tagged()); 2408 descriptors->InitializeRepresentations(Representation::Tagged());
2399 2409
2400 // Unless the instance is being migrated, ensure that modify_index is a field. 2410 // Unless the instance is being migrated, ensure that modify_index is a field.
2401 PropertyDetails details = descriptors->GetDetails(modify_index); 2411 PropertyDetails details = descriptors->GetDetails(modify_index);
2402 if (store_mode == FORCE_FIELD && details.type() != FIELD) { 2412 if (store_mode == FORCE_FIELD && details.type() != FIELD) {
2403 FieldDescriptor d(descriptors->GetKey(modify_index), 2413 FieldDescriptor d(descriptors->GetKey(modify_index),
2404 new_map->NumberOfFields(), 2414 new_map->NumberOfFields(),
2405 attributes, 2415 attributes,
2406 Representation::Tagged()); 2416 Representation::Tagged());
2407 d.SetSortedKeyIndex(details.pointer()); 2417 d.SetSortedKeyIndex(details.pointer());
2408 descriptors->Set(modify_index, &d); 2418 descriptors->Set(modify_index, &d);
2409 int unused_property_fields = new_map->unused_property_fields() - 1; 2419 int unused_property_fields = new_map->unused_property_fields() - 1;
2410 if (unused_property_fields < 0) { 2420 if (unused_property_fields < 0) {
2411 unused_property_fields += JSObject::kFieldsAdded; 2421 unused_property_fields += JSObject::kFieldsAdded;
2412 } 2422 }
2413 new_map->set_unused_property_fields(unused_property_fields); 2423 new_map->set_unused_property_fields(unused_property_fields);
2414 } 2424 }
2415 2425
2416 if (FLAG_trace_generalization) { 2426 if (FLAG_trace_generalization) {
2417 PrintGeneralization(stdout, reason, modify_index, 2427 map->PrintGeneralization(stdout, reason, modify_index,
2418 new_map->NumberOfOwnDescriptors(), 2428 new_map->NumberOfOwnDescriptors(),
2419 new_map->NumberOfOwnDescriptors(), 2429 new_map->NumberOfOwnDescriptors(),
2420 details.type() == CONSTANT && store_mode == FORCE_FIELD, 2430 details.type() == CONSTANT && store_mode == FORCE_FIELD,
2421 Representation::Tagged(), Representation::Tagged()); 2431 Representation::Tagged(), Representation::Tagged());
2422 } 2432 }
2423 return new_map; 2433 return new_map;
2424 } 2434 }
2425 2435
2426 2436
2427 void Map::DeprecateTransitionTree() { 2437 void Map::DeprecateTransitionTree() {
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
2555 // FindUpdatedMap. This uses the keys in the own map's descriptor array to 2565 // FindUpdatedMap. This uses the keys in the own map's descriptor array to
2556 // walk the transition tree. 2566 // walk the transition tree.
2557 // - Merge/generalize the descriptor array of the current map and |updated|. 2567 // - Merge/generalize the descriptor array of the current map and |updated|.
2558 // - Generalize the |modify_index| descriptor using |new_representation|. 2568 // - Generalize the |modify_index| descriptor using |new_representation|.
2559 // - Walk the tree again starting from the root towards |updated|. Stop at 2569 // - Walk the tree again starting from the root towards |updated|. Stop at
2560 // |split_map|, the first map who's descriptor array does not match the merged 2570 // |split_map|, the first map who's descriptor array does not match the merged
2561 // descriptor array. 2571 // descriptor array.
2562 // - If |updated| == |split_map|, |updated| is in the expected state. Return it. 2572 // - If |updated| == |split_map|, |updated| is in the expected state. Return it.
2563 // - Otherwise, invalidate the outdated transition target from |updated|, and 2573 // - Otherwise, invalidate the outdated transition target from |updated|, and
2564 // replace its transition tree with a new branch for the updated descriptors. 2574 // replace its transition tree with a new branch for the updated descriptors.
2565 MaybeObject* Map::GeneralizeRepresentation(int modify_index, 2575 Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map,
2566 Representation new_representation, 2576 int modify_index,
2567 StoreMode store_mode) { 2577 Representation new_representation,
2568 Map* old_map = this; 2578 StoreMode store_mode) {
2569 DescriptorArray* old_descriptors = old_map->instance_descriptors(); 2579 Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors());
2570 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); 2580 PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
2571 Representation old_representation = old_details.representation(); 2581 Representation old_representation = old_details.representation();
2572 2582
2573 // It's fine to transition from None to anything but double without any 2583 // It's fine to transition from None to anything but double without any
2574 // modification to the object, because the default uninitialized value for 2584 // modification to the object, because the default uninitialized value for
2575 // representation None can be overwritten by both smi and tagged values. 2585 // representation None can be overwritten by both smi and tagged values.
2576 // Doubles, however, would require a box allocation. 2586 // Doubles, however, would require a box allocation.
2577 if (old_representation.IsNone() && 2587 if (old_representation.IsNone() &&
2578 !new_representation.IsNone() && 2588 !new_representation.IsNone() &&
2579 !new_representation.IsDouble()) { 2589 !new_representation.IsDouble()) {
2580 old_descriptors->SetRepresentation(modify_index, new_representation); 2590 old_descriptors->SetRepresentation(modify_index, new_representation);
2581 return old_map; 2591 return old_map;
2582 } 2592 }
2583 2593
2584 int descriptors = old_map->NumberOfOwnDescriptors(); 2594 int descriptors = old_map->NumberOfOwnDescriptors();
2585 Map* root_map = old_map->FindRootMap(); 2595 Handle<Map> root_map(old_map->FindRootMap());
2586 2596
2587 // Check the state of the root map. 2597 // Check the state of the root map.
2588 if (!old_map->EquivalentToForTransition(root_map)) { 2598 if (!old_map->EquivalentToForTransition(*root_map)) {
2589 return CopyGeneralizeAllRepresentations( 2599 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
2590 modify_index, store_mode, old_details.attributes(), "not equivalent"); 2600 old_details.attributes(), "not equivalent");
2591 } 2601 }
2592 2602
2593 int verbatim = root_map->NumberOfOwnDescriptors(); 2603 int verbatim = root_map->NumberOfOwnDescriptors();
2594 2604
2595 if (store_mode != ALLOW_AS_CONSTANT && modify_index < verbatim) { 2605 if (store_mode != ALLOW_AS_CONSTANT && modify_index < verbatim) {
2596 return CopyGeneralizeAllRepresentations( 2606 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
2597 modify_index, store_mode,
2598 old_details.attributes(), "root modification"); 2607 old_details.attributes(), "root modification");
2599 } 2608 }
2600 2609
2601 Map* updated = root_map->FindUpdatedMap( 2610 Map* raw_updated = root_map->FindUpdatedMap(
2602 verbatim, descriptors, old_descriptors); 2611 verbatim, descriptors, *old_descriptors);
2603 if (updated == NULL) { 2612 if (raw_updated == NULL) {
2604 return CopyGeneralizeAllRepresentations( 2613 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
2605 modify_index, store_mode, old_details.attributes(), "incompatible"); 2614 old_details.attributes(), "incompatible");
2606 } 2615 }
2607 2616
2608 DescriptorArray* updated_descriptors = updated->instance_descriptors(); 2617 Handle<Map> updated(raw_updated);
2618 Handle<DescriptorArray> updated_descriptors(updated->instance_descriptors());
2609 2619
2610 int valid = updated->NumberOfOwnDescriptors(); 2620 int valid = updated->NumberOfOwnDescriptors();
2611 2621
2612 // Directly change the map if the target map is more general. Ensure that the 2622 // Directly change the map if the target map is more general. Ensure that the
2613 // target type of the modify_index is a FIELD, unless we are migrating. 2623 // target type of the modify_index is a FIELD, unless we are migrating.
2614 if (updated_descriptors->IsMoreGeneralThan( 2624 if (updated_descriptors->IsMoreGeneralThan(
2615 verbatim, valid, descriptors, old_descriptors) && 2625 verbatim, valid, descriptors, *old_descriptors) &&
2616 (store_mode == ALLOW_AS_CONSTANT || 2626 (store_mode == ALLOW_AS_CONSTANT ||
2617 updated_descriptors->GetDetails(modify_index).type() == FIELD)) { 2627 updated_descriptors->GetDetails(modify_index).type() == FIELD)) {
2618 Representation updated_representation = 2628 Representation updated_representation =
2619 updated_descriptors->GetDetails(modify_index).representation(); 2629 updated_descriptors->GetDetails(modify_index).representation();
2620 if (new_representation.fits_into(updated_representation)) return updated; 2630 if (new_representation.fits_into(updated_representation)) return updated;
2621 } 2631 }
2622 2632
2623 DescriptorArray* new_descriptors; 2633 Handle<DescriptorArray> new_descriptors = DescriptorArray::Merge(
2624 MaybeObject* maybe_descriptors = updated_descriptors->Merge( 2634 updated_descriptors, verbatim, valid, descriptors, modify_index,
2625 verbatim, valid, descriptors, modify_index, store_mode, old_descriptors); 2635 store_mode, old_descriptors);
2626 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
2627 ASSERT(store_mode == ALLOW_AS_CONSTANT || 2636 ASSERT(store_mode == ALLOW_AS_CONSTANT ||
2628 new_descriptors->GetDetails(modify_index).type() == FIELD); 2637 new_descriptors->GetDetails(modify_index).type() == FIELD);
2629 2638
2630 old_representation = 2639 old_representation =
2631 new_descriptors->GetDetails(modify_index).representation(); 2640 new_descriptors->GetDetails(modify_index).representation();
2632 Representation updated_representation = 2641 Representation updated_representation =
2633 new_representation.generalize(old_representation); 2642 new_representation.generalize(old_representation);
2634 if (!updated_representation.Equals(old_representation)) { 2643 if (!updated_representation.Equals(old_representation)) {
2635 new_descriptors->SetRepresentation(modify_index, updated_representation); 2644 new_descriptors->SetRepresentation(modify_index, updated_representation);
2636 } 2645 }
2637 2646
2638 Map* split_map = root_map->FindLastMatchMap( 2647 Handle<Map> split_map(root_map->FindLastMatchMap(
2639 verbatim, descriptors, new_descriptors); 2648 verbatim, descriptors, *new_descriptors));
2640 2649
2641 int split_descriptors = split_map->NumberOfOwnDescriptors(); 2650 int split_descriptors = split_map->NumberOfOwnDescriptors();
2642 // This is shadowed by |updated_descriptors| being more general than 2651 // This is shadowed by |updated_descriptors| being more general than
2643 // |old_descriptors|. 2652 // |old_descriptors|.
2644 ASSERT(descriptors != split_descriptors); 2653 ASSERT(descriptors != split_descriptors);
2645 2654
2646 int descriptor = split_descriptors; 2655 int descriptor = split_descriptors;
2647 split_map->DeprecateTarget( 2656 split_map->DeprecateTarget(
2648 old_descriptors->GetKey(descriptor), new_descriptors); 2657 old_descriptors->GetKey(descriptor), *new_descriptors);
2649 2658
2650 if (FLAG_trace_generalization) { 2659 if (FLAG_trace_generalization) {
2651 PrintGeneralization( 2660 old_map->PrintGeneralization(
2652 stdout, "", modify_index, descriptor, descriptors, 2661 stdout, "", modify_index, descriptor, descriptors,
2653 old_descriptors->GetDetails(modify_index).type() == CONSTANT && 2662 old_descriptors->GetDetails(modify_index).type() == CONSTANT &&
2654 store_mode == FORCE_FIELD, 2663 store_mode == FORCE_FIELD,
2655 old_representation, updated_representation); 2664 old_representation, updated_representation);
2656 } 2665 }
2657 2666
2658 Map* new_map = split_map;
2659 // Add missing transitions. 2667 // Add missing transitions.
2668 Handle<Map> new_map = split_map;
2660 for (; descriptor < descriptors; descriptor++) { 2669 for (; descriptor < descriptors; descriptor++) {
2661 MaybeObject* maybe_map = new_map->CopyInstallDescriptors( 2670 new_map = Map::CopyInstallDescriptors(new_map, descriptor, new_descriptors);
2662 descriptor, new_descriptors);
2663 if (!maybe_map->To(&new_map)) {
2664 // Create a handle for the last created map to ensure it stays alive
2665 // during GC. Its descriptor array is too large, but it will be
2666 // overwritten during retry anyway.
2667 Handle<Map>(new_map);
2668 return maybe_map;
2669 }
2670 new_map->set_migration_target(true); 2671 new_map->set_migration_target(true);
2671 } 2672 }
2672 2673
2673 new_map->set_owns_descriptors(true); 2674 new_map->set_owns_descriptors(true);
2674 return new_map; 2675 return new_map;
2675 } 2676 }
2676 2677
2677 2678
2678 Map* Map::CurrentMapForDeprecated() { 2679 Map* Map::CurrentMapForDeprecated() {
2679 DisallowHeapAllocation no_allocation; 2680 DisallowHeapAllocation no_allocation;
(...skipping 16 matching lines...) Expand all
2696 int valid = updated->NumberOfOwnDescriptors(); 2697 int valid = updated->NumberOfOwnDescriptors();
2697 if (!updated_descriptors->IsMoreGeneralThan( 2698 if (!updated_descriptors->IsMoreGeneralThan(
2698 verbatim, valid, descriptors, old_descriptors)) { 2699 verbatim, valid, descriptors, old_descriptors)) {
2699 return NULL; 2700 return NULL;
2700 } 2701 }
2701 2702
2702 return updated; 2703 return updated;
2703 } 2704 }
2704 2705
2705 2706
2706 MaybeObject* JSObject::SetPropertyWithInterceptor( 2707 Handle<Object> JSObject::SetPropertyWithInterceptor(
2707 Name* name, 2708 Handle<JSObject> object,
2708 Object* value, 2709 Handle<Name> name,
2710 Handle<Object> value,
2709 PropertyAttributes attributes, 2711 PropertyAttributes attributes,
2710 StrictModeFlag strict_mode) { 2712 StrictModeFlag strict_mode) {
2711 // TODO(rossberg): Support symbols in the API. 2713 // TODO(rossberg): Support symbols in the API.
2712 if (name->IsSymbol()) return value; 2714 if (name->IsSymbol()) return value;
2713 Isolate* isolate = GetIsolate(); 2715 Isolate* isolate = object->GetIsolate();
2714 HandleScope scope(isolate); 2716 Handle<String> name_string = Handle<String>::cast(name);
2715 Handle<JSObject> this_handle(this); 2717 Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor());
2716 Handle<String> name_handle(String::cast(name));
2717 Handle<Object> value_handle(value, isolate);
2718 Handle<InterceptorInfo> interceptor(GetNamedInterceptor());
2719 if (!interceptor->setter()->IsUndefined()) { 2718 if (!interceptor->setter()->IsUndefined()) {
2720 LOG(isolate, ApiNamedPropertyAccess("interceptor-named-set", this, name)); 2719 LOG(isolate,
2721 PropertyCallbackArguments args(isolate, interceptor->data(), this, this); 2720 ApiNamedPropertyAccess("interceptor-named-set", *object, *name));
2721 PropertyCallbackArguments args(
2722 isolate, interceptor->data(), *object, *object);
2722 v8::NamedPropertySetterCallback setter = 2723 v8::NamedPropertySetterCallback setter =
2723 v8::ToCData<v8::NamedPropertySetterCallback>(interceptor->setter()); 2724 v8::ToCData<v8::NamedPropertySetterCallback>(interceptor->setter());
2724 Handle<Object> value_unhole(value->IsTheHole() ? 2725 Handle<Object> value_unhole = value->IsTheHole()
2725 isolate->heap()->undefined_value() : 2726 ? Handle<Object>(isolate->factory()->undefined_value()) : value;
2726 value,
2727 isolate);
2728 v8::Handle<v8::Value> result = args.Call(setter, 2727 v8::Handle<v8::Value> result = args.Call(setter,
2729 v8::Utils::ToLocal(name_handle), 2728 v8::Utils::ToLocal(name_string),
2730 v8::Utils::ToLocal(value_unhole)); 2729 v8::Utils::ToLocal(value_unhole));
2731 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 2730 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
2732 if (!result.IsEmpty()) return *value_handle; 2731 if (!result.IsEmpty()) return value;
2733 } 2732 }
2734 MaybeObject* raw_result = 2733 Handle<Object> result =
2735 this_handle->SetPropertyPostInterceptor(*name_handle, 2734 SetPropertyPostInterceptor(object, name, value, attributes, strict_mode);
2736 *value_handle, 2735 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
2737 attributes, 2736 return result;
2738 strict_mode);
2739 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
2740 return raw_result;
2741 } 2737 }
2742 2738
2743 2739
2744 Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object, 2740 Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object,
2745 Handle<Name> key, 2741 Handle<Name> name,
2746 Handle<Object> value, 2742 Handle<Object> value,
2747 PropertyAttributes attributes, 2743 PropertyAttributes attributes,
2748 StrictModeFlag strict_mode) { 2744 StrictModeFlag strict_mode,
2749 CALL_HEAP_FUNCTION(object->GetIsolate(), 2745 StoreFromKeyed store_mode) {
2750 object->SetProperty(*key, *value, attributes, strict_mode), 2746 LookupResult result(object->GetIsolate());
2751 Object); 2747 object->LocalLookup(*name, &result, true);
2748 if (!result.IsFound()) {
2749 object->map()->LookupTransition(JSObject::cast(*object), *name, &result);
2750 }
2751 return SetProperty(object, &result, name, value, attributes, strict_mode,
2752 store_mode);
2752 } 2753 }
2753 2754
2754 2755
2755 MaybeObject* JSReceiver::SetPropertyOrFail( 2756 Handle<Object> JSObject::SetPropertyWithCallback(Handle<JSObject> object,
2756 Handle<JSReceiver> object, 2757 Handle<Object> structure,
2757 Handle<Name> key, 2758 Handle<Name> name,
2758 Handle<Object> value, 2759 Handle<Object> value,
2759 PropertyAttributes attributes, 2760 Handle<JSObject> holder,
2760 StrictModeFlag strict_mode, 2761 StrictModeFlag strict_mode) {
2761 JSReceiver::StoreFromKeyed store_mode) { 2762 Isolate* isolate = object->GetIsolate();
2762 CALL_HEAP_FUNCTION_PASS_EXCEPTION(
2763 object->GetIsolate(),
2764 object->SetProperty(*key, *value, attributes, strict_mode, store_mode));
2765 }
2766
2767
2768 MaybeObject* JSReceiver::SetProperty(Name* name,
2769 Object* value,
2770 PropertyAttributes attributes,
2771 StrictModeFlag strict_mode,
2772 JSReceiver::StoreFromKeyed store_mode) {
2773 LookupResult result(GetIsolate());
2774 LocalLookup(name, &result, true);
2775 if (!result.IsFound()) {
2776 map()->LookupTransition(JSObject::cast(this), name, &result);
2777 }
2778 return SetProperty(&result, name, value, attributes, strict_mode, store_mode);
2779 }
2780
2781
2782 MaybeObject* JSObject::SetPropertyWithCallback(Object* structure,
2783 Name* name,
2784 Object* value,
2785 JSObject* holder,
2786 StrictModeFlag strict_mode) {
2787 Isolate* isolate = GetIsolate();
2788 HandleScope scope(isolate);
2789 2763
2790 // We should never get here to initialize a const with the hole 2764 // We should never get here to initialize a const with the hole
2791 // value since a const declaration would conflict with the setter. 2765 // value since a const declaration would conflict with the setter.
2792 ASSERT(!value->IsTheHole()); 2766 ASSERT(!value->IsTheHole());
2793 Handle<Object> value_handle(value, isolate);
2794 2767
2795 // To accommodate both the old and the new api we switch on the 2768 // To accommodate both the old and the new api we switch on the
2796 // data structure used to store the callbacks. Eventually foreign 2769 // data structure used to store the callbacks. Eventually foreign
2797 // callbacks should be phased out. 2770 // callbacks should be phased out.
2798 if (structure->IsForeign()) { 2771 if (structure->IsForeign()) {
2799 AccessorDescriptor* callback = 2772 AccessorDescriptor* callback =
2800 reinterpret_cast<AccessorDescriptor*>( 2773 reinterpret_cast<AccessorDescriptor*>(
2801 Foreign::cast(structure)->foreign_address()); 2774 Handle<Foreign>::cast(structure)->foreign_address());
2802 MaybeObject* obj = (callback->setter)( 2775 CALL_AND_RETRY_OR_DIE(isolate,
2803 isolate, this, value, callback->data); 2776 (callback->setter)(
2804 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 2777 isolate, *object, *value, callback->data),
2805 if (obj->IsFailure()) return obj; 2778 break,
2806 return *value_handle; 2779 return Handle<Object>());
2780 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
2781 return value;
2807 } 2782 }
2808 2783
2809 if (structure->IsExecutableAccessorInfo()) { 2784 if (structure->IsExecutableAccessorInfo()) {
2810 // api style callbacks 2785 // api style callbacks
2811 ExecutableAccessorInfo* data = ExecutableAccessorInfo::cast(structure); 2786 ExecutableAccessorInfo* data = ExecutableAccessorInfo::cast(*structure);
2812 if (!data->IsCompatibleReceiver(this)) { 2787 if (!data->IsCompatibleReceiver(*object)) {
2813 Handle<Object> name_handle(name, isolate); 2788 Handle<Object> args[2] = { name, object };
2814 Handle<Object> receiver_handle(this, isolate);
2815 Handle<Object> args[2] = { name_handle, receiver_handle };
2816 Handle<Object> error = 2789 Handle<Object> error =
2817 isolate->factory()->NewTypeError("incompatible_method_receiver", 2790 isolate->factory()->NewTypeError("incompatible_method_receiver",
2818 HandleVector(args, 2791 HandleVector(args,
2819 ARRAY_SIZE(args))); 2792 ARRAY_SIZE(args)));
2820 return isolate->Throw(*error); 2793 isolate->Throw(*error);
2794 return Handle<Object>();
2821 } 2795 }
2822 // TODO(rossberg): Support symbols in the API. 2796 // TODO(rossberg): Support symbols in the API.
2823 if (name->IsSymbol()) return value; 2797 if (name->IsSymbol()) return value;
2824 Object* call_obj = data->setter(); 2798 Object* call_obj = data->setter();
2825 v8::AccessorSetterCallback call_fun = 2799 v8::AccessorSetterCallback call_fun =
2826 v8::ToCData<v8::AccessorSetterCallback>(call_obj); 2800 v8::ToCData<v8::AccessorSetterCallback>(call_obj);
2827 if (call_fun == NULL) return value; 2801 if (call_fun == NULL) return value;
2828 Handle<String> key(String::cast(name)); 2802 Handle<String> key = Handle<String>::cast(name);
2829 LOG(isolate, ApiNamedPropertyAccess("store", this, name)); 2803 LOG(isolate, ApiNamedPropertyAccess("store", *object, *name));
2830 PropertyCallbackArguments args( 2804 PropertyCallbackArguments args(
2831 isolate, data->data(), this, JSObject::cast(holder)); 2805 isolate, data->data(), *object, JSObject::cast(*holder));
2832 args.Call(call_fun, 2806 args.Call(call_fun,
2833 v8::Utils::ToLocal(key), 2807 v8::Utils::ToLocal(key),
2834 v8::Utils::ToLocal(value_handle)); 2808 v8::Utils::ToLocal(value));
2835 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 2809 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
2836 return *value_handle; 2810 return value;
2837 } 2811 }
2838 2812
2839 if (structure->IsAccessorPair()) { 2813 if (structure->IsAccessorPair()) {
2840 Object* setter = AccessorPair::cast(structure)->setter(); 2814 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate);
2841 if (setter->IsSpecFunction()) { 2815 if (setter->IsSpecFunction()) {
2842 // TODO(rossberg): nicer would be to cast to some JSCallable here... 2816 // TODO(rossberg): nicer would be to cast to some JSCallable here...
2843 return SetPropertyWithDefinedSetter(JSReceiver::cast(setter), value); 2817 return SetPropertyWithDefinedSetter(
2818 object, Handle<JSReceiver>::cast(setter), value);
2844 } else { 2819 } else {
2845 if (strict_mode == kNonStrictMode) { 2820 if (strict_mode == kNonStrictMode) {
2846 return value; 2821 return value;
2847 } 2822 }
2848 Handle<Name> key(name); 2823 Handle<Object> args[2] = { name, holder };
2849 Handle<Object> holder_handle(holder, isolate); 2824 Handle<Object> error =
2850 Handle<Object> args[2] = { key, holder_handle }; 2825 isolate->factory()->NewTypeError("no_setter_in_callback",
2851 return isolate->Throw( 2826 HandleVector(args, 2));
2852 *isolate->factory()->NewTypeError("no_setter_in_callback", 2827 isolate->Throw(*error);
2853 HandleVector(args, 2))); 2828 return Handle<Object>();
2854 } 2829 }
2855 } 2830 }
2856 2831
2857 // TODO(dcarney): Handle correctly. 2832 // TODO(dcarney): Handle correctly.
2858 if (structure->IsDeclaredAccessorInfo()) { 2833 if (structure->IsDeclaredAccessorInfo()) {
2859 return value; 2834 return value;
2860 } 2835 }
2861 2836
2862 UNREACHABLE(); 2837 UNREACHABLE();
2863 return NULL; 2838 return Handle<Object>();
2864 } 2839 }
2865 2840
2866 2841
2867 MaybeObject* JSReceiver::SetPropertyWithDefinedSetter(JSReceiver* setter, 2842 Handle<Object> JSReceiver::SetPropertyWithDefinedSetter(
2868 Object* value) { 2843 Handle<JSReceiver> object,
2869 Isolate* isolate = GetIsolate(); 2844 Handle<JSReceiver> setter,
2870 Handle<Object> value_handle(value, isolate); 2845 Handle<Object> value) {
2871 Handle<JSReceiver> fun(setter, isolate); 2846 Isolate* isolate = object->GetIsolate();
2872 Handle<JSReceiver> self(this, isolate); 2847
2873 #ifdef ENABLE_DEBUGGER_SUPPORT 2848 #ifdef ENABLE_DEBUGGER_SUPPORT
2874 Debug* debug = isolate->debug(); 2849 Debug* debug = isolate->debug();
2875 // Handle stepping into a setter if step into is active. 2850 // Handle stepping into a setter if step into is active.
2876 // TODO(rossberg): should this apply to getters that are function proxies? 2851 // TODO(rossberg): should this apply to getters that are function proxies?
2877 if (debug->StepInActive() && fun->IsJSFunction()) { 2852 if (debug->StepInActive() && setter->IsJSFunction()) {
2878 debug->HandleStepIn( 2853 debug->HandleStepIn(
2879 Handle<JSFunction>::cast(fun), Handle<Object>::null(), 0, false); 2854 Handle<JSFunction>::cast(setter), Handle<Object>::null(), 0, false);
2880 } 2855 }
2881 #endif 2856 #endif
2857
2882 bool has_pending_exception; 2858 bool has_pending_exception;
2883 Handle<Object> argv[] = { value_handle }; 2859 Handle<Object> argv[] = { value };
2884 Execution::Call( 2860 Execution::Call(
2885 isolate, fun, self, ARRAY_SIZE(argv), argv, &has_pending_exception); 2861 isolate, setter, object, ARRAY_SIZE(argv), argv, &has_pending_exception);
2886 // Check for pending exception and return the result. 2862 // Check for pending exception and return the result.
2887 if (has_pending_exception) return Failure::Exception(); 2863 if (has_pending_exception) return Handle<Object>();
2888 return *value_handle; 2864 return value;
2889 } 2865 }
2890 2866
2891 2867
2892 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes( 2868 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes(
2893 uint32_t index, 2869 uint32_t index,
2894 Object* value, 2870 Object* value,
2895 bool* found, 2871 bool* found,
2896 StrictModeFlag strict_mode) { 2872 StrictModeFlag strict_mode) {
2897 Heap* heap = GetHeap(); 2873 Heap* heap = GetHeap();
2898 for (Object* pt = GetPrototype(); 2874 for (Object* pt = GetPrototype();
2899 pt != heap->null_value(); 2875 pt != heap->null_value();
2900 pt = pt->GetPrototype(GetIsolate())) { 2876 pt = pt->GetPrototype(GetIsolate())) {
2901 if (pt->IsJSProxy()) { 2877 if (pt->IsJSProxy()) {
2902 String* name; 2878 Isolate* isolate = GetIsolate();
2903 MaybeObject* maybe = heap->Uint32ToString(index); 2879 HandleScope scope(isolate);
2904 if (!maybe->To<String>(&name)) { 2880 Handle<JSProxy> proxy(JSProxy::cast(pt));
2905 *found = true; // Force abort 2881 Handle<JSObject> self(this, isolate);
2906 return maybe; 2882 Handle<String> name = isolate->factory()->Uint32ToString(index);
2907 } 2883 Handle<Object> value_handle(value, isolate);
2908 return JSProxy::cast(pt)->SetPropertyViaPrototypesWithHandler( 2884 Handle<Object> result = JSProxy::SetPropertyViaPrototypesWithHandler(
2909 this, name, value, NONE, strict_mode, found); 2885 proxy, self, name, value_handle, NONE, strict_mode, found);
2886 RETURN_IF_EMPTY_HANDLE(isolate, result);
2887 return *result;
2910 } 2888 }
2911 if (!JSObject::cast(pt)->HasDictionaryElements()) { 2889 if (!JSObject::cast(pt)->HasDictionaryElements()) {
2912 continue; 2890 continue;
2913 } 2891 }
2914 SeededNumberDictionary* dictionary = 2892 SeededNumberDictionary* dictionary =
2915 JSObject::cast(pt)->element_dictionary(); 2893 JSObject::cast(pt)->element_dictionary();
2916 int entry = dictionary->FindEntry(index); 2894 int entry = dictionary->FindEntry(index);
2917 if (entry != SeededNumberDictionary::kNotFound) { 2895 if (entry != SeededNumberDictionary::kNotFound) {
2918 PropertyDetails details = dictionary->DetailsAt(entry); 2896 PropertyDetails details = dictionary->DetailsAt(entry);
2919 if (details.type() == CALLBACKS) { 2897 if (details.type() == CALLBACKS) {
2920 *found = true; 2898 *found = true;
2921 return SetElementWithCallback(dictionary->ValueAt(entry), 2899 Isolate* isolate = GetIsolate();
2922 index, 2900 HandleScope scope(isolate);
2923 value, 2901 Handle<JSObject> self(this, isolate);
2924 JSObject::cast(pt), 2902 Handle<Object> structure(dictionary->ValueAt(entry), isolate);
2925 strict_mode); 2903 Handle<Object> value_handle(value, isolate);
2904 Handle<JSObject> holder(JSObject::cast(pt));
2905 Handle<Object> result = SetElementWithCallback(
2906 self, structure, index, value_handle, holder, strict_mode);
2907 RETURN_IF_EMPTY_HANDLE(isolate, result);
2908 return *result;
2926 } 2909 }
2927 } 2910 }
2928 } 2911 }
2929 *found = false; 2912 *found = false;
2930 return heap->the_hole_value(); 2913 return heap->the_hole_value();
2931 } 2914 }
2932 2915
2933 MaybeObject* JSObject::SetPropertyViaPrototypes( 2916
2934 Name* name, 2917 Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object,
2935 Object* value, 2918 Handle<Name> name,
2936 PropertyAttributes attributes, 2919 Handle<Object> value,
2937 StrictModeFlag strict_mode, 2920 PropertyAttributes attributes,
2938 bool* done) { 2921 StrictModeFlag strict_mode,
2939 Heap* heap = GetHeap(); 2922 bool* done) {
2940 Isolate* isolate = heap->isolate(); 2923 Isolate* isolate = object->GetIsolate();
2941 2924
2942 *done = false; 2925 *done = false;
2943 // We could not find a local property so let's check whether there is an 2926 // We could not find a local property so let's check whether there is an
2944 // accessor that wants to handle the property, or whether the property is 2927 // accessor that wants to handle the property, or whether the property is
2945 // read-only on the prototype chain. 2928 // read-only on the prototype chain.
2946 LookupResult result(isolate); 2929 LookupResult result(isolate);
2947 LookupRealNamedPropertyInPrototypes(name, &result); 2930 object->LookupRealNamedPropertyInPrototypes(*name, &result);
2948 if (result.IsFound()) { 2931 if (result.IsFound()) {
2949 switch (result.type()) { 2932 switch (result.type()) {
2950 case NORMAL: 2933 case NORMAL:
2951 case FIELD: 2934 case FIELD:
2952 case CONSTANT: 2935 case CONSTANT:
2953 *done = result.IsReadOnly(); 2936 *done = result.IsReadOnly();
2954 break; 2937 break;
2955 case INTERCEPTOR: { 2938 case INTERCEPTOR: {
2956 PropertyAttributes attr = 2939 PropertyAttributes attr =
2957 result.holder()->GetPropertyAttributeWithInterceptor( 2940 result.holder()->GetPropertyAttributeWithInterceptor(
2958 this, name, true); 2941 *object, *name, true);
2959 *done = !!(attr & READ_ONLY); 2942 *done = !!(attr & READ_ONLY);
2960 break; 2943 break;
2961 } 2944 }
2962 case CALLBACKS: { 2945 case CALLBACKS: {
2963 if (!FLAG_es5_readonly && result.IsReadOnly()) break; 2946 if (!FLAG_es5_readonly && result.IsReadOnly()) break;
2964 *done = true; 2947 *done = true;
2965 return SetPropertyWithCallback(result.GetCallbackObject(), 2948 Handle<Object> callback_object(result.GetCallbackObject(), isolate);
2966 name, value, result.holder(), strict_mode); 2949 return SetPropertyWithCallback(object, callback_object, name, value,
2950 handle(result.holder()), strict_mode);
2967 } 2951 }
2968 case HANDLER: { 2952 case HANDLER: {
2969 return result.proxy()->SetPropertyViaPrototypesWithHandler( 2953 Handle<JSProxy> proxy(result.proxy());
2970 this, name, value, attributes, strict_mode, done); 2954 return JSProxy::SetPropertyViaPrototypesWithHandler(
2955 proxy, object, name, value, attributes, strict_mode, done);
2971 } 2956 }
2972 case TRANSITION: 2957 case TRANSITION:
2973 case NONEXISTENT: 2958 case NONEXISTENT:
2974 UNREACHABLE(); 2959 UNREACHABLE();
2975 break; 2960 break;
2976 } 2961 }
2977 } 2962 }
2978 2963
2979 // If we get here with *done true, we have encountered a read-only property. 2964 // If we get here with *done true, we have encountered a read-only property.
2980 if (!FLAG_es5_readonly) *done = false; 2965 if (!FLAG_es5_readonly) *done = false;
2981 if (*done) { 2966 if (*done) {
2982 if (strict_mode == kNonStrictMode) return value; 2967 if (strict_mode == kNonStrictMode) return value;
2983 Handle<Object> args[] = { Handle<Object>(name, isolate), 2968 Handle<Object> args[] = { name, object };
2984 Handle<Object>(this, isolate)}; 2969 Handle<Object> error = isolate->factory()->NewTypeError(
2985 return isolate->Throw(*isolate->factory()->NewTypeError( 2970 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)));
2986 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)))); 2971 isolate->Throw(*error);
2972 return Handle<Object>();
2987 } 2973 }
2988 return heap->the_hole_value(); 2974 return isolate->factory()->the_hole_value();
2989 } 2975 }
2990 2976
2991 2977
2992 void Map::EnsureDescriptorSlack(Handle<Map> map, int slack) { 2978 void Map::EnsureDescriptorSlack(Handle<Map> map, int slack) {
2993 Handle<DescriptorArray> descriptors(map->instance_descriptors()); 2979 Handle<DescriptorArray> descriptors(map->instance_descriptors());
2994 if (slack <= descriptors->NumberOfSlackDescriptors()) return; 2980 if (slack <= descriptors->NumberOfSlackDescriptors()) return;
2995 int number_of_descriptors = descriptors->number_of_descriptors(); 2981 int number_of_descriptors = descriptors->number_of_descriptors();
2996 Isolate* isolate = map->GetIsolate(); 2982 Isolate* isolate = map->GetIsolate();
2997 Handle<DescriptorArray> new_descriptors = 2983 Handle<DescriptorArray> new_descriptors =
2998 isolate->factory()->NewDescriptorArray(number_of_descriptors, slack); 2984 isolate->factory()->NewDescriptorArray(number_of_descriptors, slack);
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
3333 } 3319 }
3334 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); 3320 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result);
3335 ASSERT(!(result->IsFound() && result->type() == INTERCEPTOR)); 3321 ASSERT(!(result->IsFound() && result->type() == INTERCEPTOR));
3336 if (result->IsFound()) return; 3322 if (result->IsFound()) return;
3337 } 3323 }
3338 result->NotFound(); 3324 result->NotFound();
3339 } 3325 }
3340 3326
3341 3327
3342 // We only need to deal with CALLBACKS and INTERCEPTORS 3328 // We only need to deal with CALLBACKS and INTERCEPTORS
3343 MaybeObject* JSObject::SetPropertyWithFailedAccessCheck( 3329 Handle<Object> JSObject::SetPropertyWithFailedAccessCheck(
3330 Handle<JSObject> object,
3344 LookupResult* result, 3331 LookupResult* result,
3345 Name* name, 3332 Handle<Name> name,
3346 Object* value, 3333 Handle<Object> value,
3347 bool check_prototype, 3334 bool check_prototype,
3348 StrictModeFlag strict_mode) { 3335 StrictModeFlag strict_mode) {
3349 if (check_prototype && !result->IsProperty()) { 3336 if (check_prototype && !result->IsProperty()) {
3350 LookupRealNamedPropertyInPrototypes(name, result); 3337 object->LookupRealNamedPropertyInPrototypes(*name, result);
3351 } 3338 }
3352 3339
3353 if (result->IsProperty()) { 3340 if (result->IsProperty()) {
3354 if (!result->IsReadOnly()) { 3341 if (!result->IsReadOnly()) {
3355 switch (result->type()) { 3342 switch (result->type()) {
3356 case CALLBACKS: { 3343 case CALLBACKS: {
3357 Object* obj = result->GetCallbackObject(); 3344 Object* obj = result->GetCallbackObject();
3358 if (obj->IsAccessorInfo()) { 3345 if (obj->IsAccessorInfo()) {
3359 AccessorInfo* info = AccessorInfo::cast(obj); 3346 Handle<AccessorInfo> info(AccessorInfo::cast(obj));
3360 if (info->all_can_write()) { 3347 if (info->all_can_write()) {
3361 return SetPropertyWithCallback(result->GetCallbackObject(), 3348 return SetPropertyWithCallback(object,
3349 info,
3362 name, 3350 name,
3363 value, 3351 value,
3364 result->holder(), 3352 handle(result->holder()),
3365 strict_mode); 3353 strict_mode);
3366 } 3354 }
3367 } else if (obj->IsAccessorPair()) { 3355 } else if (obj->IsAccessorPair()) {
3368 AccessorPair* pair = AccessorPair::cast(obj); 3356 Handle<AccessorPair> pair(AccessorPair::cast(obj));
3369 if (pair->all_can_read()) { 3357 if (pair->all_can_read()) {
3370 return SetPropertyWithCallback(result->GetCallbackObject(), 3358 return SetPropertyWithCallback(object,
3359 pair,
3371 name, 3360 name,
3372 value, 3361 value,
3373 result->holder(), 3362 handle(result->holder()),
3374 strict_mode); 3363 strict_mode);
3375 } 3364 }
3376 } 3365 }
3377 break; 3366 break;
3378 } 3367 }
3379 case INTERCEPTOR: { 3368 case INTERCEPTOR: {
3380 // Try lookup real named properties. Note that only property can be 3369 // Try lookup real named properties. Note that only property can be
3381 // set is callbacks marked as ALL_CAN_WRITE on the prototype chain. 3370 // set is callbacks marked as ALL_CAN_WRITE on the prototype chain.
3382 LookupResult r(GetIsolate()); 3371 LookupResult r(object->GetIsolate());
3383 LookupRealNamedProperty(name, &r); 3372 object->LookupRealNamedProperty(*name, &r);
3384 if (r.IsProperty()) { 3373 if (r.IsProperty()) {
3385 return SetPropertyWithFailedAccessCheck(&r, 3374 return SetPropertyWithFailedAccessCheck(object,
3375 &r,
3386 name, 3376 name,
3387 value, 3377 value,
3388 check_prototype, 3378 check_prototype,
3389 strict_mode); 3379 strict_mode);
3390 } 3380 }
3391 break; 3381 break;
3392 } 3382 }
3393 default: { 3383 default: {
3394 break; 3384 break;
3395 } 3385 }
3396 } 3386 }
3397 } 3387 }
3398 } 3388 }
3399 3389
3400 Isolate* isolate = GetIsolate(); 3390 Isolate* isolate = object->GetIsolate();
3401 HandleScope scope(isolate); 3391 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_SET);
3402 Handle<Object> value_handle(value, isolate); 3392 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
3403 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); 3393 return value;
3404 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
3405 return *value_handle;
3406 } 3394 }
3407 3395
3408 3396
3409 MaybeObject* JSReceiver::SetProperty(LookupResult* result, 3397 Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object,
3410 Name* key, 3398 LookupResult* result,
3411 Object* value, 3399 Handle<Name> key,
3412 PropertyAttributes attributes, 3400 Handle<Object> value,
3413 StrictModeFlag strict_mode, 3401 PropertyAttributes attributes,
3414 JSReceiver::StoreFromKeyed store_mode) { 3402 StrictModeFlag strict_mode,
3403 StoreFromKeyed store_mode) {
3415 if (result->IsHandler()) { 3404 if (result->IsHandler()) {
3416 return result->proxy()->SetPropertyWithHandler( 3405 return JSProxy::SetPropertyWithHandler(handle(result->proxy()),
3417 this, key, value, attributes, strict_mode); 3406 object, key, value, attributes, strict_mode);
3418 } else { 3407 } else {
3419 return JSObject::cast(this)->SetPropertyForResult( 3408 return JSObject::SetPropertyForResult(Handle<JSObject>::cast(object),
3420 result, key, value, attributes, strict_mode, store_mode); 3409 result, key, value, attributes, strict_mode, store_mode);
3421 } 3410 }
3422 } 3411 }
3423 3412
3424 3413
3425 bool JSProxy::HasPropertyWithHandler(Name* name_raw) { 3414 bool JSProxy::HasPropertyWithHandler(Handle<JSProxy> proxy, Handle<Name> name) {
3426 Isolate* isolate = GetIsolate(); 3415 Isolate* isolate = proxy->GetIsolate();
3427 HandleScope scope(isolate);
3428 Handle<Object> receiver(this, isolate);
3429 Handle<Object> name(name_raw, isolate);
3430 3416
3431 // TODO(rossberg): adjust once there is a story for symbols vs proxies. 3417 // TODO(rossberg): adjust once there is a story for symbols vs proxies.
3432 if (name->IsSymbol()) return false; 3418 if (name->IsSymbol()) return false;
3433 3419
3434 Handle<Object> args[] = { name }; 3420 Handle<Object> args[] = { name };
3435 Handle<Object> result = CallTrap( 3421 Handle<Object> result = proxy->CallTrap(
3436 "has", isolate->derived_has_trap(), ARRAY_SIZE(args), args); 3422 "has", isolate->derived_has_trap(), ARRAY_SIZE(args), args);
3437 if (isolate->has_pending_exception()) return false; 3423 if (isolate->has_pending_exception()) return false;
3438 3424
3439 return result->BooleanValue(); 3425 return result->BooleanValue();
3440 } 3426 }
3441 3427
3442 3428
3443 MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandler( 3429 Handle<Object> JSProxy::SetPropertyWithHandler(Handle<JSProxy> proxy,
3444 JSReceiver* receiver_raw, 3430 Handle<JSReceiver> receiver,
3445 Name* name_raw, 3431 Handle<Name> name,
3446 Object* value_raw, 3432 Handle<Object> value,
3447 PropertyAttributes attributes, 3433 PropertyAttributes attributes,
3448 StrictModeFlag strict_mode) { 3434 StrictModeFlag strict_mode) {
3449 Isolate* isolate = GetIsolate(); 3435 Isolate* isolate = proxy->GetIsolate();
3450 HandleScope scope(isolate);
3451 Handle<JSReceiver> receiver(receiver_raw);
3452 Handle<Object> name(name_raw, isolate);
3453 Handle<Object> value(value_raw, isolate);
3454 3436
3455 // TODO(rossberg): adjust once there is a story for symbols vs proxies. 3437 // TODO(rossberg): adjust once there is a story for symbols vs proxies.
3456 if (name->IsSymbol()) return *value; 3438 if (name->IsSymbol()) return value;
3457 3439
3458 Handle<Object> args[] = { receiver, name, value }; 3440 Handle<Object> args[] = { receiver, name, value };
3459 CallTrap("set", isolate->derived_set_trap(), ARRAY_SIZE(args), args); 3441 proxy->CallTrap("set", isolate->derived_set_trap(), ARRAY_SIZE(args), args);
3460 if (isolate->has_pending_exception()) return Failure::Exception(); 3442 if (isolate->has_pending_exception()) return Handle<Object>();
3461 3443
3462 return *value; 3444 return value;
3463 } 3445 }
3464 3446
3465 3447
3466 MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyViaPrototypesWithHandler( 3448 Handle<Object> JSProxy::SetPropertyViaPrototypesWithHandler(
3467 JSReceiver* receiver_raw, 3449 Handle<JSProxy> proxy,
3468 Name* name_raw, 3450 Handle<JSReceiver> receiver,
3469 Object* value_raw, 3451 Handle<Name> name,
3452 Handle<Object> value,
3470 PropertyAttributes attributes, 3453 PropertyAttributes attributes,
3471 StrictModeFlag strict_mode, 3454 StrictModeFlag strict_mode,
3472 bool* done) { 3455 bool* done) {
3473 Isolate* isolate = GetIsolate(); 3456 Isolate* isolate = proxy->GetIsolate();
3474 Handle<JSProxy> proxy(this); 3457 Handle<Object> handler(proxy->handler(), isolate); // Trap might morph proxy.
3475 Handle<JSReceiver> receiver(receiver_raw);
3476 Handle<Name> name(name_raw);
3477 Handle<Object> value(value_raw, isolate);
3478 Handle<Object> handler(this->handler(), isolate); // Trap might morph proxy.
3479 3458
3480 // TODO(rossberg): adjust once there is a story for symbols vs proxies. 3459 // TODO(rossberg): adjust once there is a story for symbols vs proxies.
3481 if (name->IsSymbol()) { 3460 if (name->IsSymbol()) {
3482 *done = false; 3461 *done = false;
3483 return isolate->heap()->the_hole_value(); 3462 return isolate->factory()->the_hole_value();
3484 } 3463 }
3485 3464
3486 *done = true; // except where redefined... 3465 *done = true; // except where redefined...
3487 Handle<Object> args[] = { name }; 3466 Handle<Object> args[] = { name };
3488 Handle<Object> result = proxy->CallTrap( 3467 Handle<Object> result = proxy->CallTrap(
3489 "getPropertyDescriptor", Handle<Object>(), ARRAY_SIZE(args), args); 3468 "getPropertyDescriptor", Handle<Object>(), ARRAY_SIZE(args), args);
3490 if (isolate->has_pending_exception()) return Failure::Exception(); 3469 if (isolate->has_pending_exception()) return Handle<Object>();
3491 3470
3492 if (result->IsUndefined()) { 3471 if (result->IsUndefined()) {
3493 *done = false; 3472 *done = false;
3494 return isolate->heap()->the_hole_value(); 3473 return isolate->factory()->the_hole_value();
3495 } 3474 }
3496 3475
3497 // Emulate [[GetProperty]] semantics for proxies. 3476 // Emulate [[GetProperty]] semantics for proxies.
3498 bool has_pending_exception; 3477 bool has_pending_exception;
3499 Handle<Object> argv[] = { result }; 3478 Handle<Object> argv[] = { result };
3500 Handle<Object> desc = Execution::Call( 3479 Handle<Object> desc = Execution::Call(
3501 isolate, isolate->to_complete_property_descriptor(), result, 3480 isolate, isolate->to_complete_property_descriptor(), result,
3502 ARRAY_SIZE(argv), argv, &has_pending_exception); 3481 ARRAY_SIZE(argv), argv, &has_pending_exception);
3503 if (has_pending_exception) return Failure::Exception(); 3482 if (has_pending_exception) return Handle<Object>();
3504 3483
3505 // [[GetProperty]] requires to check that all properties are configurable. 3484 // [[GetProperty]] requires to check that all properties are configurable.
3506 Handle<String> configurable_name = 3485 Handle<String> configurable_name =
3507 isolate->factory()->InternalizeOneByteString( 3486 isolate->factory()->InternalizeOneByteString(
3508 STATIC_ASCII_VECTOR("configurable_")); 3487 STATIC_ASCII_VECTOR("configurable_"));
3509 Handle<Object> configurable( 3488 Handle<Object> configurable(
3510 v8::internal::GetProperty(isolate, desc, configurable_name)); 3489 v8::internal::GetProperty(isolate, desc, configurable_name));
3511 ASSERT(!isolate->has_pending_exception()); 3490 ASSERT(!isolate->has_pending_exception());
3512 ASSERT(configurable->IsTrue() || configurable->IsFalse()); 3491 ASSERT(configurable->IsTrue() || configurable->IsFalse());
3513 if (configurable->IsFalse()) { 3492 if (configurable->IsFalse()) {
3514 Handle<String> trap = 3493 Handle<String> trap =
3515 isolate->factory()->InternalizeOneByteString( 3494 isolate->factory()->InternalizeOneByteString(
3516 STATIC_ASCII_VECTOR("getPropertyDescriptor")); 3495 STATIC_ASCII_VECTOR("getPropertyDescriptor"));
3517 Handle<Object> args[] = { handler, trap, name }; 3496 Handle<Object> args[] = { handler, trap, name };
3518 Handle<Object> error = isolate->factory()->NewTypeError( 3497 Handle<Object> error = isolate->factory()->NewTypeError(
3519 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args))); 3498 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args)));
3520 return isolate->Throw(*error); 3499 isolate->Throw(*error);
3500 return Handle<Object>();
3521 } 3501 }
3522 ASSERT(configurable->IsTrue()); 3502 ASSERT(configurable->IsTrue());
3523 3503
3524 // Check for DataDescriptor. 3504 // Check for DataDescriptor.
3525 Handle<String> hasWritable_name = 3505 Handle<String> hasWritable_name =
3526 isolate->factory()->InternalizeOneByteString( 3506 isolate->factory()->InternalizeOneByteString(
3527 STATIC_ASCII_VECTOR("hasWritable_")); 3507 STATIC_ASCII_VECTOR("hasWritable_"));
3528 Handle<Object> hasWritable( 3508 Handle<Object> hasWritable(
3529 v8::internal::GetProperty(isolate, desc, hasWritable_name)); 3509 v8::internal::GetProperty(isolate, desc, hasWritable_name));
3530 ASSERT(!isolate->has_pending_exception()); 3510 ASSERT(!isolate->has_pending_exception());
3531 ASSERT(hasWritable->IsTrue() || hasWritable->IsFalse()); 3511 ASSERT(hasWritable->IsTrue() || hasWritable->IsFalse());
3532 if (hasWritable->IsTrue()) { 3512 if (hasWritable->IsTrue()) {
3533 Handle<String> writable_name = 3513 Handle<String> writable_name =
3534 isolate->factory()->InternalizeOneByteString( 3514 isolate->factory()->InternalizeOneByteString(
3535 STATIC_ASCII_VECTOR("writable_")); 3515 STATIC_ASCII_VECTOR("writable_"));
3536 Handle<Object> writable( 3516 Handle<Object> writable(
3537 v8::internal::GetProperty(isolate, desc, writable_name)); 3517 v8::internal::GetProperty(isolate, desc, writable_name));
3538 ASSERT(!isolate->has_pending_exception()); 3518 ASSERT(!isolate->has_pending_exception());
3539 ASSERT(writable->IsTrue() || writable->IsFalse()); 3519 ASSERT(writable->IsTrue() || writable->IsFalse());
3540 *done = writable->IsFalse(); 3520 *done = writable->IsFalse();
3541 if (!*done) return GetHeap()->the_hole_value(); 3521 if (!*done) return isolate->factory()->the_hole_value();
3542 if (strict_mode == kNonStrictMode) return *value; 3522 if (strict_mode == kNonStrictMode) return value;
3543 Handle<Object> args[] = { name, receiver }; 3523 Handle<Object> args[] = { name, receiver };
3544 Handle<Object> error = isolate->factory()->NewTypeError( 3524 Handle<Object> error = isolate->factory()->NewTypeError(
3545 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); 3525 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)));
3546 return isolate->Throw(*error); 3526 isolate->Throw(*error);
3527 return Handle<Object>();
3547 } 3528 }
3548 3529
3549 // We have an AccessorDescriptor. 3530 // We have an AccessorDescriptor.
3550 Handle<String> set_name = isolate->factory()->InternalizeOneByteString( 3531 Handle<String> set_name = isolate->factory()->InternalizeOneByteString(
3551 STATIC_ASCII_VECTOR("set_")); 3532 STATIC_ASCII_VECTOR("set_"));
3552 Handle<Object> setter(v8::internal::GetProperty(isolate, desc, set_name)); 3533 Handle<Object> setter(v8::internal::GetProperty(isolate, desc, set_name));
3553 ASSERT(!isolate->has_pending_exception()); 3534 ASSERT(!isolate->has_pending_exception());
3554 if (!setter->IsUndefined()) { 3535 if (!setter->IsUndefined()) {
3555 // TODO(rossberg): nicer would be to cast to some JSCallable here... 3536 // TODO(rossberg): nicer would be to cast to some JSCallable here...
3556 return receiver->SetPropertyWithDefinedSetter( 3537 return SetPropertyWithDefinedSetter(
3557 JSReceiver::cast(*setter), *value); 3538 receiver, Handle<JSReceiver>::cast(setter), value);
3558 } 3539 }
3559 3540
3560 if (strict_mode == kNonStrictMode) return *value; 3541 if (strict_mode == kNonStrictMode) return value;
3561 Handle<Object> args2[] = { name, proxy }; 3542 Handle<Object> args2[] = { name, proxy };
3562 Handle<Object> error = isolate->factory()->NewTypeError( 3543 Handle<Object> error = isolate->factory()->NewTypeError(
3563 "no_setter_in_callback", HandleVector(args2, ARRAY_SIZE(args2))); 3544 "no_setter_in_callback", HandleVector(args2, ARRAY_SIZE(args2)));
3564 return isolate->Throw(*error); 3545 isolate->Throw(*error);
3546 return Handle<Object>();
3565 } 3547 }
3566 3548
3567 3549
3568 Handle<Object> JSProxy::DeletePropertyWithHandler( 3550 Handle<Object> JSProxy::DeletePropertyWithHandler(
3569 Handle<JSProxy> proxy, Handle<Name> name, DeleteMode mode) { 3551 Handle<JSProxy> proxy, Handle<Name> name, DeleteMode mode) {
3570 Isolate* isolate = proxy->GetIsolate(); 3552 Isolate* isolate = proxy->GetIsolate();
3571 3553
3572 // TODO(rossberg): adjust once there is a story for symbols vs proxies. 3554 // TODO(rossberg): adjust once there is a story for symbols vs proxies.
3573 if (name->IsSymbol()) return isolate->factory()->false_value(); 3555 if (name->IsSymbol()) return isolate->factory()->false_value();
3574 3556
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
3727 3709
3728 3710
3729 void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) { 3711 void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) {
3730 CALL_HEAP_FUNCTION_VOID( 3712 CALL_HEAP_FUNCTION_VOID(
3731 object->GetIsolate(), 3713 object->GetIsolate(),
3732 object->AllocateStorageForMap(*map)); 3714 object->AllocateStorageForMap(*map));
3733 } 3715 }
3734 3716
3735 3717
3736 void JSObject::MigrateInstance(Handle<JSObject> object) { 3718 void JSObject::MigrateInstance(Handle<JSObject> object) {
3737 CALL_HEAP_FUNCTION_VOID( 3719 // Converting any field to the most specific type will cause the
3738 object->GetIsolate(), 3720 // GeneralizeFieldRepresentation algorithm to create the most general existing
3739 object->MigrateInstance()); 3721 // transition that matches the object. This achieves what is needed.
3722 Handle<Map> original_map(object->map());
3723 GeneralizeFieldRepresentation(
3724 object, 0, Representation::None(), ALLOW_AS_CONSTANT);
3725 if (FLAG_trace_migration) {
3726 object->PrintInstanceMigration(stdout, *original_map, object->map());
3727 }
3740 } 3728 }
3741 3729
3742 3730
3743 Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) { 3731 Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) {
3744 CALL_HEAP_FUNCTION( 3732 MigrateInstance(object);
3745 object->GetIsolate(), 3733 return object;
3746 object->MigrateInstance(),
3747 Object);
3748 } 3734 }
3749 3735
3750 3736
3751 Handle<Map> Map::GeneralizeRepresentation(Handle<Map> map, 3737 Handle<Object> JSObject::SetPropertyUsingTransition(
3752 int modify_index, 3738 Handle<JSObject> object,
3753 Representation representation, 3739 LookupResult* lookup,
3754 StoreMode store_mode) { 3740 Handle<Name> name,
3755 CALL_HEAP_FUNCTION( 3741 Handle<Object> value,
3756 map->GetIsolate(), 3742 PropertyAttributes attributes) {
3757 map->GeneralizeRepresentation(modify_index, representation, store_mode), 3743 Handle<Map> transition_map(lookup->GetTransitionTarget());
3758 Map);
3759 }
3760
3761
3762 static MaybeObject* SetPropertyUsingTransition(LookupResult* lookup,
3763 Handle<Name> name,
3764 Handle<Object> value,
3765 PropertyAttributes attributes) {
3766 Map* transition_map = lookup->GetTransitionTarget();
3767 int descriptor = transition_map->LastAdded(); 3744 int descriptor = transition_map->LastAdded();
3768 3745
3769 DescriptorArray* descriptors = transition_map->instance_descriptors(); 3746 DescriptorArray* descriptors = transition_map->instance_descriptors();
3770 PropertyDetails details = descriptors->GetDetails(descriptor); 3747 PropertyDetails details = descriptors->GetDetails(descriptor);
3771 3748
3772 if (details.type() == CALLBACKS || attributes != details.attributes()) { 3749 if (details.type() == CALLBACKS || attributes != details.attributes()) {
3773 // AddProperty will either normalize the object, or create a new fast copy 3750 // AddProperty will either normalize the object, or create a new fast copy
3774 // of the map. If we get a fast copy of the map, all field representations 3751 // of the map. If we get a fast copy of the map, all field representations
3775 // will be tagged since the transition is omitted. 3752 // will be tagged since the transition is omitted.
3776 return lookup->holder()->AddProperty( 3753 return JSObject::AddProperty(
3777 *name, *value, attributes, kNonStrictMode, 3754 object, name, value, attributes, kNonStrictMode,
3778 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED, 3755 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED,
3779 JSReceiver::OMIT_EXTENSIBILITY_CHECK, 3756 JSReceiver::OMIT_EXTENSIBILITY_CHECK,
3780 JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION); 3757 JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION);
3781 } 3758 }
3782 3759
3783 // Keep the target CONSTANT if the same value is stored. 3760 // Keep the target CONSTANT if the same value is stored.
3784 // TODO(verwaest): Also support keeping the placeholder 3761 // TODO(verwaest): Also support keeping the placeholder
3785 // (value->IsUninitialized) as constant. 3762 // (value->IsUninitialized) as constant.
3786 if (details.type() == CONSTANT && 3763 if (details.type() == CONSTANT &&
3787 descriptors->GetValue(descriptor) == *value) { 3764 descriptors->GetValue(descriptor) == *value) {
3788 lookup->holder()->set_map(transition_map); 3765 object->set_map(*transition_map);
3789 return *value; 3766 return value;
3790 } 3767 }
3791 3768
3792 Representation representation = details.representation(); 3769 Representation representation = details.representation();
3793 3770
3794 if (!value->FitsRepresentation(representation) || 3771 if (!value->FitsRepresentation(representation) ||
3795 details.type() == CONSTANT) { 3772 details.type() == CONSTANT) {
3796 MaybeObject* maybe_map = transition_map->GeneralizeRepresentation( 3773 transition_map = Map::GeneralizeRepresentation(transition_map,
3797 descriptor, value->OptimalRepresentation(), FORCE_FIELD); 3774 descriptor, value->OptimalRepresentation(), FORCE_FIELD);
3798 if (!maybe_map->To(&transition_map)) return maybe_map;
3799 Object* back = transition_map->GetBackPointer(); 3775 Object* back = transition_map->GetBackPointer();
3800 if (back->IsMap()) { 3776 if (back->IsMap()) {
3801 MaybeObject* maybe_failure = 3777 MigrateToMap(object, handle(Map::cast(back)));
3802 lookup->holder()->MigrateToMap(Map::cast(back));
3803 if (maybe_failure->IsFailure()) return maybe_failure;
3804 } 3778 }
3805 descriptors = transition_map->instance_descriptors(); 3779 descriptors = transition_map->instance_descriptors();
3806 representation = descriptors->GetDetails(descriptor).representation(); 3780 representation = descriptors->GetDetails(descriptor).representation();
3807 } 3781 }
3808 3782
3809 int field_index = descriptors->GetFieldIndex(descriptor); 3783 int field_index = descriptors->GetFieldIndex(descriptor);
3810 return lookup->holder()->AddFastPropertyUsingMap( 3784 AddFastPropertyUsingMap(
3811 transition_map, *name, *value, field_index, representation); 3785 object, transition_map, name, value, field_index, representation);
3786 return value;
3812 } 3787 }
3813 3788
3814 3789
3815 static MaybeObject* SetPropertyToField(LookupResult* lookup, 3790 static void SetPropertyToField(LookupResult* lookup,
3816 Handle<Name> name, 3791 Handle<Name> name,
3817 Handle<Object> value) { 3792 Handle<Object> value) {
3818 Representation representation = lookup->representation(); 3793 Representation representation = lookup->representation();
3819 if (!value->FitsRepresentation(representation) || 3794 if (!value->FitsRepresentation(representation) ||
3820 lookup->type() == CONSTANT) { 3795 lookup->type() == CONSTANT) {
3821 MaybeObject* maybe_failure = 3796 JSObject::GeneralizeFieldRepresentation(handle(lookup->holder()),
3822 lookup->holder()->GeneralizeFieldRepresentation( 3797 lookup->GetDescriptorIndex(),
3823 lookup->GetDescriptorIndex(), 3798 value->OptimalRepresentation(),
3824 value->OptimalRepresentation(), 3799 FORCE_FIELD);
3825 FORCE_FIELD);
3826 if (maybe_failure->IsFailure()) return maybe_failure;
3827 DescriptorArray* desc = lookup->holder()->map()->instance_descriptors(); 3800 DescriptorArray* desc = lookup->holder()->map()->instance_descriptors();
3828 int descriptor = lookup->GetDescriptorIndex(); 3801 int descriptor = lookup->GetDescriptorIndex();
3829 representation = desc->GetDetails(descriptor).representation(); 3802 representation = desc->GetDetails(descriptor).representation();
3830 } 3803 }
3831 3804
3832 if (FLAG_track_double_fields && representation.IsDouble()) { 3805 if (FLAG_track_double_fields && representation.IsDouble()) {
3833 HeapNumber* storage = HeapNumber::cast(lookup->holder()->RawFastPropertyAt( 3806 HeapNumber* storage = HeapNumber::cast(lookup->holder()->RawFastPropertyAt(
3834 lookup->GetFieldIndex().field_index())); 3807 lookup->GetFieldIndex().field_index()));
3835 storage->set_value(value->Number()); 3808 storage->set_value(value->Number());
3836 return *value; 3809 return;
3837 } 3810 }
3838 3811
3839 lookup->holder()->FastPropertyAtPut( 3812 lookup->holder()->FastPropertyAtPut(
3840 lookup->GetFieldIndex().field_index(), *value); 3813 lookup->GetFieldIndex().field_index(), *value);
3841 return *value;
3842 } 3814 }
3843 3815
3844 3816
3845 static MaybeObject* ConvertAndSetLocalProperty(LookupResult* lookup, 3817 static void ConvertAndSetLocalProperty(LookupResult* lookup,
3846 Name* name, 3818 Handle<Name> name,
3847 Object* value, 3819 Handle<Object> value,
3848 PropertyAttributes attributes) { 3820 PropertyAttributes attributes) {
3849 JSObject* object = lookup->holder(); 3821 Handle<JSObject> object(lookup->holder());
3850 if (object->TooManyFastProperties()) { 3822 if (object->TooManyFastProperties()) {
3851 MaybeObject* maybe_failure = object->NormalizeProperties( 3823 JSObject::NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
3852 CLEAR_INOBJECT_PROPERTIES, 0);
3853 if (maybe_failure->IsFailure()) return maybe_failure;
3854 } 3824 }
3855 3825
3856 if (!object->HasFastProperties()) { 3826 if (!object->HasFastProperties()) {
3857 return object->ReplaceSlowProperty(name, value, attributes); 3827 ReplaceSlowProperty(object, name, value, attributes);
3828 return;
3858 } 3829 }
3859 3830
3860 int descriptor_index = lookup->GetDescriptorIndex(); 3831 int descriptor_index = lookup->GetDescriptorIndex();
3861 if (lookup->GetAttributes() == attributes) { 3832 if (lookup->GetAttributes() == attributes) {
3862 MaybeObject* maybe_failure = object->GeneralizeFieldRepresentation( 3833 JSObject::GeneralizeFieldRepresentation(
3863 descriptor_index, Representation::Tagged(), FORCE_FIELD); 3834 object, descriptor_index, Representation::Tagged(), FORCE_FIELD);
3864 if (maybe_failure->IsFailure()) return maybe_failure;
3865 } else { 3835 } else {
3866 Map* map; 3836 Handle<Map> old_map(object->map());
3867 MaybeObject* maybe_map = object->map()->CopyGeneralizeAllRepresentations( 3837 Handle<Map> new_map = Map::CopyGeneralizeAllRepresentations(old_map,
3868 descriptor_index, FORCE_FIELD, attributes, "attributes mismatch"); 3838 descriptor_index, FORCE_FIELD, attributes, "attributes mismatch");
3869 if (!maybe_map->To(&map)) return maybe_map; 3839 JSObject::MigrateToMap(object, new_map);
3870 MaybeObject* maybe_failure = object->MigrateToMap(map);
3871 if (maybe_failure->IsFailure()) return maybe_failure;
3872 } 3840 }
3873 3841
3874 DescriptorArray* descriptors = object->map()->instance_descriptors(); 3842 DescriptorArray* descriptors = object->map()->instance_descriptors();
3875 int index = descriptors->GetDetails(descriptor_index).field_index(); 3843 int index = descriptors->GetDetails(descriptor_index).field_index();
3876 object->FastPropertyAtPut(index, value); 3844 object->FastPropertyAtPut(index, *value);
3877 return value;
3878 } 3845 }
3879 3846
3880 3847
3881 static MaybeObject* SetPropertyToFieldWithAttributes( 3848 static void SetPropertyToFieldWithAttributes(LookupResult* lookup,
3882 LookupResult* lookup, 3849 Handle<Name> name,
3883 Handle<Name> name, 3850 Handle<Object> value,
3884 Handle<Object> value, 3851 PropertyAttributes attributes) {
3885 PropertyAttributes attributes) {
3886 if (lookup->GetAttributes() == attributes) { 3852 if (lookup->GetAttributes() == attributes) {
3887 if (value->IsUninitialized()) return *value; 3853 if (value->IsUninitialized()) return;
3888 return SetPropertyToField(lookup, name, value); 3854 SetPropertyToField(lookup, name, value);
3889 } else { 3855 } else {
3890 return ConvertAndSetLocalProperty(lookup, *name, *value, attributes); 3856 ConvertAndSetLocalProperty(lookup, name, value, attributes);
3891 } 3857 }
3892 } 3858 }
3893 3859
3894 3860
3895 MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup, 3861 Handle<Object> JSObject::SetPropertyForResult(Handle<JSObject> object,
3896 Name* name_raw, 3862 LookupResult* lookup,
3897 Object* value_raw, 3863 Handle<Name> name,
3898 PropertyAttributes attributes, 3864 Handle<Object> value,
3899 StrictModeFlag strict_mode, 3865 PropertyAttributes attributes,
3900 StoreFromKeyed store_mode) { 3866 StrictModeFlag strict_mode,
3901 Heap* heap = GetHeap(); 3867 StoreFromKeyed store_mode) {
3902 Isolate* isolate = heap->isolate(); 3868 Isolate* isolate = object->GetIsolate();
3903 3869
3904 // Make sure that the top context does not change when doing callbacks or 3870 // Make sure that the top context does not change when doing callbacks or
3905 // interceptor calls. 3871 // interceptor calls.
3906 AssertNoContextChangeWithHandleScope ncc; 3872 AssertNoContextChange ncc;
3907 3873
3908 // Optimization for 2-byte strings often used as keys in a decompression 3874 // Optimization for 2-byte strings often used as keys in a decompression
3909 // dictionary. We internalize these short keys to avoid constantly 3875 // dictionary. We internalize these short keys to avoid constantly
3910 // reallocating them. 3876 // reallocating them.
3911 if (name_raw->IsString() && !name_raw->IsInternalizedString() && 3877 if (name->IsString() && !name->IsInternalizedString() &&
3912 String::cast(name_raw)->length() <= 2) { 3878 Handle<String>::cast(name)->length() <= 2) {
3913 Object* internalized_version; 3879 name = isolate->factory()->InternalizeString(Handle<String>::cast(name));
3914 { MaybeObject* maybe_string_version = 3880 }
3915 heap->InternalizeString(String::cast(name_raw)); 3881
3916 if (maybe_string_version->ToObject(&internalized_version)) { 3882 // Check access rights if needed.
3917 name_raw = String::cast(internalized_version); 3883 if (object->IsAccessCheckNeeded()) {
3918 } 3884 if (!isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) {
3885 return SetPropertyWithFailedAccessCheck(object, lookup, name, value,
3886 true, strict_mode);
3919 } 3887 }
3920 } 3888 }
3921 3889
3922 // Check access rights if needed. 3890 if (object->IsJSGlobalProxy()) {
3923 if (IsAccessCheckNeeded()) { 3891 Handle<Object> proto(object->GetPrototype(), isolate);
3924 if (!isolate->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) { 3892 if (proto->IsNull()) return value;
3925 return SetPropertyWithFailedAccessCheck( 3893 ASSERT(proto->IsJSGlobalObject());
3926 lookup, name_raw, value_raw, true, strict_mode); 3894 return SetPropertyForResult(Handle<JSObject>::cast(proto),
3927 } 3895 lookup, name, value, attributes, strict_mode, store_mode);
3928 } 3896 }
3929 3897
3930 if (IsJSGlobalProxy()) { 3898 ASSERT(!lookup->IsFound() || lookup->holder() == *object ||
3931 Object* proto = GetPrototype();
3932 if (proto->IsNull()) return value_raw;
3933 ASSERT(proto->IsJSGlobalObject());
3934 return JSObject::cast(proto)->SetPropertyForResult(
3935 lookup, name_raw, value_raw, attributes, strict_mode, store_mode);
3936 }
3937
3938 ASSERT(!lookup->IsFound() || lookup->holder() == this ||
3939 lookup->holder()->map()->is_hidden_prototype()); 3899 lookup->holder()->map()->is_hidden_prototype());
3940 3900
3941 // From this point on everything needs to be handlified, because 3901 if (!lookup->IsProperty() && !object->IsJSContextExtensionObject()) {
3942 // SetPropertyViaPrototypes might call back into JavaScript.
3943 HandleScope scope(isolate);
3944 Handle<JSObject> self(this);
3945 Handle<Name> name(name_raw);
3946 Handle<Object> value(value_raw, isolate);
3947
3948 if (!lookup->IsProperty() && !self->IsJSContextExtensionObject()) {
3949 bool done = false; 3902 bool done = false;
3950 MaybeObject* result_object = self->SetPropertyViaPrototypes( 3903 Handle<Object> result_object = SetPropertyViaPrototypes(
3951 *name, *value, attributes, strict_mode, &done); 3904 object, name, value, attributes, strict_mode, &done);
3952 if (done) return result_object; 3905 if (done) return result_object;
3953 } 3906 }
3954 3907
3955 if (!lookup->IsFound()) { 3908 if (!lookup->IsFound()) {
3956 // Neither properties nor transitions found. 3909 // Neither properties nor transitions found.
3957 return self->AddProperty( 3910 return AddProperty(
3958 *name, *value, attributes, strict_mode, store_mode); 3911 object, name, value, attributes, strict_mode, store_mode);
3959 } 3912 }
3960 3913
3961 if (lookup->IsProperty() && lookup->IsReadOnly()) { 3914 if (lookup->IsProperty() && lookup->IsReadOnly()) {
3962 if (strict_mode == kStrictMode) { 3915 if (strict_mode == kStrictMode) {
3963 Handle<Object> args[] = { name, self }; 3916 Handle<Object> args[] = { name, object };
3964 return isolate->Throw(*isolate->factory()->NewTypeError( 3917 Handle<Object> error = isolate->factory()->NewTypeError(
3965 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)))); 3918 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)));
3919 isolate->Throw(*error);
3920 return Handle<Object>();
3966 } else { 3921 } else {
3967 return *value; 3922 return value;
3968 } 3923 }
3969 } 3924 }
3970 3925
3971 Handle<Object> old_value(heap->the_hole_value(), isolate); 3926 Handle<Object> old_value = isolate->factory()->the_hole_value();
3972 if (FLAG_harmony_observation && 3927 if (FLAG_harmony_observation &&
3973 map()->is_observed() && lookup->IsDataProperty()) { 3928 object->map()->is_observed() && lookup->IsDataProperty()) {
3974 old_value = Object::GetProperty(self, name); 3929 old_value = Object::GetProperty(object, name);
3975 } 3930 }
3976 3931
3977 // This is a real property that is not read-only, or it is a 3932 // This is a real property that is not read-only, or it is a
3978 // transition or null descriptor and there are no setters in the prototypes. 3933 // transition or null descriptor and there are no setters in the prototypes.
3979 MaybeObject* result = *value; 3934 Handle<Object> result = value;
3980 switch (lookup->type()) { 3935 switch (lookup->type()) {
3981 case NORMAL: 3936 case NORMAL:
3982 result = lookup->holder()->SetNormalizedProperty(lookup, *value); 3937 SetNormalizedProperty(handle(lookup->holder()), lookup, value);
3983 break; 3938 break;
3984 case FIELD: 3939 case FIELD:
3985 result = SetPropertyToField(lookup, name, value); 3940 SetPropertyToField(lookup, name, value);
3986 break; 3941 break;
3987 case CONSTANT: 3942 case CONSTANT:
3988 // Only replace the constant if necessary. 3943 // Only replace the constant if necessary.
3989 if (*value == lookup->GetConstant()) return *value; 3944 if (*value == lookup->GetConstant()) return value;
3990 result = SetPropertyToField(lookup, name, value); 3945 SetPropertyToField(lookup, name, value);
3991 break; 3946 break;
3992 case CALLBACKS: { 3947 case CALLBACKS: {
3993 Object* callback_object = lookup->GetCallbackObject(); 3948 Handle<Object> callback_object(lookup->GetCallbackObject(), isolate);
3994 return self->SetPropertyWithCallback( 3949 return SetPropertyWithCallback(object, callback_object, name, value,
3995 callback_object, *name, *value, lookup->holder(), strict_mode); 3950 handle(lookup->holder()), strict_mode);
3996 } 3951 }
3997 case INTERCEPTOR: 3952 case INTERCEPTOR:
3998 result = lookup->holder()->SetPropertyWithInterceptor( 3953 result = SetPropertyWithInterceptor(handle(lookup->holder()), name, value,
3999 *name, *value, attributes, strict_mode); 3954 attributes, strict_mode);
4000 break; 3955 break;
4001 case TRANSITION: { 3956 case TRANSITION:
4002 result = SetPropertyUsingTransition(lookup, name, value, attributes); 3957 result = SetPropertyUsingTransition(handle(lookup->holder()), lookup,
3958 name, value, attributes);
4003 break; 3959 break;
4004 }
4005 case HANDLER: 3960 case HANDLER:
4006 case NONEXISTENT: 3961 case NONEXISTENT:
4007 UNREACHABLE(); 3962 UNREACHABLE();
4008 } 3963 }
4009 3964
4010 Handle<Object> hresult; 3965 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<Object>());
4011 if (!result->ToHandle(&hresult, isolate)) return result;
4012 3966
4013 if (FLAG_harmony_observation && self->map()->is_observed()) { 3967 if (FLAG_harmony_observation && object->map()->is_observed()) {
4014 if (lookup->IsTransition()) { 3968 if (lookup->IsTransition()) {
4015 EnqueueChangeRecord(self, "new", name, old_value); 3969 EnqueueChangeRecord(object, "new", name, old_value);
4016 } else { 3970 } else {
4017 LookupResult new_lookup(isolate); 3971 LookupResult new_lookup(isolate);
4018 self->LocalLookup(*name, &new_lookup, true); 3972 object->LocalLookup(*name, &new_lookup, true);
4019 if (new_lookup.IsDataProperty()) { 3973 if (new_lookup.IsDataProperty()) {
4020 Handle<Object> new_value = Object::GetProperty(self, name); 3974 Handle<Object> new_value = Object::GetProperty(object, name);
4021 if (!new_value->SameValue(*old_value)) { 3975 if (!new_value->SameValue(*old_value)) {
4022 EnqueueChangeRecord(self, "updated", name, old_value); 3976 EnqueueChangeRecord(object, "updated", name, old_value);
4023 } 3977 }
4024 } 3978 }
4025 } 3979 }
4026 } 3980 }
4027 3981
4028 return *hresult; 3982 return result;
4029 } 3983 }
4030 3984
4031 3985
4032 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributesTrampoline( 3986 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributesTrampoline(
4033 Name* key, 3987 Name* key,
4034 Object* value, 3988 Object* value,
4035 PropertyAttributes attributes, 3989 PropertyAttributes attributes,
4036 ValueType value_type, 3990 ValueType value_type,
4037 StoreMode mode, 3991 StoreMode mode,
4038 ExtensibilityCheck extensibility_check) { 3992 ExtensibilityCheck extensibility_check) {
(...skipping 17 matching lines...) Expand all
4056 // present, add it with attributes NONE. This code is an exact clone of 4010 // present, add it with attributes NONE. This code is an exact clone of
4057 // SetProperty, with the check for IsReadOnly and the check for a 4011 // SetProperty, with the check for IsReadOnly and the check for a
4058 // callback setter removed. The two lines looking up the LookupResult 4012 // callback setter removed. The two lines looking up the LookupResult
4059 // result are also added. If one of the functions is changed, the other 4013 // result are also added. If one of the functions is changed, the other
4060 // should be. 4014 // should be.
4061 // Note that this method cannot be used to set the prototype of a function 4015 // Note that this method cannot be used to set the prototype of a function
4062 // because ConvertDescriptorToField() which is called in "case CALLBACKS:" 4016 // because ConvertDescriptorToField() which is called in "case CALLBACKS:"
4063 // doesn't handle function prototypes correctly. 4017 // doesn't handle function prototypes correctly.
4064 Handle<Object> JSObject::SetLocalPropertyIgnoreAttributes( 4018 Handle<Object> JSObject::SetLocalPropertyIgnoreAttributes(
4065 Handle<JSObject> object, 4019 Handle<JSObject> object,
4066 Handle<Name> key, 4020 Handle<Name> name,
4067 Handle<Object> value, 4021 Handle<Object> value,
4068 PropertyAttributes attributes, 4022 PropertyAttributes attributes,
4069 ValueType value_type, 4023 ValueType value_type,
4070 StoreMode mode, 4024 StoreMode mode,
4071 ExtensibilityCheck extensibility_check) { 4025 ExtensibilityCheck extensibility_check) {
4072 CALL_HEAP_FUNCTION( 4026 Isolate* isolate = object->GetIsolate();
4073 object->GetIsolate(),
4074 object->SetLocalPropertyIgnoreAttributes(
4075 *key, *value, attributes, value_type, mode, extensibility_check),
4076 Object);
4077 }
4078 4027
4079
4080 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes(
4081 Name* name_raw,
4082 Object* value_raw,
4083 PropertyAttributes attributes,
4084 ValueType value_type,
4085 StoreMode mode,
4086 ExtensibilityCheck extensibility_check) {
4087 // Make sure that the top context does not change when doing callbacks or 4028 // Make sure that the top context does not change when doing callbacks or
4088 // interceptor calls. 4029 // interceptor calls.
4089 AssertNoContextChangeWithHandleScope ncc; 4030 AssertNoContextChange ncc;
4090 Isolate* isolate = GetIsolate(); 4031
4091 LookupResult lookup(isolate); 4032 LookupResult lookup(isolate);
4092 LocalLookup(name_raw, &lookup, true); 4033 object->LocalLookup(*name, &lookup, true);
4093 if (!lookup.IsFound()) map()->LookupTransition(this, name_raw, &lookup); 4034 if (!lookup.IsFound()) {
4035 object->map()->LookupTransition(*object, *name, &lookup);
4036 }
4037
4094 // Check access rights if needed. 4038 // Check access rights if needed.
4095 if (IsAccessCheckNeeded()) { 4039 if (object->IsAccessCheckNeeded()) {
4096 if (!isolate->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) { 4040 if (!isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) {
4097 return SetPropertyWithFailedAccessCheck(&lookup, 4041 return SetPropertyWithFailedAccessCheck(object, &lookup, name, value,
4098 name_raw, 4042 false, kNonStrictMode);
4099 value_raw,
4100 false,
4101 kNonStrictMode);
4102 } 4043 }
4103 } 4044 }
4104 4045
4105 if (IsJSGlobalProxy()) { 4046 if (object->IsJSGlobalProxy()) {
4106 Object* proto = GetPrototype(); 4047 Handle<Object> proto(object->GetPrototype(), isolate);
4107 if (proto->IsNull()) return value_raw; 4048 if (proto->IsNull()) return value;
4108 ASSERT(proto->IsJSGlobalObject()); 4049 ASSERT(proto->IsJSGlobalObject());
4109 return JSObject::cast(proto)->SetLocalPropertyIgnoreAttributes( 4050 return SetLocalPropertyIgnoreAttributes(Handle<JSObject>::cast(proto),
4110 name_raw, 4051 name, value, attributes, value_type, mode, extensibility_check);
4111 value_raw,
4112 attributes,
4113 value_type,
4114 mode,
4115 extensibility_check);
4116 } 4052 }
4117 4053
4118 if (lookup.IsFound() && 4054 if (lookup.IsFound() &&
4119 (lookup.type() == INTERCEPTOR || lookup.type() == CALLBACKS)) { 4055 (lookup.type() == INTERCEPTOR || lookup.type() == CALLBACKS)) {
4120 LocalLookupRealNamedProperty(name_raw, &lookup); 4056 object->LocalLookupRealNamedProperty(*name, &lookup);
4121 } 4057 }
4122 4058
4123 // Check for accessor in prototype chain removed here in clone. 4059 // Check for accessor in prototype chain removed here in clone.
4124 if (!lookup.IsFound()) { 4060 if (!lookup.IsFound()) {
4125 // Neither properties nor transitions found. 4061 // Neither properties nor transitions found.
4126 return AddProperty( 4062 return AddProperty(object, name, value, attributes, kNonStrictMode,
4127 name_raw, value_raw, attributes, kNonStrictMode,
4128 MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode); 4063 MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode);
4129 } 4064 }
4130 4065
4131 // From this point on everything needs to be handlified. 4066 Handle<Object> old_value = isolate->factory()->the_hole_value();
4132 HandleScope scope(isolate);
4133 Handle<JSObject> self(this);
4134 Handle<Name> name(name_raw);
4135 Handle<Object> value(value_raw, isolate);
4136
4137 Handle<Object> old_value(isolate->heap()->the_hole_value(), isolate);
4138 PropertyAttributes old_attributes = ABSENT; 4067 PropertyAttributes old_attributes = ABSENT;
4139 bool is_observed = FLAG_harmony_observation && self->map()->is_observed(); 4068 bool is_observed = FLAG_harmony_observation && object->map()->is_observed();
4140 if (is_observed && lookup.IsProperty()) { 4069 if (is_observed && lookup.IsProperty()) {
4141 if (lookup.IsDataProperty()) old_value = 4070 if (lookup.IsDataProperty()) old_value =
4142 Object::GetProperty(self, name); 4071 Object::GetProperty(object, name);
4143 old_attributes = lookup.GetAttributes(); 4072 old_attributes = lookup.GetAttributes();
4144 } 4073 }
4145 4074
4146 // Check of IsReadOnly removed from here in clone. 4075 // Check of IsReadOnly removed from here in clone.
4147 MaybeObject* result = *value;
4148 switch (lookup.type()) { 4076 switch (lookup.type()) {
4149 case NORMAL: 4077 case NORMAL:
4150 result = self->ReplaceSlowProperty(*name, *value, attributes); 4078 ReplaceSlowProperty(object, name, value, attributes);
4151 break; 4079 break;
4152 case FIELD: 4080 case FIELD:
4153 result = SetPropertyToFieldWithAttributes( 4081 SetPropertyToFieldWithAttributes(&lookup, name, value, attributes);
4154 &lookup, name, value, attributes);
4155 break; 4082 break;
4156 case CONSTANT: 4083 case CONSTANT:
4157 // Only replace the constant if necessary. 4084 // Only replace the constant if necessary.
4158 if (lookup.GetAttributes() != attributes || 4085 if (lookup.GetAttributes() != attributes ||
4159 *value != lookup.GetConstant()) { 4086 *value != lookup.GetConstant()) {
4160 result = SetPropertyToFieldWithAttributes( 4087 SetPropertyToFieldWithAttributes(&lookup, name, value, attributes);
4161 &lookup, name, value, attributes);
4162 } 4088 }
4163 break; 4089 break;
4164 case CALLBACKS: 4090 case CALLBACKS:
4165 result = ConvertAndSetLocalProperty(&lookup, *name, *value, attributes); 4091 ConvertAndSetLocalProperty(&lookup, name, value, attributes);
4166 break; 4092 break;
4167 case TRANSITION: 4093 case TRANSITION: {
4168 result = SetPropertyUsingTransition(&lookup, name, value, attributes); 4094 Handle<Object> result = SetPropertyUsingTransition(
4095 handle(lookup.holder()), &lookup, name, value, attributes);
4096 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<Object>());
4169 break; 4097 break;
4098 }
4170 case NONEXISTENT: 4099 case NONEXISTENT:
4171 case HANDLER: 4100 case HANDLER:
4172 case INTERCEPTOR: 4101 case INTERCEPTOR:
4173 UNREACHABLE(); 4102 UNREACHABLE();
4174 } 4103 }
4175 4104
4176 Handle<Object> hresult;
4177 if (!result->ToHandle(&hresult, isolate)) return result;
4178
4179 if (is_observed) { 4105 if (is_observed) {
4180 if (lookup.IsTransition()) { 4106 if (lookup.IsTransition()) {
4181 EnqueueChangeRecord(self, "new", name, old_value); 4107 EnqueueChangeRecord(object, "new", name, old_value);
4182 } else if (old_value->IsTheHole()) { 4108 } else if (old_value->IsTheHole()) {
4183 EnqueueChangeRecord(self, "reconfigured", name, old_value); 4109 EnqueueChangeRecord(object, "reconfigured", name, old_value);
4184 } else { 4110 } else {
4185 LookupResult new_lookup(isolate); 4111 LookupResult new_lookup(isolate);
4186 self->LocalLookup(*name, &new_lookup, true); 4112 object->LocalLookup(*name, &new_lookup, true);
4187 bool value_changed = false; 4113 bool value_changed = false;
4188 if (new_lookup.IsDataProperty()) { 4114 if (new_lookup.IsDataProperty()) {
4189 Handle<Object> new_value = Object::GetProperty(self, name); 4115 Handle<Object> new_value = Object::GetProperty(object, name);
4190 value_changed = !old_value->SameValue(*new_value); 4116 value_changed = !old_value->SameValue(*new_value);
4191 } 4117 }
4192 if (new_lookup.GetAttributes() != old_attributes) { 4118 if (new_lookup.GetAttributes() != old_attributes) {
4193 if (!value_changed) old_value = isolate->factory()->the_hole_value(); 4119 if (!value_changed) old_value = isolate->factory()->the_hole_value();
4194 EnqueueChangeRecord(self, "reconfigured", name, old_value); 4120 EnqueueChangeRecord(object, "reconfigured", name, old_value);
4195 } else if (value_changed) { 4121 } else if (value_changed) {
4196 EnqueueChangeRecord(self, "updated", name, old_value); 4122 EnqueueChangeRecord(object, "updated", name, old_value);
4197 } 4123 }
4198 } 4124 }
4199 } 4125 }
4200 4126
4201 return *hresult; 4127 return value;
4202 } 4128 }
4203 4129
4204 4130
4205 PropertyAttributes JSObject::GetPropertyAttributePostInterceptor( 4131 PropertyAttributes JSObject::GetPropertyAttributePostInterceptor(
4206 JSObject* receiver, 4132 JSObject* receiver,
4207 Name* name, 4133 Name* name,
4208 bool continue_search) { 4134 bool continue_search) {
4209 // Check local property, ignore interceptor. 4135 // Check local property, ignore interceptor.
4210 LookupResult result(GetIsolate()); 4136 LookupResult result(GetIsolate());
4211 LocalLookupRealNamedProperty(name, &result); 4137 LocalLookupRealNamedProperty(name, &result);
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after
4660 PropertyDetails details = PropertyDetails(NONE, NORMAL, 0); 4586 PropertyDetails details = PropertyDetails(NONE, NORMAL, 0);
4661 MaybeObject* maybe_result = 4587 MaybeObject* maybe_result =
4662 dictionary->AddNumberEntry(i, value, details); 4588 dictionary->AddNumberEntry(i, value, details);
4663 if (!maybe_result->To(&dictionary)) return maybe_result; 4589 if (!maybe_result->To(&dictionary)) return maybe_result;
4664 } 4590 }
4665 } 4591 }
4666 return dictionary; 4592 return dictionary;
4667 } 4593 }
4668 4594
4669 4595
4596 static Handle<SeededNumberDictionary> CopyFastElementsToDictionary(
4597 Handle<FixedArrayBase> array,
4598 int length,
4599 Handle<SeededNumberDictionary> dict) {
4600 Isolate* isolate = array->GetIsolate();
4601 CALL_HEAP_FUNCTION(isolate,
4602 CopyFastElementsToDictionary(
4603 isolate, *array, length, *dict),
4604 SeededNumberDictionary);
4605 }
4606
4607
4670 Handle<SeededNumberDictionary> JSObject::NormalizeElements( 4608 Handle<SeededNumberDictionary> JSObject::NormalizeElements(
4671 Handle<JSObject> object) { 4609 Handle<JSObject> object) {
4672 CALL_HEAP_FUNCTION(object->GetIsolate(), 4610 CALL_HEAP_FUNCTION(object->GetIsolate(),
4673 object->NormalizeElements(), 4611 object->NormalizeElements(),
4674 SeededNumberDictionary); 4612 SeededNumberDictionary);
4675 } 4613 }
4676 4614
4677 4615
4678 MaybeObject* JSObject::NormalizeElements() { 4616 MaybeObject* JSObject::NormalizeElements() {
4679 ASSERT(!HasExternalArrayElements()); 4617 ASSERT(!HasExternalArrayElements());
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after
5145 if (object->IsJSGlobalProxy()) { 5083 if (object->IsJSGlobalProxy()) {
5146 Handle<Object> proto(object->GetPrototype(), isolate); 5084 Handle<Object> proto(object->GetPrototype(), isolate);
5147 if (proto->IsNull()) return factory->false_value(); 5085 if (proto->IsNull()) return factory->false_value();
5148 ASSERT(proto->IsJSGlobalObject()); 5086 ASSERT(proto->IsJSGlobalObject());
5149 return DeleteElement(Handle<JSObject>::cast(proto), index, mode); 5087 return DeleteElement(Handle<JSObject>::cast(proto), index, mode);
5150 } 5088 }
5151 5089
5152 Handle<Object> old_value; 5090 Handle<Object> old_value;
5153 bool should_enqueue_change_record = false; 5091 bool should_enqueue_change_record = false;
5154 if (FLAG_harmony_observation && object->map()->is_observed()) { 5092 if (FLAG_harmony_observation && object->map()->is_observed()) {
5155 should_enqueue_change_record = object->HasLocalElement(index); 5093 should_enqueue_change_record = HasLocalElement(object, index);
5156 if (should_enqueue_change_record) { 5094 if (should_enqueue_change_record) {
5157 old_value = object->GetLocalElementAccessorPair(index) != NULL 5095 old_value = object->GetLocalElementAccessorPair(index) != NULL
5158 ? Handle<Object>::cast(factory->the_hole_value()) 5096 ? Handle<Object>::cast(factory->the_hole_value())
5159 : Object::GetElement(isolate, object, index); 5097 : Object::GetElement(isolate, object, index);
5160 } 5098 }
5161 } 5099 }
5162 5100
5163 // Skip interceptor if forcing deletion. 5101 // Skip interceptor if forcing deletion.
5164 Handle<Object> result; 5102 Handle<Object> result;
5165 if (object->HasIndexedInterceptor() && mode != FORCE_DELETION) { 5103 if (object->HasIndexedInterceptor() && mode != FORCE_DELETION) {
5166 result = DeleteElementWithInterceptor(object, index); 5104 result = DeleteElementWithInterceptor(object, index);
5167 } else { 5105 } else {
5168 result = AccessorDelete(object, index, mode); 5106 result = AccessorDelete(object, index, mode);
5169 } 5107 }
5170 5108
5171 if (should_enqueue_change_record && !object->HasLocalElement(index)) { 5109 if (should_enqueue_change_record && !HasLocalElement(object, index)) {
5172 Handle<String> name = factory->Uint32ToString(index); 5110 Handle<String> name = factory->Uint32ToString(index);
5173 EnqueueChangeRecord(object, "deleted", name, old_value); 5111 EnqueueChangeRecord(object, "deleted", name, old_value);
5174 } 5112 }
5175 5113
5176 return result; 5114 return result;
5177 } 5115 }
5178 5116
5179 5117
5180 Handle<Object> JSObject::DeleteProperty(Handle<JSObject> object, 5118 Handle<Object> JSObject::DeleteProperty(Handle<JSObject> object,
5181 Handle<Name> name, 5119 Handle<Name> name,
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
5236 } else { 5174 } else {
5237 result = DeletePropertyWithInterceptor(object, name); 5175 result = DeletePropertyWithInterceptor(object, name);
5238 } 5176 }
5239 } else { 5177 } else {
5240 // Normalize object if needed. 5178 // Normalize object if needed.
5241 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); 5179 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
5242 // Make sure the properties are normalized before removing the entry. 5180 // Make sure the properties are normalized before removing the entry.
5243 result = DeleteNormalizedProperty(object, name, mode); 5181 result = DeleteNormalizedProperty(object, name, mode);
5244 } 5182 }
5245 5183
5246 if (is_observed && !object->HasLocalProperty(*name)) { 5184 if (is_observed && !HasLocalProperty(object, name)) {
5247 EnqueueChangeRecord(object, "deleted", name, old_value); 5185 EnqueueChangeRecord(object, "deleted", name, old_value);
5248 } 5186 }
5249 5187
5250 return result; 5188 return result;
5251 } 5189 }
5252 5190
5253 5191
5254 Handle<Object> JSReceiver::DeleteElement(Handle<JSReceiver> object, 5192 Handle<Object> JSReceiver::DeleteElement(Handle<JSReceiver> object,
5255 uint32_t index, 5193 uint32_t index,
5256 DeleteMode mode) { 5194 DeleteMode mode) {
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
5475 attrs |= READ_ONLY; 5413 attrs |= READ_ONLY;
5476 } 5414 }
5477 details = details.CopyAddAttributes( 5415 details = details.CopyAddAttributes(
5478 static_cast<PropertyAttributes>(attrs)); 5416 static_cast<PropertyAttributes>(attrs));
5479 dictionary->DetailsAtPut(i, details); 5417 dictionary->DetailsAtPut(i, details);
5480 } 5418 }
5481 } 5419 }
5482 } 5420 }
5483 5421
5484 5422
5485 MUST_USE_RESULT MaybeObject* JSObject::Freeze(Isolate* isolate) { 5423 Handle<Object> JSObject::Freeze(Handle<JSObject> object) {
5486 // Freezing non-strict arguments should be handled elsewhere. 5424 // Freezing non-strict arguments should be handled elsewhere.
5487 ASSERT(!HasNonStrictArgumentsElements()); 5425 ASSERT(!object->HasNonStrictArgumentsElements());
5488 5426
5489 Heap* heap = isolate->heap(); 5427 if (object->map()->is_frozen()) return object;
5490 5428
5491 if (map()->is_frozen()) return this; 5429 Isolate* isolate = object->GetIsolate();
5492 5430 if (object->IsAccessCheckNeeded() &&
5493 if (IsAccessCheckNeeded() && 5431 !isolate->MayNamedAccess(*object,
5494 !isolate->MayNamedAccess(this, 5432 isolate->heap()->undefined_value(),
5495 heap->undefined_value(),
5496 v8::ACCESS_KEYS)) { 5433 v8::ACCESS_KEYS)) {
5497 isolate->ReportFailedAccessCheck(this, v8::ACCESS_KEYS); 5434 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_KEYS);
5498 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 5435 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
5499 return heap->false_value(); 5436 return isolate->factory()->false_value();
5500 } 5437 }
5501 5438
5502 if (IsJSGlobalProxy()) { 5439 if (object->IsJSGlobalProxy()) {
5503 Object* proto = GetPrototype(); 5440 Handle<Object> proto(object->GetPrototype(), isolate);
5504 if (proto->IsNull()) return this; 5441 if (proto->IsNull()) return object;
5505 ASSERT(proto->IsJSGlobalObject()); 5442 ASSERT(proto->IsJSGlobalObject());
5506 return JSObject::cast(proto)->Freeze(isolate); 5443 return Freeze(Handle<JSObject>::cast(proto));
5507 } 5444 }
5508 5445
5509 // It's not possible to freeze objects with external array elements 5446 // It's not possible to freeze objects with external array elements
5510 if (HasExternalArrayElements()) { 5447 if (object->HasExternalArrayElements()) {
5511 HandleScope scope(isolate);
5512 Handle<Object> object(this, isolate);
5513 Handle<Object> error = 5448 Handle<Object> error =
5514 isolate->factory()->NewTypeError( 5449 isolate->factory()->NewTypeError(
5515 "cant_prevent_ext_external_array_elements", 5450 "cant_prevent_ext_external_array_elements",
5516 HandleVector(&object, 1)); 5451 HandleVector(&object, 1));
5517 return isolate->Throw(*error); 5452 isolate->Throw(*error);
5453 return Handle<Object>();
5518 } 5454 }
5519 5455
5520 SeededNumberDictionary* new_element_dictionary = NULL; 5456 Handle<SeededNumberDictionary> new_element_dictionary;
5521 if (!elements()->IsDictionary()) { 5457 if (!object->elements()->IsDictionary()) {
5522 int length = IsJSArray() 5458 int length = object->IsJSArray()
5523 ? Smi::cast(JSArray::cast(this)->length())->value() 5459 ? Smi::cast(Handle<JSArray>::cast(object)->length())->value()
5524 : elements()->length(); 5460 : object->elements()->length();
5525 if (length > 0) { 5461 if (length > 0) {
5526 int capacity = 0; 5462 int capacity = 0;
5527 int used = 0; 5463 int used = 0;
5528 GetElementsCapacityAndUsage(&capacity, &used); 5464 object->GetElementsCapacityAndUsage(&capacity, &used);
5529 MaybeObject* maybe_dict = SeededNumberDictionary::Allocate(heap, used); 5465 new_element_dictionary =
5530 if (!maybe_dict->To(&new_element_dictionary)) return maybe_dict; 5466 isolate->factory()->NewSeededNumberDictionary(used);
5531 5467
5532 // Move elements to a dictionary; avoid calling NormalizeElements to avoid 5468 // Move elements to a dictionary; avoid calling NormalizeElements to avoid
5533 // unnecessary transitions. 5469 // unnecessary transitions.
5534 maybe_dict = CopyFastElementsToDictionary(isolate, elements(), length, 5470 new_element_dictionary = CopyFastElementsToDictionary(
5535 new_element_dictionary); 5471 handle(object->elements()), length, new_element_dictionary);
5536 if (!maybe_dict->To(&new_element_dictionary)) return maybe_dict;
5537 } else { 5472 } else {
5538 // No existing elements, use a pre-allocated empty backing store 5473 // No existing elements, use a pre-allocated empty backing store
5539 new_element_dictionary = heap->empty_slow_element_dictionary(); 5474 new_element_dictionary =
5475 isolate->factory()->empty_slow_element_dictionary();
5540 } 5476 }
5541 } 5477 }
5542 5478
5543 LookupResult result(isolate); 5479 LookupResult result(isolate);
5544 map()->LookupTransition(this, heap->frozen_symbol(), &result); 5480 Handle<Map> old_map(object->map());
5481 old_map->LookupTransition(*object, isolate->heap()->frozen_symbol(), &result);
5545 if (result.IsTransition()) { 5482 if (result.IsTransition()) {
5546 Map* transition_map = result.GetTransitionTarget(); 5483 Map* transition_map = result.GetTransitionTarget();
5547 ASSERT(transition_map->has_dictionary_elements()); 5484 ASSERT(transition_map->has_dictionary_elements());
5548 ASSERT(transition_map->is_frozen()); 5485 ASSERT(transition_map->is_frozen());
5549 ASSERT(!transition_map->is_extensible()); 5486 ASSERT(!transition_map->is_extensible());
5550 set_map(transition_map); 5487 object->set_map(transition_map);
5551 } else if (HasFastProperties() && map()->CanHaveMoreTransitions()) { 5488 } else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) {
5552 // Create a new descriptor array with fully-frozen properties 5489 // Create a new descriptor array with fully-frozen properties
5553 int num_descriptors = map()->NumberOfOwnDescriptors(); 5490 int num_descriptors = old_map->NumberOfOwnDescriptors();
5554 DescriptorArray* new_descriptors; 5491 Handle<DescriptorArray> new_descriptors =
5555 MaybeObject* maybe_descriptors = 5492 DescriptorArray::CopyUpToAddAttributes(
5556 map()->instance_descriptors()->CopyUpToAddAttributes(num_descriptors, 5493 handle(old_map->instance_descriptors()), num_descriptors, FROZEN);
5557 FROZEN); 5494 Handle<Map> new_map = Map::CopyReplaceDescriptors(
5558 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; 5495 old_map, new_descriptors, INSERT_TRANSITION,
5559 5496 isolate->factory()->frozen_symbol());
5560 Map* new_map;
5561 MaybeObject* maybe_new_map = map()->CopyReplaceDescriptors(
5562 new_descriptors, INSERT_TRANSITION, heap->frozen_symbol());
5563 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
5564 new_map->freeze(); 5497 new_map->freeze();
5565 new_map->set_is_extensible(false); 5498 new_map->set_is_extensible(false);
5566 new_map->set_elements_kind(DICTIONARY_ELEMENTS); 5499 new_map->set_elements_kind(DICTIONARY_ELEMENTS);
5567 set_map(new_map); 5500 object->set_map(*new_map);
5568 } else { 5501 } else {
5569 // Slow path: need to normalize properties for safety 5502 // Slow path: need to normalize properties for safety
5570 MaybeObject* maybe = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); 5503 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
5571 if (maybe->IsFailure()) return maybe;
5572 5504
5573 // Create a new map, since other objects with this map may be extensible. 5505 // Create a new map, since other objects with this map may be extensible.
5574 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps. 5506 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps.
5575 Map* new_map; 5507 Handle<Map> new_map = Map::Copy(handle(object->map()));
5576 MaybeObject* maybe_copy = map()->Copy();
5577 if (!maybe_copy->To(&new_map)) return maybe_copy;
5578 new_map->freeze(); 5508 new_map->freeze();
5579 new_map->set_is_extensible(false); 5509 new_map->set_is_extensible(false);
5580 new_map->set_elements_kind(DICTIONARY_ELEMENTS); 5510 new_map->set_elements_kind(DICTIONARY_ELEMENTS);
5581 set_map(new_map); 5511 object->set_map(*new_map);
5582 5512
5583 // Freeze dictionary-mode properties 5513 // Freeze dictionary-mode properties
5584 FreezeDictionary(property_dictionary()); 5514 FreezeDictionary(object->property_dictionary());
5585 } 5515 }
5586 5516
5587 ASSERT(map()->has_dictionary_elements()); 5517 ASSERT(object->map()->has_dictionary_elements());
5588 if (new_element_dictionary != NULL) { 5518 if (!new_element_dictionary.is_null()) {
5589 set_elements(new_element_dictionary); 5519 object->set_elements(*new_element_dictionary);
5590 } 5520 }
5591 5521
5592 if (elements() != heap->empty_slow_element_dictionary()) { 5522 if (object->elements() != isolate->heap()->empty_slow_element_dictionary()) {
5593 SeededNumberDictionary* dictionary = element_dictionary(); 5523 SeededNumberDictionary* dictionary = object->element_dictionary();
5594 // Make sure we never go back to the fast case 5524 // Make sure we never go back to the fast case
5595 dictionary->set_requires_slow_elements(); 5525 dictionary->set_requires_slow_elements();
5596 // Freeze all elements in the dictionary 5526 // Freeze all elements in the dictionary
5597 FreezeDictionary(dictionary); 5527 FreezeDictionary(dictionary);
5598 } 5528 }
5599 5529
5600 return this; 5530 return object;
5601 } 5531 }
5602 5532
5603 5533
5604 MUST_USE_RESULT MaybeObject* JSObject::SetObserved(Isolate* isolate) { 5534 MUST_USE_RESULT MaybeObject* JSObject::SetObserved(Isolate* isolate) {
5605 if (map()->is_observed()) 5535 if (map()->is_observed())
5606 return isolate->heap()->undefined_value(); 5536 return isolate->heap()->undefined_value();
5607 5537
5608 Heap* heap = isolate->heap(); 5538 Heap* heap = isolate->heap();
5609 5539
5610 if (!HasExternalArrayElements()) { 5540 if (!HasExternalArrayElements()) {
(...skipping 17 matching lines...) Expand all
5628 MaybeObject* maybe_copy = map()->Copy(); 5558 MaybeObject* maybe_copy = map()->Copy();
5629 if (!maybe_copy->To(&new_map)) return maybe_copy; 5559 if (!maybe_copy->To(&new_map)) return maybe_copy;
5630 new_map->set_is_observed(true); 5560 new_map->set_is_observed(true);
5631 } 5561 }
5632 set_map(new_map); 5562 set_map(new_map);
5633 5563
5634 return heap->undefined_value(); 5564 return heap->undefined_value();
5635 } 5565 }
5636 5566
5637 5567
5638 // TODO(mstarzinger): Temporary wrapper until handlified.
5639 static Handle<Object> NewStorageFor(Isolate* isolate,
5640 Handle<Object> object,
5641 Representation representation) {
5642 Heap* heap = isolate->heap();
5643 CALL_HEAP_FUNCTION(isolate,
5644 object->AllocateNewStorageFor(heap, representation),
5645 Object);
5646 }
5647
5648
5649 Handle<JSObject> JSObject::Copy(Handle<JSObject> object) { 5568 Handle<JSObject> JSObject::Copy(Handle<JSObject> object) {
5650 Isolate* isolate = object->GetIsolate(); 5569 Isolate* isolate = object->GetIsolate();
5651 CALL_HEAP_FUNCTION(isolate, 5570 CALL_HEAP_FUNCTION(isolate,
5652 isolate->heap()->CopyJSObject(*object), JSObject); 5571 isolate->heap()->CopyJSObject(*object), JSObject);
5653 } 5572 }
5654 5573
5655 5574
5656 Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object) { 5575 Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object) {
5657 Isolate* isolate = object->GetIsolate(); 5576 Isolate* isolate = object->GetIsolate();
5658 StackLimitCheck check(isolate); 5577 StackLimitCheck check(isolate);
5659 if (check.HasOverflowed()) { 5578 if (check.HasOverflowed()) {
5660 isolate->StackOverflow(); 5579 isolate->StackOverflow();
5661 return Handle<JSObject>::null(); 5580 return Handle<JSObject>::null();
5662 } 5581 }
5663 5582
5664 if (object->map()->is_deprecated()) { 5583 if (object->map()->is_deprecated()) {
5665 MigrateInstance(object); 5584 MigrateInstance(object);
5666 } 5585 }
5667 5586
5668 Handle<JSObject> copy = Copy(object); 5587 Handle<JSObject> copy = Copy(object);
5669 5588
5589 HandleScope scope(isolate);
5590
5670 // Deep copy local properties. 5591 // Deep copy local properties.
5671 if (copy->HasFastProperties()) { 5592 if (copy->HasFastProperties()) {
5672 Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors()); 5593 Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors());
5673 int limit = copy->map()->NumberOfOwnDescriptors(); 5594 int limit = copy->map()->NumberOfOwnDescriptors();
5674 for (int i = 0; i < limit; i++) { 5595 for (int i = 0; i < limit; i++) {
5675 PropertyDetails details = descriptors->GetDetails(i); 5596 PropertyDetails details = descriptors->GetDetails(i);
5676 if (details.type() != FIELD) continue; 5597 if (details.type() != FIELD) continue;
5677 int index = descriptors->GetFieldIndex(i); 5598 int index = descriptors->GetFieldIndex(i);
5678 Handle<Object> value(object->RawFastPropertyAt(index), isolate); 5599 Handle<Object> value(object->RawFastPropertyAt(index), isolate);
5679 if (value->IsJSObject()) { 5600 if (value->IsJSObject()) {
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after
6187 if (!object->CanSetCallback(*name)) return; 6108 if (!object->CanSetCallback(*name)) return;
6188 6109
6189 uint32_t index = 0; 6110 uint32_t index = 0;
6190 bool is_element = name->AsArrayIndex(&index); 6111 bool is_element = name->AsArrayIndex(&index);
6191 6112
6192 Handle<Object> old_value = isolate->factory()->the_hole_value(); 6113 Handle<Object> old_value = isolate->factory()->the_hole_value();
6193 bool is_observed = FLAG_harmony_observation && object->map()->is_observed(); 6114 bool is_observed = FLAG_harmony_observation && object->map()->is_observed();
6194 bool preexists = false; 6115 bool preexists = false;
6195 if (is_observed) { 6116 if (is_observed) {
6196 if (is_element) { 6117 if (is_element) {
6197 preexists = object->HasLocalElement(index); 6118 preexists = HasLocalElement(object, index);
6198 if (preexists && object->GetLocalElementAccessorPair(index) == NULL) { 6119 if (preexists && object->GetLocalElementAccessorPair(index) == NULL) {
6199 old_value = Object::GetElement(isolate, object, index); 6120 old_value = Object::GetElement(isolate, object, index);
6200 } 6121 }
6201 } else { 6122 } else {
6202 LookupResult lookup(isolate); 6123 LookupResult lookup(isolate);
6203 object->LocalLookup(*name, &lookup, true); 6124 object->LocalLookup(*name, &lookup, true);
6204 preexists = lookup.IsProperty(); 6125 preexists = lookup.IsProperty();
6205 if (preexists && lookup.IsDataProperty()) { 6126 if (preexists && lookup.IsDataProperty()) {
6206 old_value = Object::GetProperty(object, name); 6127 old_value = Object::GetProperty(object, name);
6207 } 6128 }
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after
6657 result->InitializeDescriptors(new_descriptors); 6578 result->InitializeDescriptors(new_descriptors);
6658 ASSERT(result->NumberOfOwnDescriptors() == NumberOfOwnDescriptors() + 1); 6579 ASSERT(result->NumberOfOwnDescriptors() == NumberOfOwnDescriptors() + 1);
6659 6580
6660 set_transitions(transitions); 6581 set_transitions(transitions);
6661 set_owns_descriptors(false); 6582 set_owns_descriptors(false);
6662 6583
6663 return result; 6584 return result;
6664 } 6585 }
6665 6586
6666 6587
6588 Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map,
6589 Handle<DescriptorArray> descriptors,
6590 TransitionFlag flag,
6591 Handle<Name> name) {
6592 CALL_HEAP_FUNCTION(map->GetIsolate(),
6593 map->CopyReplaceDescriptors(*descriptors, flag, *name),
6594 Map);
6595 }
6596
6597
6667 MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors, 6598 MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors,
6668 TransitionFlag flag, 6599 TransitionFlag flag,
6669 Name* name, 6600 Name* name,
6670 SimpleTransitionFlag simple_flag) { 6601 SimpleTransitionFlag simple_flag) {
6671 ASSERT(descriptors->IsSortedNoDuplicates()); 6602 ASSERT(descriptors->IsSortedNoDuplicates());
6672 6603
6673 Map* result; 6604 Map* result;
6674 MaybeObject* maybe_result = CopyDropDescriptors(); 6605 MaybeObject* maybe_result = CopyDropDescriptors();
6675 if (!maybe_result->To(&result)) return maybe_result; 6606 if (!maybe_result->To(&result)) return maybe_result;
6676 6607
6677 result->InitializeDescriptors(descriptors); 6608 result->InitializeDescriptors(descriptors);
6678 6609
6679 if (flag == INSERT_TRANSITION && CanHaveMoreTransitions()) { 6610 if (flag == INSERT_TRANSITION && CanHaveMoreTransitions()) {
6680 TransitionArray* transitions; 6611 TransitionArray* transitions;
6681 MaybeObject* maybe_transitions = AddTransition(name, result, simple_flag); 6612 MaybeObject* maybe_transitions = AddTransition(name, result, simple_flag);
6682 if (!maybe_transitions->To(&transitions)) return maybe_transitions; 6613 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
6683 set_transitions(transitions); 6614 set_transitions(transitions);
6684 result->SetBackPointer(this); 6615 result->SetBackPointer(this);
6685 } else { 6616 } else {
6686 descriptors->InitializeRepresentations(Representation::Tagged()); 6617 descriptors->InitializeRepresentations(Representation::Tagged());
6687 } 6618 }
6688 6619
6689 return result; 6620 return result;
6690 } 6621 }
6691 6622
6692 6623
6624 Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map,
6625 int new_descriptor,
6626 Handle<DescriptorArray> descriptors) {
6627 CALL_HEAP_FUNCTION(map->GetIsolate(),
6628 map->CopyInstallDescriptors(new_descriptor, *descriptors),
6629 Map);
6630 }
6631
6632
6693 // Since this method is used to rewrite an existing transition tree, it can 6633 // Since this method is used to rewrite an existing transition tree, it can
6694 // always insert transitions without checking. 6634 // always insert transitions without checking.
6695 MaybeObject* Map::CopyInstallDescriptors(int new_descriptor, 6635 MaybeObject* Map::CopyInstallDescriptors(int new_descriptor,
6696 DescriptorArray* descriptors) { 6636 DescriptorArray* descriptors) {
6697 ASSERT(descriptors->IsSortedNoDuplicates()); 6637 ASSERT(descriptors->IsSortedNoDuplicates());
6698 6638
6699 Map* result; 6639 Map* result;
6700 MaybeObject* maybe_result = CopyDropDescriptors(); 6640 MaybeObject* maybe_result = CopyDropDescriptors();
6701 if (!maybe_result->To(&result)) return maybe_result; 6641 if (!maybe_result->To(&result)) return maybe_result;
6702 6642
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
6901 6841
6902 // We replace the key if it is already present. 6842 // We replace the key if it is already present.
6903 int index = old_descriptors->SearchWithCache(descriptor->GetKey(), this); 6843 int index = old_descriptors->SearchWithCache(descriptor->GetKey(), this);
6904 if (index != DescriptorArray::kNotFound) { 6844 if (index != DescriptorArray::kNotFound) {
6905 return CopyReplaceDescriptor(old_descriptors, descriptor, index, flag); 6845 return CopyReplaceDescriptor(old_descriptors, descriptor, index, flag);
6906 } 6846 }
6907 return CopyAddDescriptor(descriptor, flag); 6847 return CopyAddDescriptor(descriptor, flag);
6908 } 6848 }
6909 6849
6910 6850
6851 Handle<DescriptorArray> DescriptorArray::CopyUpToAddAttributes(
6852 Handle<DescriptorArray> desc,
6853 int enumeration_index,
6854 PropertyAttributes attributes) {
6855 CALL_HEAP_FUNCTION(desc->GetIsolate(),
6856 desc->CopyUpToAddAttributes(enumeration_index, attributes),
6857 DescriptorArray);
6858 }
6859
6860
6911 MaybeObject* DescriptorArray::CopyUpToAddAttributes( 6861 MaybeObject* DescriptorArray::CopyUpToAddAttributes(
6912 int enumeration_index, PropertyAttributes attributes) { 6862 int enumeration_index, PropertyAttributes attributes) {
6913 if (enumeration_index == 0) return GetHeap()->empty_descriptor_array(); 6863 if (enumeration_index == 0) return GetHeap()->empty_descriptor_array();
6914 6864
6915 int size = enumeration_index; 6865 int size = enumeration_index;
6916 6866
6917 DescriptorArray* descriptors; 6867 DescriptorArray* descriptors;
6918 MaybeObject* maybe_descriptors = Allocate(GetIsolate(), size); 6868 MaybeObject* maybe_descriptors = Allocate(GetIsolate(), size);
6919 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors; 6869 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors;
6920 DescriptorArray::WhitenessWitness witness(descriptors); 6870 DescriptorArray::WhitenessWitness witness(descriptors);
(...skipping 874 matching lines...) Expand 10 before | Expand all | Expand 10 after
7795 DescriptorArray* src, 7745 DescriptorArray* src,
7796 int src_index, 7746 int src_index,
7797 const WhitenessWitness& witness) { 7747 const WhitenessWitness& witness) {
7798 Object* value = src->GetValue(src_index); 7748 Object* value = src->GetValue(src_index);
7799 PropertyDetails details = src->GetDetails(src_index); 7749 PropertyDetails details = src->GetDetails(src_index);
7800 Descriptor desc(src->GetKey(src_index), value, details); 7750 Descriptor desc(src->GetKey(src_index), value, details);
7801 Set(dst_index, &desc, witness); 7751 Set(dst_index, &desc, witness);
7802 } 7752 }
7803 7753
7804 7754
7755 Handle<DescriptorArray> DescriptorArray::Merge(Handle<DescriptorArray> desc,
7756 int verbatim,
7757 int valid,
7758 int new_size,
7759 int modify_index,
7760 StoreMode store_mode,
7761 Handle<DescriptorArray> other) {
7762 CALL_HEAP_FUNCTION(desc->GetIsolate(),
7763 desc->Merge(verbatim, valid, new_size, modify_index,
7764 store_mode, *other),
7765 DescriptorArray);
7766 }
7767
7768
7805 // Generalize the |other| descriptor array by merging it into the (at least 7769 // Generalize the |other| descriptor array by merging it into the (at least
7806 // partly) updated |this| descriptor array. 7770 // partly) updated |this| descriptor array.
7807 // The method merges two descriptor array in three parts. Both descriptor arrays 7771 // The method merges two descriptor array in three parts. Both descriptor arrays
7808 // are identical up to |verbatim|. They also overlap in keys up to |valid|. 7772 // are identical up to |verbatim|. They also overlap in keys up to |valid|.
7809 // Between |verbatim| and |valid|, the resulting descriptor type as well as the 7773 // Between |verbatim| and |valid|, the resulting descriptor type as well as the
7810 // representation are generalized from both |this| and |other|. Beyond |valid|, 7774 // representation are generalized from both |this| and |other|. Beyond |valid|,
7811 // the descriptors are copied verbatim from |other| up to |new_size|. 7775 // the descriptors are copied verbatim from |other| up to |new_size|.
7812 // In case of incompatible types, the type and representation of |other| is 7776 // In case of incompatible types, the type and representation of |other| is
7813 // used. 7777 // used.
7814 MaybeObject* DescriptorArray::Merge(int verbatim, 7778 MaybeObject* DescriptorArray::Merge(int verbatim,
(...skipping 1206 matching lines...) Expand 10 before | Expand all | Expand 10 after
9021 object->Size(); 8985 object->Size();
9022 if ((ptr_end + AllocationMemento::kSize) <= 8986 if ((ptr_end + AllocationMemento::kSize) <=
9023 object->GetHeap()->NewSpaceTop()) { 8987 object->GetHeap()->NewSpaceTop()) {
9024 // There is room in newspace for allocation info. Do we have some? 8988 // There is room in newspace for allocation info. Do we have some?
9025 Map** possible_allocation_memento_map = 8989 Map** possible_allocation_memento_map =
9026 reinterpret_cast<Map**>(ptr_end); 8990 reinterpret_cast<Map**>(ptr_end);
9027 if (*possible_allocation_memento_map == 8991 if (*possible_allocation_memento_map ==
9028 object->GetHeap()->allocation_memento_map()) { 8992 object->GetHeap()->allocation_memento_map()) {
9029 AllocationMemento* memento = AllocationMemento::cast( 8993 AllocationMemento* memento = AllocationMemento::cast(
9030 reinterpret_cast<Object*>(ptr_end + kHeapObjectTag)); 8994 reinterpret_cast<Object*>(ptr_end + kHeapObjectTag));
9031 8995 return memento;
9032 // TODO(mvstanton): because of chromium bug 284577, put extra care
9033 // into validating that the memento points to a valid AllocationSite.
9034 // This check is expensive so remove it asap. Also, this check
9035 // HIDES bug 284577, so it must be disabled to debug/diagnose.
9036 Object* site = memento->allocation_site();
9037 Heap* heap = object->GetHeap();
9038 if (heap->InOldPointerSpace(site) &&
9039 site->IsHeapObject() &&
9040 HeapObject::cast(site)->map() == heap->allocation_site_map()) {
9041 return memento;
9042 }
9043 } 8996 }
9044 } 8997 }
9045 } 8998 }
9046 return NULL; 8999 return NULL;
9047 } 9000 }
9048 9001
9049 9002
9050 uint32_t StringHasher::MakeArrayIndexHash(uint32_t value, int length) { 9003 uint32_t StringHasher::MakeArrayIndexHash(uint32_t value, int length) {
9051 // For array indexes mix the length into the hash as an array index could 9004 // For array indexes mix the length into the hash as an array index could
9052 // be zero. 9005 // be zero.
(...skipping 1364 matching lines...) Expand 10 before | Expand all | Expand 10 after
10417 cell->set_value(TypeFeedbackCells::RawUninitializedSentinel(heap)); 10370 cell->set_value(TypeFeedbackCells::RawUninitializedSentinel(heap));
10418 } 10371 }
10419 } 10372 }
10420 } 10373 }
10421 } 10374 }
10422 10375
10423 10376
10424 BailoutId Code::TranslatePcOffsetToAstId(uint32_t pc_offset) { 10377 BailoutId Code::TranslatePcOffsetToAstId(uint32_t pc_offset) {
10425 DisallowHeapAllocation no_gc; 10378 DisallowHeapAllocation no_gc;
10426 ASSERT(kind() == FUNCTION); 10379 ASSERT(kind() == FUNCTION);
10427 for (FullCodeGenerator::BackEdgeTableIterator it(this, &no_gc); 10380 BackEdgeTable back_edges(this, &no_gc);
10428 !it.Done(); 10381 for (uint32_t i = 0; i < back_edges.length(); i++) {
10429 it.Next()) { 10382 if (back_edges.pc_offset(i) == pc_offset) return back_edges.ast_id(i);
10430 if (it.pc_offset() == pc_offset) return it.ast_id();
10431 } 10383 }
10432 return BailoutId::None(); 10384 return BailoutId::None();
10433 } 10385 }
10434 10386
10435 10387
10436 bool Code::allowed_in_shared_map_code_cache() { 10388 bool Code::allowed_in_shared_map_code_cache() {
10437 return is_keyed_load_stub() || is_keyed_store_stub() || 10389 return is_keyed_load_stub() || is_keyed_store_stub() ||
10438 (is_compare_ic_stub() && 10390 (is_compare_ic_stub() &&
10439 ICCompareStub::CompareState(stub_info()) == CompareIC::KNOWN_OBJECT); 10391 ICCompareStub::CompareState(stub_info()) == CompareIC::KNOWN_OBJECT);
10440 } 10392 }
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
10888 } 10840 }
10889 PrintF(out, "\n"); 10841 PrintF(out, "\n");
10890 } 10842 }
10891 PrintF(out, "\n"); 10843 PrintF(out, "\n");
10892 } else if (kind() == FUNCTION) { 10844 } else if (kind() == FUNCTION) {
10893 unsigned offset = back_edge_table_offset(); 10845 unsigned offset = back_edge_table_offset();
10894 // If there is no back edge table, the "table start" will be at or after 10846 // If there is no back edge table, the "table start" will be at or after
10895 // (due to alignment) the end of the instruction stream. 10847 // (due to alignment) the end of the instruction stream.
10896 if (static_cast<int>(offset) < instruction_size()) { 10848 if (static_cast<int>(offset) < instruction_size()) {
10897 DisallowHeapAllocation no_gc; 10849 DisallowHeapAllocation no_gc;
10898 FullCodeGenerator::BackEdgeTableIterator back_edges(this, &no_gc); 10850 BackEdgeTable back_edges(this, &no_gc);
10899 10851
10900 PrintF(out, "Back edges (size = %u)\n", back_edges.table_length()); 10852 PrintF(out, "Back edges (size = %u)\n", back_edges.length());
10901 PrintF(out, "ast_id pc_offset loop_depth\n"); 10853 PrintF(out, "ast_id pc_offset loop_depth\n");
10902 10854
10903 for ( ; !back_edges.Done(); back_edges.Next()) { 10855 for (uint32_t i = 0; i < back_edges.length(); i++) {
10904 PrintF(out, "%6d %9u %10u\n", back_edges.ast_id().ToInt(), 10856 PrintF(out, "%6d %9u %10u\n", back_edges.ast_id(i).ToInt(),
10905 back_edges.pc_offset(), 10857 back_edges.pc_offset(i),
10906 back_edges.loop_depth()); 10858 back_edges.loop_depth(i));
10907 } 10859 }
10908 10860
10909 PrintF(out, "\n"); 10861 PrintF(out, "\n");
10910 } 10862 }
10911 #ifdef OBJECT_PRINT 10863 #ifdef OBJECT_PRINT
10912 if (!type_feedback_info()->IsUndefined()) { 10864 if (!type_feedback_info()->IsUndefined()) {
10913 TypeFeedbackInfo::cast(type_feedback_info())->TypeFeedbackInfoPrint(out); 10865 TypeFeedbackInfo::cast(type_feedback_info())->TypeFeedbackInfoPrint(out);
10914 PrintF(out, "\n"); 10866 PrintF(out, "\n");
10915 } 10867 }
10916 #endif 10868 #endif
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
10967 10919
10968 if (elements_kind != NON_STRICT_ARGUMENTS_ELEMENTS) { 10920 if (elements_kind != NON_STRICT_ARGUMENTS_ELEMENTS) {
10969 Map* new_map = map(); 10921 Map* new_map = map();
10970 if (new_elements_kind != elements_kind) { 10922 if (new_elements_kind != elements_kind) {
10971 MaybeObject* maybe = 10923 MaybeObject* maybe =
10972 GetElementsTransitionMap(GetIsolate(), new_elements_kind); 10924 GetElementsTransitionMap(GetIsolate(), new_elements_kind);
10973 if (!maybe->To(&new_map)) return maybe; 10925 if (!maybe->To(&new_map)) return maybe;
10974 } 10926 }
10975 ValidateElements(); 10927 ValidateElements();
10976 set_map_and_elements(new_map, new_elements); 10928 set_map_and_elements(new_map, new_elements);
10929
10930 // Transition through the allocation site as well if present.
10931 maybe_obj = UpdateAllocationSite(new_elements_kind);
10932 if (maybe_obj->IsFailure()) return maybe_obj;
10977 } else { 10933 } else {
10978 FixedArray* parameter_map = FixedArray::cast(old_elements); 10934 FixedArray* parameter_map = FixedArray::cast(old_elements);
10979 parameter_map->set(1, new_elements); 10935 parameter_map->set(1, new_elements);
10980 } 10936 }
10981 10937
10982 if (FLAG_trace_elements_transitions) { 10938 if (FLAG_trace_elements_transitions) {
10983 PrintElementsTransition(stdout, elements_kind, old_elements, 10939 PrintElementsTransition(stdout, elements_kind, old_elements,
10984 GetElementsKind(), new_elements); 10940 GetElementsKind(), new_elements);
10985 } 10941 }
10986 10942
(...skipping 731 matching lines...) Expand 10 before | Expand all | Expand 10 after
11718 return GetDeclaredAccessorProperty(receiver, 11674 return GetDeclaredAccessorProperty(receiver,
11719 DeclaredAccessorInfo::cast(structure), 11675 DeclaredAccessorInfo::cast(structure),
11720 isolate); 11676 isolate);
11721 } 11677 }
11722 11678
11723 UNREACHABLE(); 11679 UNREACHABLE();
11724 return NULL; 11680 return NULL;
11725 } 11681 }
11726 11682
11727 11683
11728 MaybeObject* JSObject::SetElementWithCallback(Object* structure, 11684 Handle<Object> JSObject::SetElementWithCallback(Handle<JSObject> object,
11729 uint32_t index, 11685 Handle<Object> structure,
11730 Object* value, 11686 uint32_t index,
11731 JSObject* holder, 11687 Handle<Object> value,
11732 StrictModeFlag strict_mode) { 11688 Handle<JSObject> holder,
11733 Isolate* isolate = GetIsolate(); 11689 StrictModeFlag strict_mode) {
11734 HandleScope scope(isolate); 11690 Isolate* isolate = object->GetIsolate();
11735 11691
11736 // We should never get here to initialize a const with the hole 11692 // We should never get here to initialize a const with the hole
11737 // value since a const declaration would conflict with the setter. 11693 // value since a const declaration would conflict with the setter.
11738 ASSERT(!value->IsTheHole()); 11694 ASSERT(!value->IsTheHole());
11739 Handle<Object> value_handle(value, isolate);
11740 11695
11741 // To accommodate both the old and the new api we switch on the 11696 // To accommodate both the old and the new api we switch on the
11742 // data structure used to store the callbacks. Eventually foreign 11697 // data structure used to store the callbacks. Eventually foreign
11743 // callbacks should be phased out. 11698 // callbacks should be phased out.
11744 ASSERT(!structure->IsForeign()); 11699 ASSERT(!structure->IsForeign());
11745 11700
11746 if (structure->IsExecutableAccessorInfo()) { 11701 if (structure->IsExecutableAccessorInfo()) {
11747 // api style callbacks 11702 // api style callbacks
11748 Handle<JSObject> self(this); 11703 Handle<ExecutableAccessorInfo> data =
11749 Handle<JSObject> holder_handle(JSObject::cast(holder)); 11704 Handle<ExecutableAccessorInfo>::cast(structure);
11750 Handle<ExecutableAccessorInfo> data(
11751 ExecutableAccessorInfo::cast(structure));
11752 Object* call_obj = data->setter(); 11705 Object* call_obj = data->setter();
11753 v8::AccessorSetterCallback call_fun = 11706 v8::AccessorSetterCallback call_fun =
11754 v8::ToCData<v8::AccessorSetterCallback>(call_obj); 11707 v8::ToCData<v8::AccessorSetterCallback>(call_obj);
11755 if (call_fun == NULL) return value; 11708 if (call_fun == NULL) return value;
11756 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); 11709 Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
11757 Handle<String> key(isolate->factory()->NumberToString(number)); 11710 Handle<String> key(isolate->factory()->NumberToString(number));
11758 LOG(isolate, ApiNamedPropertyAccess("store", *self, *key)); 11711 LOG(isolate, ApiNamedPropertyAccess("store", *object, *key));
11759 PropertyCallbackArguments 11712 PropertyCallbackArguments
11760 args(isolate, data->data(), *self, *holder_handle); 11713 args(isolate, data->data(), *object, *holder);
11761 args.Call(call_fun, 11714 args.Call(call_fun,
11762 v8::Utils::ToLocal(key), 11715 v8::Utils::ToLocal(key),
11763 v8::Utils::ToLocal(value_handle)); 11716 v8::Utils::ToLocal(value));
11764 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 11717 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
11765 return *value_handle; 11718 return value;
11766 } 11719 }
11767 11720
11768 if (structure->IsAccessorPair()) { 11721 if (structure->IsAccessorPair()) {
11769 Handle<Object> setter(AccessorPair::cast(structure)->setter(), isolate); 11722 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate);
11770 if (setter->IsSpecFunction()) { 11723 if (setter->IsSpecFunction()) {
11771 // TODO(rossberg): nicer would be to cast to some JSCallable here... 11724 // TODO(rossberg): nicer would be to cast to some JSCallable here...
11772 return SetPropertyWithDefinedSetter(JSReceiver::cast(*setter), value); 11725 return SetPropertyWithDefinedSetter(
11726 object, Handle<JSReceiver>::cast(setter), value);
11773 } else { 11727 } else {
11774 if (strict_mode == kNonStrictMode) { 11728 if (strict_mode == kNonStrictMode) {
11775 return value; 11729 return value;
11776 } 11730 }
11777 Handle<Object> holder_handle(holder, isolate);
11778 Handle<Object> key(isolate->factory()->NewNumberFromUint(index)); 11731 Handle<Object> key(isolate->factory()->NewNumberFromUint(index));
11779 Handle<Object> args[2] = { key, holder_handle }; 11732 Handle<Object> args[2] = { key, holder };
11780 return isolate->Throw( 11733 Handle<Object> error = isolate->factory()->NewTypeError(
11781 *isolate->factory()->NewTypeError("no_setter_in_callback", 11734 "no_setter_in_callback", HandleVector(args, 2));
11782 HandleVector(args, 2))); 11735 isolate->Throw(*error);
11736 return Handle<Object>();
11783 } 11737 }
11784 } 11738 }
11785 11739
11786 // TODO(dcarney): Handle correctly. 11740 // TODO(dcarney): Handle correctly.
11787 if (structure->IsDeclaredAccessorInfo()) return value; 11741 if (structure->IsDeclaredAccessorInfo()) return value;
11788 11742
11789 UNREACHABLE(); 11743 UNREACHABLE();
11790 return NULL; 11744 return Handle<Object>();
11791 } 11745 }
11792 11746
11793 11747
11794 bool JSObject::HasFastArgumentsElements() { 11748 bool JSObject::HasFastArgumentsElements() {
11795 Heap* heap = GetHeap(); 11749 Heap* heap = GetHeap();
11796 if (!elements()->IsFixedArray()) return false; 11750 if (!elements()->IsFixedArray()) return false;
11797 FixedArray* elements = FixedArray::cast(this->elements()); 11751 FixedArray* elements = FixedArray::cast(this->elements());
11798 if (elements->map() != heap->non_strict_arguments_elements_map()) { 11752 if (elements->map() != heap->non_strict_arguments_elements_map()) {
11799 return false; 11753 return false;
11800 } 11754 }
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
11977 // Insert element in the dictionary. 11931 // Insert element in the dictionary.
11978 Handle<FixedArray> elements(FixedArray::cast(this->elements())); 11932 Handle<FixedArray> elements(FixedArray::cast(this->elements()));
11979 bool is_arguments = 11933 bool is_arguments =
11980 (elements->map() == heap->non_strict_arguments_elements_map()); 11934 (elements->map() == heap->non_strict_arguments_elements_map());
11981 Handle<SeededNumberDictionary> dictionary(is_arguments 11935 Handle<SeededNumberDictionary> dictionary(is_arguments
11982 ? SeededNumberDictionary::cast(elements->get(1)) 11936 ? SeededNumberDictionary::cast(elements->get(1))
11983 : SeededNumberDictionary::cast(*elements)); 11937 : SeededNumberDictionary::cast(*elements));
11984 11938
11985 int entry = dictionary->FindEntry(index); 11939 int entry = dictionary->FindEntry(index);
11986 if (entry != SeededNumberDictionary::kNotFound) { 11940 if (entry != SeededNumberDictionary::kNotFound) {
11987 Object* element = dictionary->ValueAt(entry); 11941 Handle<Object> element(dictionary->ValueAt(entry), isolate);
11988 PropertyDetails details = dictionary->DetailsAt(entry); 11942 PropertyDetails details = dictionary->DetailsAt(entry);
11989 if (details.type() == CALLBACKS && set_mode == SET_PROPERTY) { 11943 if (details.type() == CALLBACKS && set_mode == SET_PROPERTY) {
11990 return SetElementWithCallback(element, index, *value, this, strict_mode); 11944 Handle<Object> result = SetElementWithCallback(self, element, index,
11945 value, self, strict_mode);
11946 RETURN_IF_EMPTY_HANDLE(isolate, result);
11947 return *result;
11991 } else { 11948 } else {
11992 dictionary->UpdateMaxNumberKey(index); 11949 dictionary->UpdateMaxNumberKey(index);
11993 // If a value has not been initialized we allow writing to it even if it 11950 // If a value has not been initialized we allow writing to it even if it
11994 // is read-only (a declared const that has not been initialized). If a 11951 // is read-only (a declared const that has not been initialized). If a
11995 // value is being defined we skip attribute checks completely. 11952 // value is being defined we skip attribute checks completely.
11996 if (set_mode == DEFINE_PROPERTY) { 11953 if (set_mode == DEFINE_PROPERTY) {
11997 details = PropertyDetails( 11954 details = PropertyDetails(
11998 attributes, NORMAL, details.dictionary_index()); 11955 attributes, NORMAL, details.dictionary_index());
11999 dictionary->DetailsAtPut(entry, details); 11956 dictionary->DetailsAtPut(entry, details);
12000 } else if (details.IsReadOnly() && !element->IsTheHole()) { 11957 } else if (details.IsReadOnly() && !element->IsTheHole()) {
12001 if (strict_mode == kNonStrictMode) { 11958 if (strict_mode == kNonStrictMode) {
12002 return isolate->heap()->undefined_value(); 11959 return isolate->heap()->undefined_value();
12003 } else { 11960 } else {
12004 Handle<Object> holder(this, isolate); 11961 Handle<Object> holder(this, isolate);
12005 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); 11962 Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
12006 Handle<Object> args[2] = { number, holder }; 11963 Handle<Object> args[2] = { number, holder };
12007 Handle<Object> error = 11964 Handle<Object> error =
12008 isolate->factory()->NewTypeError("strict_read_only_property", 11965 isolate->factory()->NewTypeError("strict_read_only_property",
12009 HandleVector(args, 2)); 11966 HandleVector(args, 2));
12010 return isolate->Throw(*error); 11967 return isolate->Throw(*error);
12011 } 11968 }
12012 } 11969 }
12013 // Elements of the arguments object in slow mode might be slow aliases. 11970 // Elements of the arguments object in slow mode might be slow aliases.
12014 if (is_arguments && element->IsAliasedArgumentsEntry()) { 11971 if (is_arguments && element->IsAliasedArgumentsEntry()) {
12015 AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(element); 11972 AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(*element);
12016 Context* context = Context::cast(elements->get(0)); 11973 Context* context = Context::cast(elements->get(0));
12017 int context_index = entry->aliased_context_slot(); 11974 int context_index = entry->aliased_context_slot();
12018 ASSERT(!context->get(context_index)->IsTheHole()); 11975 ASSERT(!context->get(context_index)->IsTheHole());
12019 context->set(context_index, *value); 11976 context->set(context_index, *value);
12020 // For elements that are still writable we keep slow aliasing. 11977 // For elements that are still writable we keep slow aliasing.
12021 if (!details.IsReadOnly()) value = handle(element, isolate); 11978 if (!details.IsReadOnly()) value = element;
12022 } 11979 }
12023 dictionary->ValueAtPut(entry, *value); 11980 dictionary->ValueAtPut(entry, *value);
12024 } 11981 }
12025 } else { 11982 } else {
12026 // Index not already used. Look for an accessor in the prototype chain. 11983 // Index not already used. Look for an accessor in the prototype chain.
12027 // Can cause GC! 11984 // Can cause GC!
12028 if (check_prototype) { 11985 if (check_prototype) {
12029 bool found; 11986 bool found;
12030 MaybeObject* result = SetElementWithCallbackSetterInPrototypes( 11987 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(
12031 index, *value, &found, strict_mode); 11988 index, *value, &found, strict_mode);
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after
12501 12458
12502 // Walk through to the Allocation Site 12459 // Walk through to the Allocation Site
12503 AllocationSite* site = memento->GetAllocationSite(); 12460 AllocationSite* site = memento->GetAllocationSite();
12504 if (site->IsLiteralSite()) { 12461 if (site->IsLiteralSite()) {
12505 JSArray* transition_info = JSArray::cast(site->transition_info()); 12462 JSArray* transition_info = JSArray::cast(site->transition_info());
12506 ElementsKind kind = transition_info->GetElementsKind(); 12463 ElementsKind kind = transition_info->GetElementsKind();
12507 // if kind is holey ensure that to_kind is as well. 12464 // if kind is holey ensure that to_kind is as well.
12508 if (IsHoleyElementsKind(kind)) { 12465 if (IsHoleyElementsKind(kind)) {
12509 to_kind = GetHoleyElementsKind(to_kind); 12466 to_kind = GetHoleyElementsKind(to_kind);
12510 } 12467 }
12511 if (AllocationSite::GetMode(kind, to_kind) == TRACK_ALLOCATION_SITE) { 12468 if (IsMoreGeneralElementsKindTransition(kind, to_kind)) {
12512 // If the array is huge, it's not likely to be defined in a local 12469 // If the array is huge, it's not likely to be defined in a local
12513 // function, so we shouldn't make new instances of it very often. 12470 // function, so we shouldn't make new instances of it very often.
12514 uint32_t length = 0; 12471 uint32_t length = 0;
12515 CHECK(transition_info->length()->ToArrayIndex(&length)); 12472 CHECK(transition_info->length()->ToArrayIndex(&length));
12516 if (length <= AllocationSite::kMaximumArrayBytesToPretransition) { 12473 if (length <= AllocationSite::kMaximumArrayBytesToPretransition) {
12517 if (FLAG_trace_track_allocation_sites) { 12474 if (FLAG_trace_track_allocation_sites) {
12518 PrintF( 12475 PrintF(
12519 "AllocationSite: JSArray %p boilerplate updated %s->%s\n", 12476 "AllocationSite: JSArray %p boilerplate updated %s->%s\n",
12520 reinterpret_cast<void*>(this), 12477 reinterpret_cast<void*>(this),
12521 ElementsKindToString(kind), 12478 ElementsKindToString(kind),
12522 ElementsKindToString(to_kind)); 12479 ElementsKindToString(to_kind));
12523 } 12480 }
12524 return transition_info->TransitionElementsKind(to_kind); 12481 return transition_info->TransitionElementsKind(to_kind);
12525 } 12482 }
12526 } 12483 }
12527 } else { 12484 } else {
12528 ElementsKind kind = site->GetElementsKind(); 12485 ElementsKind kind = site->GetElementsKind();
12529 // if kind is holey ensure that to_kind is as well. 12486 // if kind is holey ensure that to_kind is as well.
12530 if (IsHoleyElementsKind(kind)) { 12487 if (IsHoleyElementsKind(kind)) {
12531 to_kind = GetHoleyElementsKind(to_kind); 12488 to_kind = GetHoleyElementsKind(to_kind);
12532 } 12489 }
12533 if (AllocationSite::GetMode(kind, to_kind) == TRACK_ALLOCATION_SITE) { 12490 if (IsMoreGeneralElementsKindTransition(kind, to_kind)) {
12534 if (FLAG_trace_track_allocation_sites) { 12491 if (FLAG_trace_track_allocation_sites) {
12535 PrintF("AllocationSite: JSArray %p site updated %s->%s\n", 12492 PrintF("AllocationSite: JSArray %p site updated %s->%s\n",
12536 reinterpret_cast<void*>(this), 12493 reinterpret_cast<void*>(this),
12537 ElementsKindToString(kind), 12494 ElementsKindToString(kind),
12538 ElementsKindToString(to_kind)); 12495 ElementsKindToString(to_kind));
12539 } 12496 }
12540 site->set_transition_info(Smi::FromInt(to_kind)); 12497 site->set_transition_info(Smi::FromInt(to_kind));
12541 } 12498 }
12542 } 12499 }
12543 return this; 12500 return this;
(...skipping 1973 matching lines...) Expand 10 before | Expand all | Expand 10 after
14517 } 14474 }
14518 14475
14519 14476
14520 PropertyCell* GlobalObject::GetPropertyCell(LookupResult* result) { 14477 PropertyCell* GlobalObject::GetPropertyCell(LookupResult* result) {
14521 ASSERT(!HasFastProperties()); 14478 ASSERT(!HasFastProperties());
14522 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); 14479 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry());
14523 return PropertyCell::cast(value); 14480 return PropertyCell::cast(value);
14524 } 14481 }
14525 14482
14526 14483
14527 // TODO(mstarzinger): Temporary wrapper until handlified.
14528 static Handle<NameDictionary> NameDictionaryAdd(Handle<NameDictionary> dict,
14529 Handle<Name> name,
14530 Handle<Object> value,
14531 PropertyDetails details) {
14532 CALL_HEAP_FUNCTION(dict->GetIsolate(),
14533 dict->Add(*name, *value, details),
14534 NameDictionary);
14535 }
14536
14537
14538 Handle<PropertyCell> GlobalObject::EnsurePropertyCell( 14484 Handle<PropertyCell> GlobalObject::EnsurePropertyCell(
14539 Handle<GlobalObject> global, 14485 Handle<GlobalObject> global,
14540 Handle<Name> name) { 14486 Handle<Name> name) {
14541 ASSERT(!global->HasFastProperties()); 14487 ASSERT(!global->HasFastProperties());
14542 int entry = global->property_dictionary()->FindEntry(*name); 14488 int entry = global->property_dictionary()->FindEntry(*name);
14543 if (entry == NameDictionary::kNotFound) { 14489 if (entry == NameDictionary::kNotFound) {
14544 Isolate* isolate = global->GetIsolate(); 14490 Isolate* isolate = global->GetIsolate();
14545 Handle<PropertyCell> cell = isolate->factory()->NewPropertyCell( 14491 Handle<PropertyCell> cell = isolate->factory()->NewPropertyCell(
14546 isolate->factory()->the_hole_value()); 14492 isolate->factory()->the_hole_value());
14547 PropertyDetails details(NONE, NORMAL, 0); 14493 PropertyDetails details(NONE, NORMAL, 0);
(...skipping 1558 matching lines...) Expand 10 before | Expand all | Expand 10 after
16106 isolate, DependentCode::kPropertyCellChangedGroup); 16052 isolate, DependentCode::kPropertyCellChangedGroup);
16107 16053
16108 if (old_type->Is(Type::None()) || old_type->Is(Type::Undefined())) { 16054 if (old_type->Is(Type::None()) || old_type->Is(Type::Undefined())) {
16109 return *new_type; 16055 return *new_type;
16110 } 16056 }
16111 16057
16112 return Type::Any(); 16058 return Type::Any();
16113 } 16059 }
16114 16060
16115 16061
16062 void PropertyCell::SetValueInferType(Handle<PropertyCell> cell,
16063 Handle<Object> value,
16064 WriteBarrierMode mode) {
16065 CALL_HEAP_FUNCTION_VOID(cell->GetIsolate(),
16066 cell->SetValueInferType(*value, mode));
16067 }
16068
16069
16116 MaybeObject* PropertyCell::SetValueInferType(Object* value, 16070 MaybeObject* PropertyCell::SetValueInferType(Object* value,
16117 WriteBarrierMode ignored) { 16071 WriteBarrierMode ignored) {
16118 set_value(value, ignored); 16072 set_value(value, ignored);
16119 if (!Type::Any()->Is(type())) { 16073 if (!Type::Any()->Is(type())) {
16120 IdempotentPointerToHandleCodeTrampoline trampoline(GetIsolate()); 16074 IdempotentPointerToHandleCodeTrampoline trampoline(GetIsolate());
16121 MaybeObject* maybe_type = trampoline.CallWithReturnValue( 16075 MaybeObject* maybe_type = trampoline.CallWithReturnValue(
16122 &PropertyCell::UpdateType, 16076 &PropertyCell::UpdateType,
16123 Handle<PropertyCell>(this), 16077 Handle<PropertyCell>(this),
16124 Handle<Object>(value, GetIsolate())); 16078 Handle<Object>(value, GetIsolate()));
16125 Type* new_type = NULL; 16079 Type* new_type = NULL;
(...skipping 28 matching lines...) Expand all
16154 #define ERROR_MESSAGES_TEXTS(C, T) T, 16108 #define ERROR_MESSAGES_TEXTS(C, T) T,
16155 static const char* error_messages_[] = { 16109 static const char* error_messages_[] = {
16156 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16110 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16157 }; 16111 };
16158 #undef ERROR_MESSAGES_TEXTS 16112 #undef ERROR_MESSAGES_TEXTS
16159 return error_messages_[reason]; 16113 return error_messages_[reason];
16160 } 16114 }
16161 16115
16162 16116
16163 } } // namespace v8::internal 16117 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698