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

Side by Side Diff: src/objects.cc

Issue 23601031: Handlify JSReceiver::SetProperty and friends. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments by Toon Verwaest. Created 7 years, 3 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(uint32_t index) {
466 String* name; 464 String* name;
467 MaybeObject* maybe = GetHeap()->Uint32ToString(index); 465 MaybeObject* maybe = GetHeap()->Uint32ToString(index);
468 if (!maybe->To<String>(&name)) return maybe; 466 if (!maybe->To<String>(&name)) return maybe;
469 return HasPropertyWithHandler(name); 467 return HasPropertyWithHandler(name);
470 } 468 }
471 469
(...skipping 1392 matching lines...) Expand 10 before | Expand all | Expand 10 after
1864 // If the constructor is not present, return "Object". 1862 // If the constructor is not present, return "Object".
1865 return GetHeap()->Object_string(); 1863 return GetHeap()->Object_string();
1866 } 1864 }
1867 1865
1868 1866
1869 String* JSReceiver::constructor_name() { 1867 String* JSReceiver::constructor_name() {
1870 return map()->constructor_name(); 1868 return map()->constructor_name();
1871 } 1869 }
1872 1870
1873 1871
1872 Handle<Object> JSObject::AddFastPropertyUsingMap(
1873 Handle<JSObject> object,
1874 Handle<Map> new_map,
1875 Handle<Name> name,
1876 Handle<Object> value,
1877 int field_index,
1878 Representation representation) {
1879 CALL_HEAP_FUNCTION(object->GetIsolate(),
1880 object->AddFastPropertyUsingMap(
1881 *new_map, *name, *value, field_index, representation),
1882 Object);
1883 }
1884
1885
1874 MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map, 1886 MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map,
1875 Name* name, 1887 Name* name,
1876 Object* value, 1888 Object* value,
1877 int field_index, 1889 int field_index,
1878 Representation representation) { 1890 Representation representation) {
1879 // This method is used to transition to a field. If we are transitioning to a 1891 // This method is used to transition to a field. If we are transitioning to a
1880 // double field, allocate new storage. 1892 // double field, allocate new storage.
1881 Object* storage; 1893 Object* storage;
1882 MaybeObject* maybe_storage = 1894 MaybeObject* maybe_storage =
1883 value->AllocateNewStorageFor(GetHeap(), representation); 1895 value->AllocateNewStorageFor(GetHeap(), representation);
1884 if (!maybe_storage->To(&storage)) return maybe_storage; 1896 if (!maybe_storage->To(&storage)) return maybe_storage;
1885 1897
1886 if (map()->unused_property_fields() == 0) { 1898 if (map()->unused_property_fields() == 0) {
1887 int new_unused = new_map->unused_property_fields(); 1899 int new_unused = new_map->unused_property_fields();
1888 FixedArray* values; 1900 FixedArray* values;
1889 MaybeObject* maybe_values = 1901 MaybeObject* maybe_values =
1890 properties()->CopySize(properties()->length() + new_unused + 1); 1902 properties()->CopySize(properties()->length() + new_unused + 1);
1891 if (!maybe_values->To(&values)) return maybe_values; 1903 if (!maybe_values->To(&values)) return maybe_values;
1892 1904
1893 set_properties(values); 1905 set_properties(values);
1894 } 1906 }
1895 1907
1896 set_map(new_map); 1908 set_map(new_map);
1897 1909
1898 FastPropertyAtPut(field_index, storage); 1910 FastPropertyAtPut(field_index, storage);
1899 return value; 1911 return value;
1900 } 1912 }
1901 1913
1902 1914
1903 MaybeObject* JSObject::AddFastProperty(Name* name, 1915 static MaybeObject* CopyAddFieldDescriptor(Map* map,
1904 Object* value, 1916 Name* name,
1905 PropertyAttributes attributes, 1917 int index,
1906 StoreFromKeyed store_mode, 1918 PropertyAttributes attributes,
1907 ValueType value_type, 1919 Representation representation,
1908 TransitionFlag flag) { 1920 TransitionFlag flag) {
1909 ASSERT(!IsJSGlobalProxy()); 1921 Map* new_map;
1922 FieldDescriptor new_field_desc(name, index, attributes, representation);
1923 MaybeObject* maybe_map = map->CopyAddDescriptor(&new_field_desc, flag);
1924 if (!maybe_map->To(&new_map)) return maybe_map;
1925 int unused_property_fields = map->unused_property_fields() - 1;
1926 if (unused_property_fields < 0) {
1927 unused_property_fields += JSObject::kFieldsAdded;
1928 }
1929 new_map->set_unused_property_fields(unused_property_fields);
1930 return new_map;
1931 }
1932
1933
1934 static Handle<Map> CopyAddFieldDescriptor(Handle<Map> map,
1935 Handle<Name> name,
1936 int index,
1937 PropertyAttributes attributes,
1938 Representation representation,
1939 TransitionFlag flag) {
1940 CALL_HEAP_FUNCTION(map->GetIsolate(),
1941 CopyAddFieldDescriptor(
1942 *map, *name, index, attributes, representation, flag),
1943 Map);
1944 }
1945
1946
1947 void JSObject::AddFastProperty(Handle<JSObject> object,
1948 Handle<Name> name,
1949 Handle<Object> value,
1950 PropertyAttributes attributes,
1951 StoreFromKeyed store_mode,
1952 ValueType value_type,
1953 TransitionFlag flag) {
1954 ASSERT(!object->IsJSGlobalProxy());
1910 ASSERT(DescriptorArray::kNotFound == 1955 ASSERT(DescriptorArray::kNotFound ==
1911 map()->instance_descriptors()->Search( 1956 object->map()->instance_descriptors()->Search(
1912 name, map()->NumberOfOwnDescriptors())); 1957 *name, object->map()->NumberOfOwnDescriptors()));
1913 1958
1914 // Normalize the object if the name is an actual name (not the 1959 // Normalize the object if the name is an actual name (not the
1915 // hidden strings) and is not a real identifier. 1960 // hidden strings) and is not a real identifier.
1916 // Normalize the object if it will have too many fast properties. 1961 // Normalize the object if it will have too many fast properties.
1917 Isolate* isolate = GetHeap()->isolate(); 1962 Isolate* isolate = object->GetIsolate();
1918 if (!name->IsCacheable(isolate) || TooManyFastProperties(store_mode)) { 1963 if (!name->IsCacheable(isolate) ||
1919 MaybeObject* maybe_failure = 1964 object->TooManyFastProperties(store_mode)) {
1920 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); 1965 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
1921 if (maybe_failure->IsFailure()) return maybe_failure; 1966 AddSlowProperty(object, name, value, attributes);
1922 return AddSlowProperty(name, value, attributes); 1967 return;
1923 } 1968 }
1924 1969
1925 // Compute the new index for new field. 1970 // Compute the new index for new field.
1926 int index = map()->NextFreePropertyIndex(); 1971 int index = object->map()->NextFreePropertyIndex();
1927 1972
1928 // Allocate new instance descriptors with (name, index) added 1973 // Allocate new instance descriptors with (name, index) added
1929 if (IsJSContextExtensionObject()) value_type = FORCE_TAGGED; 1974 if (object->IsJSContextExtensionObject()) value_type = FORCE_TAGGED;
1930 Representation representation = value->OptimalRepresentation(value_type); 1975 Representation representation = value->OptimalRepresentation(value_type);
1931 1976 Handle<Map> new_map = CopyAddFieldDescriptor(
1932 FieldDescriptor new_field(name, index, attributes, representation); 1977 handle(object->map()), name, index, attributes, representation, flag);
1933 1978
1934 Map* new_map; 1979 AddFastPropertyUsingMap(object, new_map, name, value, index, representation);
1935 MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&new_field, flag); 1980 }
1936 if (!maybe_new_map->To(&new_map)) return maybe_new_map; 1981
1937 1982
1938 int unused_property_fields = map()->unused_property_fields() - 1; 1983 static MaybeObject* CopyAddConstantDescriptor(Map* map,
1939 if (unused_property_fields < 0) { 1984 Name* name,
1940 unused_property_fields += kFieldsAdded; 1985 Object* value,
1941 } 1986 PropertyAttributes attributes,
1942 new_map->set_unused_property_fields(unused_property_fields); 1987 TransitionFlag flag) {
1943 1988 ConstantDescriptor new_constant_desc(name, value, attributes);
1944 return AddFastPropertyUsingMap(new_map, name, value, index, representation); 1989 return map->CopyAddDescriptor(&new_constant_desc, flag);
1945 } 1990 }
1946 1991
1947 1992
1948 MaybeObject* JSObject::AddConstantProperty( 1993 static Handle<Map> CopyAddConstantDescriptor(Handle<Map> map,
1949 Name* name, 1994 Handle<Name> name,
1950 Object* constant, 1995 Handle<Object> value,
1951 PropertyAttributes attributes, 1996 PropertyAttributes attributes,
1952 TransitionFlag initial_flag) { 1997 TransitionFlag flag) {
1953 // Allocate new instance descriptors with (name, constant) added 1998 CALL_HEAP_FUNCTION(map->GetIsolate(),
1954 ConstantDescriptor d(name, constant, attributes); 1999 CopyAddConstantDescriptor(
1955 2000 *map, *name, *value, attributes, flag),
2001 Map);
2002 }
2003
2004
2005 void JSObject::AddConstantProperty(Handle<JSObject> object,
2006 Handle<Name> name,
2007 Handle<Object> constant,
2008 PropertyAttributes attributes,
2009 TransitionFlag initial_flag) {
1956 TransitionFlag flag = 2010 TransitionFlag flag =
1957 // Do not add transitions to global objects. 2011 // Do not add transitions to global objects.
1958 (IsGlobalObject() || 2012 (object->IsGlobalObject() ||
1959 // Don't add transitions to special properties with non-trivial 2013 // Don't add transitions to special properties with non-trivial
1960 // attributes. 2014 // attributes.
1961 attributes != NONE) 2015 attributes != NONE)
1962 ? OMIT_TRANSITION 2016 ? OMIT_TRANSITION
1963 : initial_flag; 2017 : initial_flag;
1964 2018
1965 Map* new_map; 2019 // Allocate new instance descriptors with (name, constant) added.
1966 MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&d, flag); 2020 Handle<Map> new_map = CopyAddConstantDescriptor(
1967 if (!maybe_new_map->To(&new_map)) return maybe_new_map; 2021 handle(object->map()), name, constant, attributes, flag);
1968 2022
1969 set_map(new_map); 2023 object->set_map(*new_map);
1970 return constant; 2024 }
1971 } 2025
1972 2026
1973 2027 // TODO(mstarzinger): Temporary wrapper until handlified.
1974 // Add property in slow mode 2028 static Handle<NameDictionary> NameDictionaryAdd(Handle<NameDictionary> dict,
1975 MaybeObject* JSObject::AddSlowProperty(Name* name, 2029 Handle<Name> name,
1976 Object* value, 2030 Handle<Object> value,
1977 PropertyAttributes attributes) { 2031 PropertyDetails details) {
1978 ASSERT(!HasFastProperties()); 2032 CALL_HEAP_FUNCTION(dict->GetIsolate(),
1979 NameDictionary* dict = property_dictionary(); 2033 dict->Add(*name, *value, details),
1980 Object* store_value = value; 2034 NameDictionary);
1981 if (IsGlobalObject()) { 2035 }
2036
2037
2038 void JSObject::AddSlowProperty(Handle<JSObject> object,
2039 Handle<Name> name,
2040 Handle<Object> value,
2041 PropertyAttributes attributes) {
2042 ASSERT(!object->HasFastProperties());
2043 Isolate* isolate = object->GetIsolate();
2044 Handle<NameDictionary> dict(object->property_dictionary());
2045 if (object->IsGlobalObject()) {
1982 // In case name is an orphaned property reuse the cell. 2046 // In case name is an orphaned property reuse the cell.
1983 int entry = dict->FindEntry(name); 2047 int entry = dict->FindEntry(*name);
1984 if (entry != NameDictionary::kNotFound) { 2048 if (entry != NameDictionary::kNotFound) {
1985 store_value = dict->ValueAt(entry); 2049 Handle<PropertyCell> cell(PropertyCell::cast(dict->ValueAt(entry)));
1986 MaybeObject* maybe_type = 2050 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 2051 // Assign an enumeration index to the property and update
1990 // SetNextEnumerationIndex. 2052 // SetNextEnumerationIndex.
1991 int index = dict->NextEnumerationIndex(); 2053 int index = dict->NextEnumerationIndex();
1992 PropertyDetails details = PropertyDetails(attributes, NORMAL, index); 2054 PropertyDetails details = PropertyDetails(attributes, NORMAL, index);
1993 dict->SetNextEnumerationIndex(index + 1); 2055 dict->SetNextEnumerationIndex(index + 1);
1994 dict->SetEntry(entry, name, store_value, details); 2056 dict->SetEntry(entry, *name, *cell, details);
1995 return value; 2057 return;
1996 } 2058 }
1997 Heap* heap = GetHeap(); 2059 Handle<PropertyCell> cell = isolate->factory()->NewPropertyCell(value);
1998 { MaybeObject* maybe_store_value = 2060 PropertyCell::SetValueInferType(cell, value);
1999 heap->AllocatePropertyCell(value); 2061 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 } 2062 }
2006 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0); 2063 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0);
2007 Object* result; 2064 Handle<NameDictionary> result = NameDictionaryAdd(dict, name, value, details);
2008 { MaybeObject* maybe_result = dict->Add(name, store_value, details); 2065 if (*dict != *result) object->set_properties(*result);
2009 if (!maybe_result->ToObject(&result)) return maybe_result; 2066 }
2010 } 2067
2011 if (dict != result) set_properties(NameDictionary::cast(result)); 2068
2012 return value; 2069 Handle<Object> JSObject::AddProperty(Handle<JSObject> object,
2013 } 2070 Handle<Name> name,
2014 2071 Handle<Object> value,
2015 2072 PropertyAttributes attributes,
2016 MaybeObject* JSObject::AddProperty(Name* name, 2073 StrictModeFlag strict_mode,
2017 Object* value, 2074 JSReceiver::StoreFromKeyed store_mode,
2018 PropertyAttributes attributes, 2075 ExtensibilityCheck extensibility_check,
2019 StrictModeFlag strict_mode, 2076 ValueType value_type,
2020 JSReceiver::StoreFromKeyed store_mode, 2077 StoreMode mode,
2021 ExtensibilityCheck extensibility_check, 2078 TransitionFlag transition_flag) {
2022 ValueType value_type, 2079 ASSERT(!object->IsJSGlobalProxy());
2023 StoreMode mode, 2080 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 && 2081 if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK &&
2031 !map_of_this->is_extensible()) { 2082 !object->map()->is_extensible()) {
2032 if (strict_mode == kNonStrictMode) { 2083 if (strict_mode == kNonStrictMode) {
2033 return value; 2084 return value;
2034 } else { 2085 } else {
2035 Handle<Object> args[1] = {Handle<Name>(name)}; 2086 Handle<Object> args[1] = { name };
2036 return isolate->Throw( 2087 Handle<Object> error = isolate->factory()->NewTypeError(
2037 *isolate->factory()->NewTypeError("object_not_extensible", 2088 "object_not_extensible", HandleVector(args, ARRAY_SIZE(args)));
2038 HandleVector(args, 1))); 2089 isolate->Throw(*error);
2090 return Handle<Object>();
2039 } 2091 }
2040 } 2092 }
2041 2093
2042 if (HasFastProperties()) { 2094 if (object->HasFastProperties()) {
2043 // Ensure the descriptor array does not get too big. 2095 // Ensure the descriptor array does not get too big.
2044 if (map_of_this->NumberOfOwnDescriptors() < 2096 if (object->map()->NumberOfOwnDescriptors() <
2045 DescriptorArray::kMaxNumberOfDescriptors) { 2097 DescriptorArray::kMaxNumberOfDescriptors) {
2046 // TODO(verwaest): Support other constants. 2098 // TODO(verwaest): Support other constants.
2047 // if (mode == ALLOW_AS_CONSTANT && 2099 // if (mode == ALLOW_AS_CONSTANT &&
2048 // !value->IsTheHole() && 2100 // !value->IsTheHole() &&
2049 // !value->IsConsString()) { 2101 // !value->IsConsString()) {
2050 if (value->IsJSFunction()) { 2102 if (value->IsJSFunction()) {
2051 result = AddConstantProperty(name, value, attributes, transition_flag); 2103 AddConstantProperty(object, name, value, attributes, transition_flag);
2052 } else { 2104 } else {
2053 result = AddFastProperty( 2105 AddFastProperty(object, name, value, attributes, store_mode,
2054 name, value, attributes, store_mode, value_type, transition_flag); 2106 value_type, transition_flag);
2055 } 2107 }
2056 } else { 2108 } else {
2057 // Normalize the object to prevent very large instance descriptors. 2109 // Normalize the object to prevent very large instance descriptors.
2058 // This eliminates unwanted N^2 allocation and lookup behavior. 2110 // This eliminates unwanted N^2 allocation and lookup behavior.
2059 Object* obj; 2111 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
2060 MaybeObject* maybe = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); 2112 AddSlowProperty(object, name, value, attributes);
2061 if (!maybe->To(&obj)) return maybe;
2062 result = AddSlowProperty(name, value, attributes);
2063 } 2113 }
2064 } else { 2114 } else {
2065 result = AddSlowProperty(name, value, attributes); 2115 AddSlowProperty(object, name, value, attributes);
2066 } 2116 }
2067 2117
2068 Handle<Object> hresult; 2118 if (FLAG_harmony_observation && object->map()->is_observed()) {
2069 if (!result->ToHandle(&hresult, isolate)) return result; 2119 Handle<Object> old_value = isolate->factory()->the_hole_value();
2070 2120 EnqueueChangeRecord(object, "new", name, old_value);
2071 if (FLAG_harmony_observation && map()->is_observed()) { 2121 }
2072 EnqueueChangeRecord(handle(this, isolate), 2122
2073 "new", 2123 return value;
2074 handle(name, isolate), 2124 }
2075 handle(heap->the_hole_value(), isolate)); 2125
2076 } 2126
2077
2078 return *hresult;
2079 }
2080
2081
2082 void JSObject::EnqueueChangeRecord(Handle<JSObject> object, 2127 void JSObject::EnqueueChangeRecord(Handle<JSObject> object,
2083 const char* type_str, 2128 const char* type_str,
2084 Handle<Name> name, 2129 Handle<Name> name,
2085 Handle<Object> old_value) { 2130 Handle<Object> old_value) {
2086 Isolate* isolate = object->GetIsolate(); 2131 Isolate* isolate = object->GetIsolate();
2087 HandleScope scope(isolate); 2132 HandleScope scope(isolate);
2088 Handle<String> type = isolate->factory()->InternalizeUtf8String(type_str); 2133 Handle<String> type = isolate->factory()->InternalizeUtf8String(type_str);
2089 if (object->IsJSGlobalObject()) { 2134 if (object->IsJSGlobalObject()) {
2090 object = handle(JSGlobalObject::cast(*object)->global_receiver(), isolate); 2135 object = handle(JSGlobalObject::cast(*object)->global_receiver(), isolate);
2091 } 2136 }
(...skipping 16 matching lines...) Expand all
2108 isolate->observers_deliver_changes(), 2153 isolate->observers_deliver_changes(),
2109 isolate->factory()->undefined_value(), 2154 isolate->factory()->undefined_value(),
2110 0, 2155 0,
2111 NULL, 2156 NULL,
2112 &threw); 2157 &threw);
2113 ASSERT(!threw); 2158 ASSERT(!threw);
2114 isolate->set_observer_delivery_pending(false); 2159 isolate->set_observer_delivery_pending(false);
2115 } 2160 }
2116 2161
2117 2162
2118 MaybeObject* JSObject::SetPropertyPostInterceptor( 2163 Handle<Object> JSObject::SetPropertyPostInterceptor(
2119 Name* name, 2164 Handle<JSObject> object,
2120 Object* value, 2165 Handle<Name> name,
2166 Handle<Object> value,
2121 PropertyAttributes attributes, 2167 PropertyAttributes attributes,
2122 StrictModeFlag strict_mode, 2168 StrictModeFlag strict_mode) {
2123 StoreMode mode) {
2124 // Check local property, ignore interceptor. 2169 // Check local property, ignore interceptor.
2125 LookupResult result(GetIsolate()); 2170 LookupResult result(object->GetIsolate());
2126 LocalLookupRealNamedProperty(name, &result); 2171 object->LocalLookupRealNamedProperty(*name, &result);
2127 if (!result.IsFound()) map()->LookupTransition(this, name, &result); 2172 if (!result.IsFound()) {
2173 object->map()->LookupTransition(*object, *name, &result);
2174 }
2128 if (result.IsFound()) { 2175 if (result.IsFound()) {
2129 // An existing property or a map transition was found. Use set property to 2176 // An existing property or a map transition was found. Use set property to
2130 // handle all these cases. 2177 // handle all these cases.
2131 return SetProperty(&result, name, value, attributes, strict_mode); 2178 return SetPropertyForResult(object, &result, name, value, attributes,
2179 strict_mode, MAY_BE_STORE_FROM_KEYED);
2132 } 2180 }
2133 bool done = false; 2181 bool done = false;
2134 MaybeObject* result_object = 2182 Handle<Object> result_object = SetPropertyViaPrototypes(
2135 SetPropertyViaPrototypes(name, value, attributes, strict_mode, &done); 2183 object, name, value, attributes, strict_mode, &done);
2136 if (done) return result_object; 2184 if (done) return result_object;
2137 // Add a new real property. 2185 // Add a new real property.
2138 return AddProperty(name, value, attributes, strict_mode, 2186 return AddProperty(object, name, value, attributes, strict_mode);
2139 MAY_BE_STORE_FROM_KEYED, PERFORM_EXTENSIBILITY_CHECK,
2140 OPTIMAL_REPRESENTATION, mode);
2141 } 2187 }
2142 2188
2143 2189
2144 MaybeObject* JSObject::ReplaceSlowProperty(Name* name, 2190 static Handle<Object> ReplaceSlowProperty(Handle<JSObject> object,
2145 Object* value, 2191 Handle<Name> name,
2146 PropertyAttributes attributes) { 2192 Handle<Object> value,
2147 NameDictionary* dictionary = property_dictionary(); 2193 PropertyAttributes attributes) {
2148 int old_index = dictionary->FindEntry(name); 2194 NameDictionary* dictionary = object->property_dictionary();
2195 int old_index = dictionary->FindEntry(*name);
2149 int new_enumeration_index = 0; // 0 means "Use the next available index." 2196 int new_enumeration_index = 0; // 0 means "Use the next available index."
2150 if (old_index != -1) { 2197 if (old_index != -1) {
2151 // All calls to ReplaceSlowProperty have had all transitions removed. 2198 // All calls to ReplaceSlowProperty have had all transitions removed.
2152 new_enumeration_index = dictionary->DetailsAt(old_index).dictionary_index(); 2199 new_enumeration_index = dictionary->DetailsAt(old_index).dictionary_index();
2153 } 2200 }
2154 2201
2155 PropertyDetails new_details(attributes, NORMAL, new_enumeration_index); 2202 PropertyDetails new_details(attributes, NORMAL, new_enumeration_index);
2156 return SetNormalizedProperty(name, value, new_details); 2203 return JSObject::SetNormalizedProperty(object, name, value, new_details);
2157 } 2204 }
2158 2205
2159 2206
2160 const char* Representation::Mnemonic() const { 2207 const char* Representation::Mnemonic() const {
2161 switch (kind_) { 2208 switch (kind_) {
2162 case kNone: return "v"; 2209 case kNone: return "v";
2163 case kTagged: return "t"; 2210 case kTagged: return "t";
2164 case kSmi: return "s"; 2211 case kSmi: return "s";
2165 case kDouble: return "d"; 2212 case kDouble: return "d";
2166 case kInteger32: return "i"; 2213 case kInteger32: return "i";
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
2253 ASSERT(target_inobject < inobject_properties()); 2300 ASSERT(target_inobject < inobject_properties());
2254 if (target_number_of_fields <= target_inobject) { 2301 if (target_number_of_fields <= target_inobject) {
2255 ASSERT(target_number_of_fields + target_unused == target_inobject); 2302 ASSERT(target_number_of_fields + target_unused == target_inobject);
2256 return false; 2303 return false;
2257 } 2304 }
2258 // Otherwise, properties will need to be moved to the backing store. 2305 // Otherwise, properties will need to be moved to the backing store.
2259 return true; 2306 return true;
2260 } 2307 }
2261 2308
2262 2309
2310 void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) {
2311 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), object->MigrateToMap(*new_map));
2312 }
2313
2314
2263 // To migrate an instance to a map: 2315 // To migrate an instance to a map:
2264 // - First check whether the instance needs to be rewritten. If not, simply 2316 // - First check whether the instance needs to be rewritten. If not, simply
2265 // change the map. 2317 // change the map.
2266 // - Otherwise, allocate a fixed array large enough to hold all fields, in 2318 // - Otherwise, allocate a fixed array large enough to hold all fields, in
2267 // addition to unused space. 2319 // addition to unused space.
2268 // - Copy all existing properties in, in the following order: backing store 2320 // - Copy all existing properties in, in the following order: backing store
2269 // properties, unused fields, inobject properties. 2321 // properties, unused fields, inobject properties.
2270 // - If all allocation succeeded, commit the state atomically: 2322 // - If all allocation succeeded, commit the state atomically:
2271 // * Copy inobject properties from the backing store back into the object. 2323 // * Copy inobject properties from the backing store back into the object.
2272 // * Trim the difference in instance size of the object. This also cleanly 2324 // * 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); 2406 RightTrimFixedArray<FROM_MUTATOR>(heap, array, inobject);
2355 set_properties(array); 2407 set_properties(array);
2356 } 2408 }
2357 2409
2358 set_map(new_map); 2410 set_map(new_map);
2359 2411
2360 return this; 2412 return this;
2361 } 2413 }
2362 2414
2363 2415
2364 MaybeObject* JSObject::GeneralizeFieldRepresentation( 2416 void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object,
2365 int modify_index, 2417 int modify_index,
2366 Representation new_representation, 2418 Representation new_representation,
2367 StoreMode store_mode) { 2419 StoreMode store_mode) {
2368 Map* new_map; 2420 Handle<Map> new_map = Map::GeneralizeRepresentation(
2369 MaybeObject* maybe_new_map = map()->GeneralizeRepresentation( 2421 handle(object->map()), modify_index, new_representation, store_mode);
2370 modify_index, new_representation, store_mode); 2422 if (object->map() == *new_map) return;
2371 if (!maybe_new_map->To(&new_map)) return maybe_new_map; 2423 return MigrateToMap(object, new_map);
2372 if (map() == new_map) return this;
2373
2374 return MigrateToMap(new_map);
2375 } 2424 }
2376 2425
2377 2426
2378 int Map::NumberOfFields() { 2427 int Map::NumberOfFields() {
2379 DescriptorArray* descriptors = instance_descriptors(); 2428 DescriptorArray* descriptors = instance_descriptors();
2380 int result = 0; 2429 int result = 0;
2381 for (int i = 0; i < NumberOfOwnDescriptors(); i++) { 2430 for (int i = 0; i < NumberOfOwnDescriptors(); i++) {
2382 if (descriptors->GetDetails(i).type() == FIELD) result++; 2431 if (descriptors->GetDetails(i).type() == FIELD) result++;
2383 } 2432 }
2384 return result; 2433 return result;
2385 } 2434 }
2386 2435
2387 2436
2388 MaybeObject* Map::CopyGeneralizeAllRepresentations( 2437 Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map,
2389 int modify_index, 2438 int modify_index,
2390 StoreMode store_mode, 2439 StoreMode store_mode,
2391 PropertyAttributes attributes, 2440 PropertyAttributes attributes,
2392 const char* reason) { 2441 const char* reason) {
2393 Map* new_map; 2442 Handle<Map> new_map = Copy(map);
2394 MaybeObject* maybe_map = this->Copy();
2395 if (!maybe_map->To(&new_map)) return maybe_map;
2396 2443
2397 DescriptorArray* descriptors = new_map->instance_descriptors(); 2444 DescriptorArray* descriptors = new_map->instance_descriptors();
2398 descriptors->InitializeRepresentations(Representation::Tagged()); 2445 descriptors->InitializeRepresentations(Representation::Tagged());
2399 2446
2400 // Unless the instance is being migrated, ensure that modify_index is a field. 2447 // Unless the instance is being migrated, ensure that modify_index is a field.
2401 PropertyDetails details = descriptors->GetDetails(modify_index); 2448 PropertyDetails details = descriptors->GetDetails(modify_index);
2402 if (store_mode == FORCE_FIELD && details.type() != FIELD) { 2449 if (store_mode == FORCE_FIELD && details.type() != FIELD) {
2403 FieldDescriptor d(descriptors->GetKey(modify_index), 2450 FieldDescriptor d(descriptors->GetKey(modify_index),
2404 new_map->NumberOfFields(), 2451 new_map->NumberOfFields(),
2405 attributes, 2452 attributes,
2406 Representation::Tagged()); 2453 Representation::Tagged());
2407 d.SetSortedKeyIndex(details.pointer()); 2454 d.SetSortedKeyIndex(details.pointer());
2408 descriptors->Set(modify_index, &d); 2455 descriptors->Set(modify_index, &d);
2409 int unused_property_fields = new_map->unused_property_fields() - 1; 2456 int unused_property_fields = new_map->unused_property_fields() - 1;
2410 if (unused_property_fields < 0) { 2457 if (unused_property_fields < 0) {
2411 unused_property_fields += JSObject::kFieldsAdded; 2458 unused_property_fields += JSObject::kFieldsAdded;
2412 } 2459 }
2413 new_map->set_unused_property_fields(unused_property_fields); 2460 new_map->set_unused_property_fields(unused_property_fields);
2414 } 2461 }
2415 2462
2416 if (FLAG_trace_generalization) { 2463 if (FLAG_trace_generalization) {
2417 PrintGeneralization(stdout, reason, modify_index, 2464 map->PrintGeneralization(stdout, reason, modify_index,
2418 new_map->NumberOfOwnDescriptors(), 2465 new_map->NumberOfOwnDescriptors(),
2419 new_map->NumberOfOwnDescriptors(), 2466 new_map->NumberOfOwnDescriptors(),
2420 details.type() == CONSTANT && store_mode == FORCE_FIELD, 2467 details.type() == CONSTANT && store_mode == FORCE_FIELD,
2421 Representation::Tagged(), Representation::Tagged()); 2468 Representation::Tagged(), Representation::Tagged());
2422 } 2469 }
2423 return new_map; 2470 return new_map;
2424 } 2471 }
2425 2472
2426 2473
2427 void Map::DeprecateTransitionTree() { 2474 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 2602 // FindUpdatedMap. This uses the keys in the own map's descriptor array to
2556 // walk the transition tree. 2603 // walk the transition tree.
2557 // - Merge/generalize the descriptor array of the current map and |updated|. 2604 // - Merge/generalize the descriptor array of the current map and |updated|.
2558 // - Generalize the |modify_index| descriptor using |new_representation|. 2605 // - Generalize the |modify_index| descriptor using |new_representation|.
2559 // - Walk the tree again starting from the root towards |updated|. Stop at 2606 // - 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 2607 // |split_map|, the first map who's descriptor array does not match the merged
2561 // descriptor array. 2608 // descriptor array.
2562 // - If |updated| == |split_map|, |updated| is in the expected state. Return it. 2609 // - If |updated| == |split_map|, |updated| is in the expected state. Return it.
2563 // - Otherwise, invalidate the outdated transition target from |updated|, and 2610 // - Otherwise, invalidate the outdated transition target from |updated|, and
2564 // replace its transition tree with a new branch for the updated descriptors. 2611 // replace its transition tree with a new branch for the updated descriptors.
2565 MaybeObject* Map::GeneralizeRepresentation(int modify_index, 2612 Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map,
2566 Representation new_representation, 2613 int modify_index,
2567 StoreMode store_mode) { 2614 Representation new_representation,
2568 Map* old_map = this; 2615 StoreMode store_mode) {
2569 DescriptorArray* old_descriptors = old_map->instance_descriptors(); 2616 Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors());
2570 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); 2617 PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
2571 Representation old_representation = old_details.representation(); 2618 Representation old_representation = old_details.representation();
2572 2619
2573 // It's fine to transition from None to anything but double without any 2620 // It's fine to transition from None to anything but double without any
2574 // modification to the object, because the default uninitialized value for 2621 // modification to the object, because the default uninitialized value for
2575 // representation None can be overwritten by both smi and tagged values. 2622 // representation None can be overwritten by both smi and tagged values.
2576 // Doubles, however, would require a box allocation. 2623 // Doubles, however, would require a box allocation.
2577 if (old_representation.IsNone() && 2624 if (old_representation.IsNone() &&
2578 !new_representation.IsNone() && 2625 !new_representation.IsNone() &&
2579 !new_representation.IsDouble()) { 2626 !new_representation.IsDouble()) {
2580 old_descriptors->SetRepresentation(modify_index, new_representation); 2627 old_descriptors->SetRepresentation(modify_index, new_representation);
2581 return old_map; 2628 return old_map;
2582 } 2629 }
2583 2630
2584 int descriptors = old_map->NumberOfOwnDescriptors(); 2631 int descriptors = old_map->NumberOfOwnDescriptors();
2585 Map* root_map = old_map->FindRootMap(); 2632 Handle<Map> root_map(old_map->FindRootMap());
2586 2633
2587 // Check the state of the root map. 2634 // Check the state of the root map.
2588 if (!old_map->EquivalentToForTransition(root_map)) { 2635 if (!old_map->EquivalentToForTransition(*root_map)) {
2589 return CopyGeneralizeAllRepresentations( 2636 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
2590 modify_index, store_mode, old_details.attributes(), "not equivalent"); 2637 old_details.attributes(), "not equivalent");
2591 } 2638 }
2592 2639
2593 int verbatim = root_map->NumberOfOwnDescriptors(); 2640 int verbatim = root_map->NumberOfOwnDescriptors();
2594 2641
2595 if (store_mode != ALLOW_AS_CONSTANT && modify_index < verbatim) { 2642 if (store_mode != ALLOW_AS_CONSTANT && modify_index < verbatim) {
2596 return CopyGeneralizeAllRepresentations( 2643 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
2597 modify_index, store_mode,
2598 old_details.attributes(), "root modification"); 2644 old_details.attributes(), "root modification");
2599 } 2645 }
2600 2646
2601 Map* updated = root_map->FindUpdatedMap( 2647 Map* raw_updated = root_map->FindUpdatedMap(
2602 verbatim, descriptors, old_descriptors); 2648 verbatim, descriptors, *old_descriptors);
2603 if (updated == NULL) { 2649 if (raw_updated == NULL) {
2604 return CopyGeneralizeAllRepresentations( 2650 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
2605 modify_index, store_mode, old_details.attributes(), "incompatible"); 2651 old_details.attributes(), "incompatible");
2606 } 2652 }
2607 2653
2608 DescriptorArray* updated_descriptors = updated->instance_descriptors(); 2654 Handle<Map> updated(raw_updated);
2655 Handle<DescriptorArray> updated_descriptors(updated->instance_descriptors());
2609 2656
2610 int valid = updated->NumberOfOwnDescriptors(); 2657 int valid = updated->NumberOfOwnDescriptors();
2611 2658
2612 // Directly change the map if the target map is more general. Ensure that the 2659 // 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. 2660 // target type of the modify_index is a FIELD, unless we are migrating.
2614 if (updated_descriptors->IsMoreGeneralThan( 2661 if (updated_descriptors->IsMoreGeneralThan(
2615 verbatim, valid, descriptors, old_descriptors) && 2662 verbatim, valid, descriptors, *old_descriptors) &&
2616 (store_mode == ALLOW_AS_CONSTANT || 2663 (store_mode == ALLOW_AS_CONSTANT ||
2617 updated_descriptors->GetDetails(modify_index).type() == FIELD)) { 2664 updated_descriptors->GetDetails(modify_index).type() == FIELD)) {
2618 Representation updated_representation = 2665 Representation updated_representation =
2619 updated_descriptors->GetDetails(modify_index).representation(); 2666 updated_descriptors->GetDetails(modify_index).representation();
2620 if (new_representation.fits_into(updated_representation)) return updated; 2667 if (new_representation.fits_into(updated_representation)) return updated;
2621 } 2668 }
2622 2669
2623 DescriptorArray* new_descriptors; 2670 Handle<DescriptorArray> new_descriptors = DescriptorArray::Merge(
2624 MaybeObject* maybe_descriptors = updated_descriptors->Merge( 2671 updated_descriptors, verbatim, valid, descriptors, modify_index,
2625 verbatim, valid, descriptors, modify_index, store_mode, old_descriptors); 2672 store_mode, old_descriptors);
2626 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
2627 ASSERT(store_mode == ALLOW_AS_CONSTANT || 2673 ASSERT(store_mode == ALLOW_AS_CONSTANT ||
2628 new_descriptors->GetDetails(modify_index).type() == FIELD); 2674 new_descriptors->GetDetails(modify_index).type() == FIELD);
2629 2675
2630 old_representation = 2676 old_representation =
2631 new_descriptors->GetDetails(modify_index).representation(); 2677 new_descriptors->GetDetails(modify_index).representation();
2632 Representation updated_representation = 2678 Representation updated_representation =
2633 new_representation.generalize(old_representation); 2679 new_representation.generalize(old_representation);
2634 if (!updated_representation.Equals(old_representation)) { 2680 if (!updated_representation.Equals(old_representation)) {
2635 new_descriptors->SetRepresentation(modify_index, updated_representation); 2681 new_descriptors->SetRepresentation(modify_index, updated_representation);
2636 } 2682 }
2637 2683
2638 Map* split_map = root_map->FindLastMatchMap( 2684 Handle<Map> split_map(root_map->FindLastMatchMap(
2639 verbatim, descriptors, new_descriptors); 2685 verbatim, descriptors, *new_descriptors));
2640 2686
2641 int split_descriptors = split_map->NumberOfOwnDescriptors(); 2687 int split_descriptors = split_map->NumberOfOwnDescriptors();
2642 // This is shadowed by |updated_descriptors| being more general than 2688 // This is shadowed by |updated_descriptors| being more general than
2643 // |old_descriptors|. 2689 // |old_descriptors|.
2644 ASSERT(descriptors != split_descriptors); 2690 ASSERT(descriptors != split_descriptors);
2645 2691
2646 int descriptor = split_descriptors; 2692 int descriptor = split_descriptors;
2647 split_map->DeprecateTarget( 2693 split_map->DeprecateTarget(
2648 old_descriptors->GetKey(descriptor), new_descriptors); 2694 old_descriptors->GetKey(descriptor), *new_descriptors);
2649 2695
2650 if (FLAG_trace_generalization) { 2696 if (FLAG_trace_generalization) {
2651 PrintGeneralization( 2697 old_map->PrintGeneralization(
2652 stdout, "", modify_index, descriptor, descriptors, 2698 stdout, "", modify_index, descriptor, descriptors,
2653 old_descriptors->GetDetails(modify_index).type() == CONSTANT && 2699 old_descriptors->GetDetails(modify_index).type() == CONSTANT &&
2654 store_mode == FORCE_FIELD, 2700 store_mode == FORCE_FIELD,
2655 old_representation, updated_representation); 2701 old_representation, updated_representation);
2656 } 2702 }
2657 2703
2658 Map* new_map = split_map;
2659 // Add missing transitions. 2704 // Add missing transitions.
2705 Handle<Map> new_map = split_map;
2660 for (; descriptor < descriptors; descriptor++) { 2706 for (; descriptor < descriptors; descriptor++) {
2661 MaybeObject* maybe_map = new_map->CopyInstallDescriptors( 2707 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); 2708 new_map->set_migration_target(true);
2671 } 2709 }
2672 2710
2673 new_map->set_owns_descriptors(true); 2711 new_map->set_owns_descriptors(true);
2674 return new_map; 2712 return new_map;
2675 } 2713 }
2676 2714
2677 2715
2678 Map* Map::CurrentMapForDeprecated() { 2716 Map* Map::CurrentMapForDeprecated() {
2679 DisallowHeapAllocation no_allocation; 2717 DisallowHeapAllocation no_allocation;
(...skipping 16 matching lines...) Expand all
2696 int valid = updated->NumberOfOwnDescriptors(); 2734 int valid = updated->NumberOfOwnDescriptors();
2697 if (!updated_descriptors->IsMoreGeneralThan( 2735 if (!updated_descriptors->IsMoreGeneralThan(
2698 verbatim, valid, descriptors, old_descriptors)) { 2736 verbatim, valid, descriptors, old_descriptors)) {
2699 return NULL; 2737 return NULL;
2700 } 2738 }
2701 2739
2702 return updated; 2740 return updated;
2703 } 2741 }
2704 2742
2705 2743
2706 MaybeObject* JSObject::SetPropertyWithInterceptor( 2744 Handle<Object> JSObject::SetPropertyWithInterceptor(
2707 Name* name, 2745 Handle<JSObject> object,
2708 Object* value, 2746 Handle<Name> name,
2747 Handle<Object> value,
2709 PropertyAttributes attributes, 2748 PropertyAttributes attributes,
2710 StrictModeFlag strict_mode) { 2749 StrictModeFlag strict_mode) {
2711 // TODO(rossberg): Support symbols in the API. 2750 // TODO(rossberg): Support symbols in the API.
2712 if (name->IsSymbol()) return value; 2751 if (name->IsSymbol()) return value;
2713 Isolate* isolate = GetIsolate(); 2752 Isolate* isolate = object->GetIsolate();
2714 HandleScope scope(isolate); 2753 Handle<String> name_string = Handle<String>::cast(name);
2715 Handle<JSObject> this_handle(this); 2754 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()) { 2755 if (!interceptor->setter()->IsUndefined()) {
2720 LOG(isolate, ApiNamedPropertyAccess("interceptor-named-set", this, name)); 2756 LOG(isolate,
2721 PropertyCallbackArguments args(isolate, interceptor->data(), this, this); 2757 ApiNamedPropertyAccess("interceptor-named-set", *object, *name));
2758 PropertyCallbackArguments args(
2759 isolate, interceptor->data(), *object, *object);
2722 v8::NamedPropertySetterCallback setter = 2760 v8::NamedPropertySetterCallback setter =
2723 v8::ToCData<v8::NamedPropertySetterCallback>(interceptor->setter()); 2761 v8::ToCData<v8::NamedPropertySetterCallback>(interceptor->setter());
2724 Handle<Object> value_unhole(value->IsTheHole() ? 2762 Handle<Object> value_unhole = value->IsTheHole()
2725 isolate->heap()->undefined_value() : 2763 ? Handle<Object>(isolate->factory()->undefined_value()) : value;
2726 value,
2727 isolate);
2728 v8::Handle<v8::Value> result = args.Call(setter, 2764 v8::Handle<v8::Value> result = args.Call(setter,
2729 v8::Utils::ToLocal(name_handle), 2765 v8::Utils::ToLocal(name_string),
2730 v8::Utils::ToLocal(value_unhole)); 2766 v8::Utils::ToLocal(value_unhole));
2731 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 2767 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
2732 if (!result.IsEmpty()) return *value_handle; 2768 if (!result.IsEmpty()) return value;
2733 } 2769 }
2734 MaybeObject* raw_result = 2770 Handle<Object> result =
2735 this_handle->SetPropertyPostInterceptor(*name_handle, 2771 SetPropertyPostInterceptor(object, name, value, attributes, strict_mode);
2736 *value_handle, 2772 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
2737 attributes, 2773 return result;
2738 strict_mode);
2739 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
2740 return raw_result;
2741 } 2774 }
2742 2775
2743 2776
2744 Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object, 2777 Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object,
2745 Handle<Name> key, 2778 Handle<Name> name,
2746 Handle<Object> value, 2779 Handle<Object> value,
2747 PropertyAttributes attributes, 2780 PropertyAttributes attributes,
2748 StrictModeFlag strict_mode) { 2781 StrictModeFlag strict_mode,
2749 CALL_HEAP_FUNCTION(object->GetIsolate(), 2782 StoreFromKeyed store_mode) {
2750 object->SetProperty(*key, *value, attributes, strict_mode), 2783 LookupResult result(object->GetIsolate());
2751 Object); 2784 object->LocalLookup(*name, &result, true);
2785 if (!result.IsFound()) {
2786 object->map()->LookupTransition(JSObject::cast(*object), *name, &result);
2787 }
2788 return SetProperty(object, &result, name, value, attributes, strict_mode,
2789 store_mode);
2752 } 2790 }
2753 2791
2754 2792
2755 MaybeObject* JSReceiver::SetPropertyOrFail(
2756 Handle<JSReceiver> object,
2757 Handle<Name> key,
2758 Handle<Object> value,
2759 PropertyAttributes attributes,
2760 StrictModeFlag strict_mode,
2761 JSReceiver::StoreFromKeyed store_mode) {
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, 2793 MaybeObject* JSObject::SetPropertyWithCallback(Object* structure,
2783 Name* name, 2794 Name* name,
2784 Object* value, 2795 Object* value,
2785 JSObject* holder, 2796 JSObject* holder,
2786 StrictModeFlag strict_mode) { 2797 StrictModeFlag strict_mode) {
2787 Isolate* isolate = GetIsolate(); 2798 Isolate* isolate = GetIsolate();
2788 HandleScope scope(isolate); 2799 HandleScope scope(isolate);
2789 2800
2790 // We should never get here to initialize a const with the hole 2801 // We should never get here to initialize a const with the hole
2791 // value since a const declaration would conflict with the setter. 2802 // value since a const declaration would conflict with the setter.
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
2923 value, 2934 value,
2924 JSObject::cast(pt), 2935 JSObject::cast(pt),
2925 strict_mode); 2936 strict_mode);
2926 } 2937 }
2927 } 2938 }
2928 } 2939 }
2929 *found = false; 2940 *found = false;
2930 return heap->the_hole_value(); 2941 return heap->the_hole_value();
2931 } 2942 }
2932 2943
2933 MaybeObject* JSObject::SetPropertyViaPrototypes( 2944 Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object,
2934 Name* name, 2945 Handle<Name> name,
2935 Object* value, 2946 Handle<Object> value,
2936 PropertyAttributes attributes, 2947 PropertyAttributes attributes,
2937 StrictModeFlag strict_mode, 2948 StrictModeFlag strict_mode,
2938 bool* done) { 2949 bool* done) {
2939 Heap* heap = GetHeap(); 2950 Isolate* isolate = object->GetIsolate();
2940 Isolate* isolate = heap->isolate();
2941 2951
2942 *done = false; 2952 *done = false;
2943 // We could not find a local property so let's check whether there is an 2953 // 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 2954 // accessor that wants to handle the property, or whether the property is
2945 // read-only on the prototype chain. 2955 // read-only on the prototype chain.
2946 LookupResult result(isolate); 2956 LookupResult result(isolate);
2947 LookupRealNamedPropertyInPrototypes(name, &result); 2957 object->LookupRealNamedPropertyInPrototypes(*name, &result);
2948 if (result.IsFound()) { 2958 if (result.IsFound()) {
2949 switch (result.type()) { 2959 switch (result.type()) {
2950 case NORMAL: 2960 case NORMAL:
2951 case FIELD: 2961 case FIELD:
2952 case CONSTANT: 2962 case CONSTANT:
2953 *done = result.IsReadOnly(); 2963 *done = result.IsReadOnly();
2954 break; 2964 break;
2955 case INTERCEPTOR: { 2965 case INTERCEPTOR: {
2956 PropertyAttributes attr = 2966 PropertyAttributes attr =
2957 result.holder()->GetPropertyAttributeWithInterceptor( 2967 result.holder()->GetPropertyAttributeWithInterceptor(
2958 this, name, true); 2968 *object, *name, true);
2959 *done = !!(attr & READ_ONLY); 2969 *done = !!(attr & READ_ONLY);
2960 break; 2970 break;
2961 } 2971 }
2962 case CALLBACKS: { 2972 case CALLBACKS: {
2963 if (!FLAG_es5_readonly && result.IsReadOnly()) break; 2973 if (!FLAG_es5_readonly && result.IsReadOnly()) break;
2964 *done = true; 2974 *done = true;
2965 return SetPropertyWithCallback(result.GetCallbackObject(), 2975 CALL_HEAP_FUNCTION(isolate,
2966 name, value, result.holder(), strict_mode); 2976 object->SetPropertyWithCallback(
2977 result.GetCallbackObject(),
2978 *name, *value, result.holder(), strict_mode),
2979 Object);
2967 } 2980 }
2968 case HANDLER: { 2981 case HANDLER: {
2969 return result.proxy()->SetPropertyViaPrototypesWithHandler( 2982 CALL_HEAP_FUNCTION(isolate,
2970 this, name, value, attributes, strict_mode, done); 2983 result.proxy()->SetPropertyViaPrototypesWithHandler(
2984 *object, *name, *value, attributes, strict_mode,
2985 done),
2986 Object);
2971 } 2987 }
2972 case TRANSITION: 2988 case TRANSITION:
2973 case NONEXISTENT: 2989 case NONEXISTENT:
2974 UNREACHABLE(); 2990 UNREACHABLE();
2975 break; 2991 break;
2976 } 2992 }
2977 } 2993 }
2978 2994
2979 // If we get here with *done true, we have encountered a read-only property. 2995 // If we get here with *done true, we have encountered a read-only property.
2980 if (!FLAG_es5_readonly) *done = false; 2996 if (!FLAG_es5_readonly) *done = false;
2981 if (*done) { 2997 if (*done) {
2982 if (strict_mode == kNonStrictMode) return value; 2998 if (strict_mode == kNonStrictMode) return value;
2983 Handle<Object> args[] = { Handle<Object>(name, isolate), 2999 Handle<Object> args[] = { name, object };
2984 Handle<Object>(this, isolate)}; 3000 Handle<Object> error = isolate->factory()->NewTypeError(
2985 return isolate->Throw(*isolate->factory()->NewTypeError( 3001 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)));
2986 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)))); 3002 isolate->Throw(*error);
3003 return Handle<Object>();
2987 } 3004 }
2988 return heap->the_hole_value(); 3005 return isolate->factory()->the_hole_value();
2989 } 3006 }
2990 3007
2991 3008
2992 void Map::EnsureDescriptorSlack(Handle<Map> map, int slack) { 3009 void Map::EnsureDescriptorSlack(Handle<Map> map, int slack) {
2993 Handle<DescriptorArray> descriptors(map->instance_descriptors()); 3010 Handle<DescriptorArray> descriptors(map->instance_descriptors());
2994 if (slack <= descriptors->NumberOfSlackDescriptors()) return; 3011 if (slack <= descriptors->NumberOfSlackDescriptors()) return;
2995 int number_of_descriptors = descriptors->number_of_descriptors(); 3012 int number_of_descriptors = descriptors->number_of_descriptors();
2996 Isolate* isolate = map->GetIsolate(); 3013 Isolate* isolate = map->GetIsolate();
2997 Handle<DescriptorArray> new_descriptors = 3014 Handle<DescriptorArray> new_descriptors =
2998 isolate->factory()->NewDescriptorArray(number_of_descriptors, slack); 3015 isolate->factory()->NewDescriptorArray(number_of_descriptors, slack);
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
3399 3416
3400 Isolate* isolate = GetIsolate(); 3417 Isolate* isolate = GetIsolate();
3401 HandleScope scope(isolate); 3418 HandleScope scope(isolate);
3402 Handle<Object> value_handle(value, isolate); 3419 Handle<Object> value_handle(value, isolate);
3403 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); 3420 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET);
3404 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 3421 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
3405 return *value_handle; 3422 return *value_handle;
3406 } 3423 }
3407 3424
3408 3425
3409 MaybeObject* JSReceiver::SetProperty(LookupResult* result, 3426 Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object,
3410 Name* key, 3427 LookupResult* result,
3411 Object* value, 3428 Handle<Name> key,
3412 PropertyAttributes attributes, 3429 Handle<Object> value,
3413 StrictModeFlag strict_mode, 3430 PropertyAttributes attributes,
3414 JSReceiver::StoreFromKeyed store_mode) { 3431 StrictModeFlag strict_mode,
3432 StoreFromKeyed store_mode) {
3415 if (result->IsHandler()) { 3433 if (result->IsHandler()) {
3416 return result->proxy()->SetPropertyWithHandler( 3434 return JSProxy::SetPropertyWithHandler(handle(result->proxy()),
3417 this, key, value, attributes, strict_mode); 3435 object, key, value, attributes, strict_mode);
3418 } else { 3436 } else {
3419 return JSObject::cast(this)->SetPropertyForResult( 3437 return JSObject::SetPropertyForResult(Handle<JSObject>::cast(object),
3420 result, key, value, attributes, strict_mode, store_mode); 3438 result, key, value, attributes, strict_mode, store_mode);
3421 } 3439 }
3422 } 3440 }
3423 3441
3424 3442
3425 bool JSProxy::HasPropertyWithHandler(Name* name_raw) { 3443 bool JSProxy::HasPropertyWithHandler(Name* name_raw) {
3426 Isolate* isolate = GetIsolate(); 3444 Isolate* isolate = GetIsolate();
3427 HandleScope scope(isolate); 3445 HandleScope scope(isolate);
3428 Handle<Object> receiver(this, isolate); 3446 Handle<Object> receiver(this, isolate);
3429 Handle<Object> name(name_raw, isolate); 3447 Handle<Object> name(name_raw, isolate);
3430 3448
3431 // TODO(rossberg): adjust once there is a story for symbols vs proxies. 3449 // TODO(rossberg): adjust once there is a story for symbols vs proxies.
3432 if (name->IsSymbol()) return false; 3450 if (name->IsSymbol()) return false;
3433 3451
3434 Handle<Object> args[] = { name }; 3452 Handle<Object> args[] = { name };
3435 Handle<Object> result = CallTrap( 3453 Handle<Object> result = CallTrap(
3436 "has", isolate->derived_has_trap(), ARRAY_SIZE(args), args); 3454 "has", isolate->derived_has_trap(), ARRAY_SIZE(args), args);
3437 if (isolate->has_pending_exception()) return false; 3455 if (isolate->has_pending_exception()) return false;
3438 3456
3439 return result->BooleanValue(); 3457 return result->BooleanValue();
3440 } 3458 }
3441 3459
3442 3460
3443 MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandler( 3461 Handle<Object> JSProxy::SetPropertyWithHandler(Handle<JSProxy> proxy,
3444 JSReceiver* receiver_raw, 3462 Handle<JSReceiver> receiver,
3445 Name* name_raw, 3463 Handle<Name> name,
3446 Object* value_raw, 3464 Handle<Object> value,
3447 PropertyAttributes attributes, 3465 PropertyAttributes attributes,
3448 StrictModeFlag strict_mode) { 3466 StrictModeFlag strict_mode) {
3449 Isolate* isolate = GetIsolate(); 3467 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 3468
3455 // TODO(rossberg): adjust once there is a story for symbols vs proxies. 3469 // TODO(rossberg): adjust once there is a story for symbols vs proxies.
3456 if (name->IsSymbol()) return *value; 3470 if (name->IsSymbol()) return value;
3457 3471
3458 Handle<Object> args[] = { receiver, name, value }; 3472 Handle<Object> args[] = { receiver, name, value };
3459 CallTrap("set", isolate->derived_set_trap(), ARRAY_SIZE(args), args); 3473 proxy->CallTrap("set", isolate->derived_set_trap(), ARRAY_SIZE(args), args);
3460 if (isolate->has_pending_exception()) return Failure::Exception(); 3474 if (isolate->has_pending_exception()) return Handle<Object>();
3461 3475
3462 return *value; 3476 return value;
3463 } 3477 }
3464 3478
3465 3479
3466 MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyViaPrototypesWithHandler( 3480 MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyViaPrototypesWithHandler(
3467 JSReceiver* receiver_raw, 3481 JSReceiver* receiver_raw,
3468 Name* name_raw, 3482 Name* name_raw,
3469 Object* value_raw, 3483 Object* value_raw,
3470 PropertyAttributes attributes, 3484 PropertyAttributes attributes,
3471 StrictModeFlag strict_mode, 3485 StrictModeFlag strict_mode,
3472 bool* done) { 3486 bool* done) {
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
3727 3741
3728 3742
3729 void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) { 3743 void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) {
3730 CALL_HEAP_FUNCTION_VOID( 3744 CALL_HEAP_FUNCTION_VOID(
3731 object->GetIsolate(), 3745 object->GetIsolate(),
3732 object->AllocateStorageForMap(*map)); 3746 object->AllocateStorageForMap(*map));
3733 } 3747 }
3734 3748
3735 3749
3736 void JSObject::MigrateInstance(Handle<JSObject> object) { 3750 void JSObject::MigrateInstance(Handle<JSObject> object) {
3737 CALL_HEAP_FUNCTION_VOID( 3751 // Converting any field to the most specific type will cause the
3738 object->GetIsolate(), 3752 // GeneralizeFieldRepresentation algorithm to create the most general existing
3739 object->MigrateInstance()); 3753 // transition that matches the object. This achieves what is needed.
3754 Handle<Map> original_map(object->map());
3755 GeneralizeFieldRepresentation(
3756 object, 0, Representation::None(), ALLOW_AS_CONSTANT);
3757 if (FLAG_trace_migration) {
3758 object->PrintInstanceMigration(stdout, *original_map, object->map());
3759 }
3740 } 3760 }
3741 3761
3742 3762
3743 Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) { 3763 Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) {
3744 CALL_HEAP_FUNCTION( 3764 MigrateInstance(object);
3745 object->GetIsolate(), 3765 return object;
3746 object->MigrateInstance(),
3747 Object);
3748 } 3766 }
3749 3767
3750 3768
3751 Handle<Map> Map::GeneralizeRepresentation(Handle<Map> map, 3769 Handle<Object> JSObject::SetPropertyUsingTransition(
3752 int modify_index, 3770 Handle<JSObject> object,
3753 Representation representation, 3771 LookupResult* lookup,
3754 StoreMode store_mode) { 3772 Handle<Name> name,
3755 CALL_HEAP_FUNCTION( 3773 Handle<Object> value,
3756 map->GetIsolate(), 3774 PropertyAttributes attributes) {
3757 map->GeneralizeRepresentation(modify_index, representation, store_mode), 3775 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(); 3776 int descriptor = transition_map->LastAdded();
3768 3777
3769 DescriptorArray* descriptors = transition_map->instance_descriptors(); 3778 DescriptorArray* descriptors = transition_map->instance_descriptors();
3770 PropertyDetails details = descriptors->GetDetails(descriptor); 3779 PropertyDetails details = descriptors->GetDetails(descriptor);
3771 3780
3772 if (details.type() == CALLBACKS || attributes != details.attributes()) { 3781 if (details.type() == CALLBACKS || attributes != details.attributes()) {
3773 // AddProperty will either normalize the object, or create a new fast copy 3782 // 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 3783 // of the map. If we get a fast copy of the map, all field representations
3775 // will be tagged since the transition is omitted. 3784 // will be tagged since the transition is omitted.
3776 return lookup->holder()->AddProperty( 3785 return JSObject::AddProperty(
3777 *name, *value, attributes, kNonStrictMode, 3786 object, name, value, attributes, kNonStrictMode,
3778 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED, 3787 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED,
3779 JSReceiver::OMIT_EXTENSIBILITY_CHECK, 3788 JSReceiver::OMIT_EXTENSIBILITY_CHECK,
3780 JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION); 3789 JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION);
3781 } 3790 }
3782 3791
3783 // Keep the target CONSTANT if the same value is stored. 3792 // Keep the target CONSTANT if the same value is stored.
3784 // TODO(verwaest): Also support keeping the placeholder 3793 // TODO(verwaest): Also support keeping the placeholder
3785 // (value->IsUninitialized) as constant. 3794 // (value->IsUninitialized) as constant.
3786 if (details.type() == CONSTANT && 3795 if (details.type() == CONSTANT &&
3787 descriptors->GetValue(descriptor) == *value) { 3796 descriptors->GetValue(descriptor) == *value) {
3788 lookup->holder()->set_map(transition_map); 3797 object->set_map(*transition_map);
3789 return *value; 3798 return value;
3790 } 3799 }
3791 3800
3792 Representation representation = details.representation(); 3801 Representation representation = details.representation();
3793 3802
3794 if (!value->FitsRepresentation(representation) || 3803 if (!value->FitsRepresentation(representation) ||
3795 details.type() == CONSTANT) { 3804 details.type() == CONSTANT) {
3796 MaybeObject* maybe_map = transition_map->GeneralizeRepresentation( 3805 transition_map = Map::GeneralizeRepresentation(transition_map,
3797 descriptor, value->OptimalRepresentation(), FORCE_FIELD); 3806 descriptor, value->OptimalRepresentation(), FORCE_FIELD);
3798 if (!maybe_map->To(&transition_map)) return maybe_map;
3799 Object* back = transition_map->GetBackPointer(); 3807 Object* back = transition_map->GetBackPointer();
3800 if (back->IsMap()) { 3808 if (back->IsMap()) {
3801 MaybeObject* maybe_failure = 3809 MigrateToMap(object, handle(Map::cast(back)));
3802 lookup->holder()->MigrateToMap(Map::cast(back));
3803 if (maybe_failure->IsFailure()) return maybe_failure;
3804 } 3810 }
3805 descriptors = transition_map->instance_descriptors(); 3811 descriptors = transition_map->instance_descriptors();
3806 representation = descriptors->GetDetails(descriptor).representation(); 3812 representation = descriptors->GetDetails(descriptor).representation();
3807 } 3813 }
3808 3814
3809 int field_index = descriptors->GetFieldIndex(descriptor); 3815 int field_index = descriptors->GetFieldIndex(descriptor);
3810 return lookup->holder()->AddFastPropertyUsingMap( 3816 return AddFastPropertyUsingMap(
3811 transition_map, *name, *value, field_index, representation); 3817 object, transition_map, name, value, field_index, representation);
3812 } 3818 }
3813 3819
3814 3820
3815 static MaybeObject* SetPropertyToField(LookupResult* lookup, 3821 static Handle<Object> SetPropertyToField(LookupResult* lookup,
3816 Handle<Name> name, 3822 Handle<Name> name,
3817 Handle<Object> value) { 3823 Handle<Object> value) {
3818 Representation representation = lookup->representation(); 3824 Representation representation = lookup->representation();
3819 if (!value->FitsRepresentation(representation) || 3825 if (!value->FitsRepresentation(representation) ||
3820 lookup->type() == CONSTANT) { 3826 lookup->type() == CONSTANT) {
3821 MaybeObject* maybe_failure = 3827 JSObject::GeneralizeFieldRepresentation(handle(lookup->holder()),
3822 lookup->holder()->GeneralizeFieldRepresentation( 3828 lookup->GetDescriptorIndex(),
3823 lookup->GetDescriptorIndex(), 3829 value->OptimalRepresentation(),
3824 value->OptimalRepresentation(), 3830 FORCE_FIELD);
3825 FORCE_FIELD);
3826 if (maybe_failure->IsFailure()) return maybe_failure;
3827 DescriptorArray* desc = lookup->holder()->map()->instance_descriptors(); 3831 DescriptorArray* desc = lookup->holder()->map()->instance_descriptors();
3828 int descriptor = lookup->GetDescriptorIndex(); 3832 int descriptor = lookup->GetDescriptorIndex();
3829 representation = desc->GetDetails(descriptor).representation(); 3833 representation = desc->GetDetails(descriptor).representation();
3830 } 3834 }
3831 3835
3832 if (FLAG_track_double_fields && representation.IsDouble()) { 3836 if (FLAG_track_double_fields && representation.IsDouble()) {
3833 HeapNumber* storage = HeapNumber::cast(lookup->holder()->RawFastPropertyAt( 3837 HeapNumber* storage = HeapNumber::cast(lookup->holder()->RawFastPropertyAt(
3834 lookup->GetFieldIndex().field_index())); 3838 lookup->GetFieldIndex().field_index()));
3835 storage->set_value(value->Number()); 3839 storage->set_value(value->Number());
3836 return *value; 3840 return value;
3837 } 3841 }
3838 3842
3839 lookup->holder()->FastPropertyAtPut( 3843 lookup->holder()->FastPropertyAtPut(
3840 lookup->GetFieldIndex().field_index(), *value); 3844 lookup->GetFieldIndex().field_index(), *value);
3841 return *value; 3845 return value;
3842 } 3846 }
3843 3847
3844 3848
3845 static MaybeObject* ConvertAndSetLocalProperty(LookupResult* lookup, 3849 static Handle<Object> ConvertAndSetLocalProperty(
3846 Name* name, 3850 LookupResult* lookup,
3847 Object* value, 3851 Handle<Name> name,
3848 PropertyAttributes attributes) { 3852 Handle<Object> value,
3849 JSObject* object = lookup->holder(); 3853 PropertyAttributes attributes) {
3854 Handle<JSObject> object(lookup->holder());
3850 if (object->TooManyFastProperties()) { 3855 if (object->TooManyFastProperties()) {
3851 MaybeObject* maybe_failure = object->NormalizeProperties( 3856 JSObject::NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
3852 CLEAR_INOBJECT_PROPERTIES, 0);
3853 if (maybe_failure->IsFailure()) return maybe_failure;
3854 } 3857 }
3855 3858
3856 if (!object->HasFastProperties()) { 3859 if (!object->HasFastProperties()) {
3857 return object->ReplaceSlowProperty(name, value, attributes); 3860 return ReplaceSlowProperty(object, name, value, attributes);
3858 } 3861 }
3859 3862
3860 int descriptor_index = lookup->GetDescriptorIndex(); 3863 int descriptor_index = lookup->GetDescriptorIndex();
3861 if (lookup->GetAttributes() == attributes) { 3864 if (lookup->GetAttributes() == attributes) {
3862 MaybeObject* maybe_failure = object->GeneralizeFieldRepresentation( 3865 JSObject::GeneralizeFieldRepresentation(
3863 descriptor_index, Representation::Tagged(), FORCE_FIELD); 3866 object, descriptor_index, Representation::Tagged(), FORCE_FIELD);
3864 if (maybe_failure->IsFailure()) return maybe_failure;
3865 } else { 3867 } else {
3866 Map* map; 3868 Handle<Map> old_map(object->map());
3867 MaybeObject* maybe_map = object->map()->CopyGeneralizeAllRepresentations( 3869 Handle<Map> new_map = Map::CopyGeneralizeAllRepresentations(old_map,
3868 descriptor_index, FORCE_FIELD, attributes, "attributes mismatch"); 3870 descriptor_index, FORCE_FIELD, attributes, "attributes mismatch");
3869 if (!maybe_map->To(&map)) return maybe_map; 3871 JSObject::MigrateToMap(object, new_map);
3870 MaybeObject* maybe_failure = object->MigrateToMap(map);
3871 if (maybe_failure->IsFailure()) return maybe_failure;
3872 } 3872 }
3873 3873
3874 DescriptorArray* descriptors = object->map()->instance_descriptors(); 3874 DescriptorArray* descriptors = object->map()->instance_descriptors();
3875 int index = descriptors->GetDetails(descriptor_index).field_index(); 3875 int index = descriptors->GetDetails(descriptor_index).field_index();
3876 object->FastPropertyAtPut(index, value); 3876 object->FastPropertyAtPut(index, *value);
3877 return value; 3877 return value;
3878 } 3878 }
3879 3879
3880 3880
3881 static MaybeObject* SetPropertyToFieldWithAttributes( 3881 static Handle<Object> SetPropertyToFieldWithAttributes(
3882 LookupResult* lookup, 3882 LookupResult* lookup,
3883 Handle<Name> name, 3883 Handle<Name> name,
3884 Handle<Object> value, 3884 Handle<Object> value,
3885 PropertyAttributes attributes) { 3885 PropertyAttributes attributes) {
3886 if (lookup->GetAttributes() == attributes) { 3886 if (lookup->GetAttributes() == attributes) {
3887 if (value->IsUninitialized()) return *value; 3887 if (value->IsUninitialized()) return value;
3888 return SetPropertyToField(lookup, name, value); 3888 return SetPropertyToField(lookup, name, value);
3889 } else { 3889 } else {
3890 return ConvertAndSetLocalProperty(lookup, *name, *value, attributes); 3890 return ConvertAndSetLocalProperty(lookup, name, value, attributes);
3891 } 3891 }
3892 } 3892 }
3893 3893
3894 3894
3895 MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup, 3895 Handle<Object> JSObject::SetPropertyForResult(Handle<JSObject> object,
3896 Name* name_raw, 3896 LookupResult* lookup,
3897 Object* value_raw, 3897 Handle<Name> name,
3898 PropertyAttributes attributes, 3898 Handle<Object> value,
3899 StrictModeFlag strict_mode, 3899 PropertyAttributes attributes,
3900 StoreFromKeyed store_mode) { 3900 StrictModeFlag strict_mode,
3901 Heap* heap = GetHeap(); 3901 StoreFromKeyed store_mode) {
3902 Isolate* isolate = heap->isolate(); 3902 Isolate* isolate = object->GetIsolate();
3903 3903
3904 // Make sure that the top context does not change when doing callbacks or 3904 // Make sure that the top context does not change when doing callbacks or
3905 // interceptor calls. 3905 // interceptor calls.
3906 AssertNoContextChangeWithHandleScope ncc; 3906 AssertNoContextChange ncc;
3907 3907
3908 // Optimization for 2-byte strings often used as keys in a decompression 3908 // Optimization for 2-byte strings often used as keys in a decompression
3909 // dictionary. We internalize these short keys to avoid constantly 3909 // dictionary. We internalize these short keys to avoid constantly
3910 // reallocating them. 3910 // reallocating them.
3911 if (name_raw->IsString() && !name_raw->IsInternalizedString() && 3911 if (name->IsString() && !name->IsInternalizedString() &&
3912 String::cast(name_raw)->length() <= 2) { 3912 Handle<String>::cast(name)->length() <= 2) {
3913 Object* internalized_version; 3913 name = isolate->factory()->InternalizeString(Handle<String>::cast(name));
3914 { MaybeObject* maybe_string_version = 3914 }
3915 heap->InternalizeString(String::cast(name_raw)); 3915
3916 if (maybe_string_version->ToObject(&internalized_version)) { 3916 // Check access rights if needed.
3917 name_raw = String::cast(internalized_version); 3917 if (object->IsAccessCheckNeeded()) {
3918 } 3918 if (!isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) {
3919 CALL_HEAP_FUNCTION(
3920 isolate,
3921 object->SetPropertyWithFailedAccessCheck(
3922 lookup, *name, *value, true, strict_mode),
3923 Object);
3919 } 3924 }
3920 } 3925 }
3921 3926
3922 // Check access rights if needed. 3927 if (object->IsJSGlobalProxy()) {
3923 if (IsAccessCheckNeeded()) { 3928 Handle<Object> proto(object->GetPrototype(), isolate);
3924 if (!isolate->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) { 3929 if (proto->IsNull()) return value;
3925 return SetPropertyWithFailedAccessCheck( 3930 ASSERT(proto->IsJSGlobalObject());
3926 lookup, name_raw, value_raw, true, strict_mode); 3931 return SetPropertyForResult(Handle<JSObject>::cast(proto),
3927 } 3932 lookup, name, value, attributes, strict_mode, store_mode);
3928 } 3933 }
3929 3934
3930 if (IsJSGlobalProxy()) { 3935 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()); 3936 lookup->holder()->map()->is_hidden_prototype());
3940 3937
3941 // From this point on everything needs to be handlified, because 3938 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; 3939 bool done = false;
3950 MaybeObject* result_object = self->SetPropertyViaPrototypes( 3940 Handle<Object> result_object = SetPropertyViaPrototypes(
3951 *name, *value, attributes, strict_mode, &done); 3941 object, name, value, attributes, strict_mode, &done);
3952 if (done) return result_object; 3942 if (done) return result_object;
3953 } 3943 }
3954 3944
3955 if (!lookup->IsFound()) { 3945 if (!lookup->IsFound()) {
3956 // Neither properties nor transitions found. 3946 // Neither properties nor transitions found.
3957 return self->AddProperty( 3947 return AddProperty(
3958 *name, *value, attributes, strict_mode, store_mode); 3948 object, name, value, attributes, strict_mode, store_mode);
3959 } 3949 }
3960 3950
3961 if (lookup->IsProperty() && lookup->IsReadOnly()) { 3951 if (lookup->IsProperty() && lookup->IsReadOnly()) {
3962 if (strict_mode == kStrictMode) { 3952 if (strict_mode == kStrictMode) {
3963 Handle<Object> args[] = { name, self }; 3953 Handle<Object> args[] = { name, object };
3964 return isolate->Throw(*isolate->factory()->NewTypeError( 3954 Handle<Object> error = isolate->factory()->NewTypeError(
3965 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)))); 3955 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)));
3956 isolate->Throw(*error);
3957 return Handle<Object>();
3966 } else { 3958 } else {
3967 return *value; 3959 return value;
3968 } 3960 }
3969 } 3961 }
3970 3962
3971 Handle<Object> old_value(heap->the_hole_value(), isolate); 3963 Handle<Object> old_value = isolate->factory()->the_hole_value();
3972 if (FLAG_harmony_observation && 3964 if (FLAG_harmony_observation &&
3973 map()->is_observed() && lookup->IsDataProperty()) { 3965 object->map()->is_observed() && lookup->IsDataProperty()) {
3974 old_value = Object::GetProperty(self, name); 3966 old_value = Object::GetProperty(object, name);
3975 } 3967 }
3976 3968
3977 // This is a real property that is not read-only, or it is a 3969 // 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. 3970 // transition or null descriptor and there are no setters in the prototypes.
3979 MaybeObject* result = *value; 3971 Handle<Object> result = value;
3980 switch (lookup->type()) { 3972 switch (lookup->type()) {
3981 case NORMAL: 3973 case NORMAL:
3982 result = lookup->holder()->SetNormalizedProperty(lookup, *value); 3974 result = SetNormalizedProperty(handle(lookup->holder()), lookup, value);
3983 break; 3975 break;
3984 case FIELD: 3976 case FIELD:
3985 result = SetPropertyToField(lookup, name, value); 3977 result = SetPropertyToField(lookup, name, value);
3986 break; 3978 break;
3987 case CONSTANT: 3979 case CONSTANT:
3988 // Only replace the constant if necessary. 3980 // Only replace the constant if necessary.
3989 if (*value == lookup->GetConstant()) return *value; 3981 if (*value == lookup->GetConstant()) return value;
3990 result = SetPropertyToField(lookup, name, value); 3982 result = SetPropertyToField(lookup, name, value);
3991 break; 3983 break;
3992 case CALLBACKS: { 3984 case CALLBACKS: {
3993 Object* callback_object = lookup->GetCallbackObject(); 3985 Handle<Object> callback_object(lookup->GetCallbackObject(), isolate);
3994 return self->SetPropertyWithCallback( 3986 CALL_HEAP_FUNCTION(
3995 callback_object, *name, *value, lookup->holder(), strict_mode); 3987 isolate,
3988 object->SetPropertyWithCallback(*callback_object, *name, *value,
3989 lookup->holder(), strict_mode),
3990 Object);
3996 } 3991 }
3997 case INTERCEPTOR: 3992 case INTERCEPTOR:
3998 result = lookup->holder()->SetPropertyWithInterceptor( 3993 result = SetPropertyWithInterceptor(handle(lookup->holder()), name, value,
3999 *name, *value, attributes, strict_mode); 3994 attributes, strict_mode);
4000 break; 3995 break;
4001 case TRANSITION: { 3996 case TRANSITION:
4002 result = SetPropertyUsingTransition(lookup, name, value, attributes); 3997 result = SetPropertyUsingTransition(handle(lookup->holder()), lookup,
3998 name, value, attributes);
4003 break; 3999 break;
4004 }
4005 case HANDLER: 4000 case HANDLER:
4006 case NONEXISTENT: 4001 case NONEXISTENT:
4007 UNREACHABLE(); 4002 UNREACHABLE();
4008 } 4003 }
4009 4004
4010 Handle<Object> hresult; 4005 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<Object>());
4011 if (!result->ToHandle(&hresult, isolate)) return result;
4012 4006
4013 if (FLAG_harmony_observation && self->map()->is_observed()) { 4007 if (FLAG_harmony_observation && object->map()->is_observed()) {
4014 if (lookup->IsTransition()) { 4008 if (lookup->IsTransition()) {
4015 EnqueueChangeRecord(self, "new", name, old_value); 4009 EnqueueChangeRecord(object, "new", name, old_value);
4016 } else { 4010 } else {
4017 LookupResult new_lookup(isolate); 4011 LookupResult new_lookup(isolate);
4018 self->LocalLookup(*name, &new_lookup, true); 4012 object->LocalLookup(*name, &new_lookup, true);
4019 if (new_lookup.IsDataProperty()) { 4013 if (new_lookup.IsDataProperty()) {
4020 Handle<Object> new_value = Object::GetProperty(self, name); 4014 Handle<Object> new_value = Object::GetProperty(object, name);
4021 if (!new_value->SameValue(*old_value)) { 4015 if (!new_value->SameValue(*old_value)) {
4022 EnqueueChangeRecord(self, "updated", name, old_value); 4016 EnqueueChangeRecord(object, "updated", name, old_value);
4023 } 4017 }
4024 } 4018 }
4025 } 4019 }
4026 } 4020 }
4027 4021
4028 return *hresult; 4022 return result;
4029 } 4023 }
4030 4024
4031 4025
4032 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributesTrampoline( 4026 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributesTrampoline(
4033 Name* key, 4027 Name* key,
4034 Object* value, 4028 Object* value,
4035 PropertyAttributes attributes, 4029 PropertyAttributes attributes,
4036 ValueType value_type, 4030 ValueType value_type,
4037 StoreMode mode, 4031 StoreMode mode,
4038 ExtensibilityCheck extensibility_check) { 4032 ExtensibilityCheck extensibility_check) {
(...skipping 17 matching lines...) Expand all
4056 // present, add it with attributes NONE. This code is an exact clone of 4050 // 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 4051 // SetProperty, with the check for IsReadOnly and the check for a
4058 // callback setter removed. The two lines looking up the LookupResult 4052 // callback setter removed. The two lines looking up the LookupResult
4059 // result are also added. If one of the functions is changed, the other 4053 // result are also added. If one of the functions is changed, the other
4060 // should be. 4054 // should be.
4061 // Note that this method cannot be used to set the prototype of a function 4055 // Note that this method cannot be used to set the prototype of a function
4062 // because ConvertDescriptorToField() which is called in "case CALLBACKS:" 4056 // because ConvertDescriptorToField() which is called in "case CALLBACKS:"
4063 // doesn't handle function prototypes correctly. 4057 // doesn't handle function prototypes correctly.
4064 Handle<Object> JSObject::SetLocalPropertyIgnoreAttributes( 4058 Handle<Object> JSObject::SetLocalPropertyIgnoreAttributes(
4065 Handle<JSObject> object, 4059 Handle<JSObject> object,
4066 Handle<Name> key, 4060 Handle<Name> name,
4067 Handle<Object> value, 4061 Handle<Object> value,
4068 PropertyAttributes attributes, 4062 PropertyAttributes attributes,
4069 ValueType value_type, 4063 ValueType value_type,
4070 StoreMode mode, 4064 StoreMode mode,
4071 ExtensibilityCheck extensibility_check) { 4065 ExtensibilityCheck extensibility_check) {
4072 CALL_HEAP_FUNCTION( 4066 Isolate* isolate = object->GetIsolate();
4073 object->GetIsolate(),
4074 object->SetLocalPropertyIgnoreAttributes(
4075 *key, *value, attributes, value_type, mode, extensibility_check),
4076 Object);
4077 }
4078 4067
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 4068 // Make sure that the top context does not change when doing callbacks or
4088 // interceptor calls. 4069 // interceptor calls.
4089 AssertNoContextChangeWithHandleScope ncc; 4070 AssertNoContextChange ncc;
4090 Isolate* isolate = GetIsolate(); 4071
4091 LookupResult lookup(isolate); 4072 LookupResult lookup(isolate);
4092 LocalLookup(name_raw, &lookup, true); 4073 object->LocalLookup(*name, &lookup, true);
4093 if (!lookup.IsFound()) map()->LookupTransition(this, name_raw, &lookup); 4074 if (!lookup.IsFound()) {
4075 object->map()->LookupTransition(*object, *name, &lookup);
4076 }
4077
4094 // Check access rights if needed. 4078 // Check access rights if needed.
4095 if (IsAccessCheckNeeded()) { 4079 if (object->IsAccessCheckNeeded()) {
4096 if (!isolate->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) { 4080 if (!isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) {
4097 return SetPropertyWithFailedAccessCheck(&lookup, 4081 CALL_HEAP_FUNCTION(
4098 name_raw, 4082 isolate,
4099 value_raw, 4083 object->SetPropertyWithFailedAccessCheck(
4100 false, 4084 &lookup, *name, *value, false, kNonStrictMode),
4101 kNonStrictMode); 4085 Object);
4102 } 4086 }
4103 } 4087 }
4104 4088
4105 if (IsJSGlobalProxy()) { 4089 if (object->IsJSGlobalProxy()) {
4106 Object* proto = GetPrototype(); 4090 Handle<Object> proto(object->GetPrototype(), isolate);
4107 if (proto->IsNull()) return value_raw; 4091 if (proto->IsNull()) return value;
4108 ASSERT(proto->IsJSGlobalObject()); 4092 ASSERT(proto->IsJSGlobalObject());
4109 return JSObject::cast(proto)->SetLocalPropertyIgnoreAttributes( 4093 return SetLocalPropertyIgnoreAttributes(Handle<JSObject>::cast(proto),
4110 name_raw, 4094 name, value, attributes, value_type, mode, extensibility_check);
4111 value_raw,
4112 attributes,
4113 value_type,
4114 mode,
4115 extensibility_check);
4116 } 4095 }
4117 4096
4118 if (lookup.IsFound() && 4097 if (lookup.IsFound() &&
4119 (lookup.type() == INTERCEPTOR || lookup.type() == CALLBACKS)) { 4098 (lookup.type() == INTERCEPTOR || lookup.type() == CALLBACKS)) {
4120 LocalLookupRealNamedProperty(name_raw, &lookup); 4099 object->LocalLookupRealNamedProperty(*name, &lookup);
4121 } 4100 }
4122 4101
4123 // Check for accessor in prototype chain removed here in clone. 4102 // Check for accessor in prototype chain removed here in clone.
4124 if (!lookup.IsFound()) { 4103 if (!lookup.IsFound()) {
4125 // Neither properties nor transitions found. 4104 // Neither properties nor transitions found.
4126 return AddProperty( 4105 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); 4106 MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode);
4129 } 4107 }
4130 4108
4131 // From this point on everything needs to be handlified. 4109 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; 4110 PropertyAttributes old_attributes = ABSENT;
4139 bool is_observed = FLAG_harmony_observation && self->map()->is_observed(); 4111 bool is_observed = FLAG_harmony_observation && object->map()->is_observed();
4140 if (is_observed && lookup.IsProperty()) { 4112 if (is_observed && lookup.IsProperty()) {
4141 if (lookup.IsDataProperty()) old_value = 4113 if (lookup.IsDataProperty()) old_value =
4142 Object::GetProperty(self, name); 4114 Object::GetProperty(object, name);
4143 old_attributes = lookup.GetAttributes(); 4115 old_attributes = lookup.GetAttributes();
4144 } 4116 }
4145 4117
4146 // Check of IsReadOnly removed from here in clone. 4118 // Check of IsReadOnly removed from here in clone.
4147 MaybeObject* result = *value; 4119 Handle<Object> result = value;
4148 switch (lookup.type()) { 4120 switch (lookup.type()) {
4149 case NORMAL: 4121 case NORMAL:
4150 result = self->ReplaceSlowProperty(*name, *value, attributes); 4122 result = ReplaceSlowProperty(object, name, value, attributes);
4151 break; 4123 break;
4152 case FIELD: 4124 case FIELD:
4153 result = SetPropertyToFieldWithAttributes( 4125 result = SetPropertyToFieldWithAttributes(
4154 &lookup, name, value, attributes); 4126 &lookup, name, value, attributes);
4155 break; 4127 break;
4156 case CONSTANT: 4128 case CONSTANT:
4157 // Only replace the constant if necessary. 4129 // Only replace the constant if necessary.
4158 if (lookup.GetAttributes() != attributes || 4130 if (lookup.GetAttributes() != attributes ||
4159 *value != lookup.GetConstant()) { 4131 *value != lookup.GetConstant()) {
4160 result = SetPropertyToFieldWithAttributes( 4132 result = SetPropertyToFieldWithAttributes(
4161 &lookup, name, value, attributes); 4133 &lookup, name, value, attributes);
4162 } 4134 }
4163 break; 4135 break;
4164 case CALLBACKS: 4136 case CALLBACKS:
4165 result = ConvertAndSetLocalProperty(&lookup, *name, *value, attributes); 4137 result = ConvertAndSetLocalProperty(&lookup, name, value, attributes);
4166 break; 4138 break;
4167 case TRANSITION: 4139 case TRANSITION:
4168 result = SetPropertyUsingTransition(&lookup, name, value, attributes); 4140 result = SetPropertyUsingTransition(handle(lookup.holder()), &lookup,
4141 name, value, attributes);
4169 break; 4142 break;
4170 case NONEXISTENT: 4143 case NONEXISTENT:
4171 case HANDLER: 4144 case HANDLER:
4172 case INTERCEPTOR: 4145 case INTERCEPTOR:
4173 UNREACHABLE(); 4146 UNREACHABLE();
4174 } 4147 }
4175 4148
4176 Handle<Object> hresult; 4149 if (result.is_null()) return result;
4177 if (!result->ToHandle(&hresult, isolate)) return result;
4178 4150
4179 if (is_observed) { 4151 if (is_observed) {
4180 if (lookup.IsTransition()) { 4152 if (lookup.IsTransition()) {
4181 EnqueueChangeRecord(self, "new", name, old_value); 4153 EnqueueChangeRecord(object, "new", name, old_value);
4182 } else if (old_value->IsTheHole()) { 4154 } else if (old_value->IsTheHole()) {
4183 EnqueueChangeRecord(self, "reconfigured", name, old_value); 4155 EnqueueChangeRecord(object, "reconfigured", name, old_value);
4184 } else { 4156 } else {
4185 LookupResult new_lookup(isolate); 4157 LookupResult new_lookup(isolate);
4186 self->LocalLookup(*name, &new_lookup, true); 4158 object->LocalLookup(*name, &new_lookup, true);
4187 bool value_changed = false; 4159 bool value_changed = false;
4188 if (new_lookup.IsDataProperty()) { 4160 if (new_lookup.IsDataProperty()) {
4189 Handle<Object> new_value = Object::GetProperty(self, name); 4161 Handle<Object> new_value = Object::GetProperty(object, name);
4190 value_changed = !old_value->SameValue(*new_value); 4162 value_changed = !old_value->SameValue(*new_value);
4191 } 4163 }
4192 if (new_lookup.GetAttributes() != old_attributes) { 4164 if (new_lookup.GetAttributes() != old_attributes) {
4193 if (!value_changed) old_value = isolate->factory()->the_hole_value(); 4165 if (!value_changed) old_value = isolate->factory()->the_hole_value();
4194 EnqueueChangeRecord(self, "reconfigured", name, old_value); 4166 EnqueueChangeRecord(object, "reconfigured", name, old_value);
4195 } else if (value_changed) { 4167 } else if (value_changed) {
4196 EnqueueChangeRecord(self, "updated", name, old_value); 4168 EnqueueChangeRecord(object, "updated", name, old_value);
4197 } 4169 }
4198 } 4170 }
4199 } 4171 }
4200 4172
4201 return *hresult; 4173 return result;
4202 } 4174 }
4203 4175
4204 4176
4205 PropertyAttributes JSObject::GetPropertyAttributePostInterceptor( 4177 PropertyAttributes JSObject::GetPropertyAttributePostInterceptor(
4206 JSObject* receiver, 4178 JSObject* receiver,
4207 Name* name, 4179 Name* name,
4208 bool continue_search) { 4180 bool continue_search) {
4209 // Check local property, ignore interceptor. 4181 // Check local property, ignore interceptor.
4210 LookupResult result(GetIsolate()); 4182 LookupResult result(GetIsolate());
4211 LocalLookupRealNamedProperty(name, &result); 4183 LocalLookupRealNamedProperty(name, &result);
(...skipping 2471 matching lines...) Expand 10 before | Expand all | Expand 10 after
6683 set_transitions(transitions); 6655 set_transitions(transitions);
6684 result->SetBackPointer(this); 6656 result->SetBackPointer(this);
6685 } else { 6657 } else {
6686 descriptors->InitializeRepresentations(Representation::Tagged()); 6658 descriptors->InitializeRepresentations(Representation::Tagged());
6687 } 6659 }
6688 6660
6689 return result; 6661 return result;
6690 } 6662 }
6691 6663
6692 6664
6665 Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map,
6666 int new_descriptor,
6667 Handle<DescriptorArray> descriptors) {
6668 CALL_HEAP_FUNCTION(map->GetIsolate(),
6669 map->CopyInstallDescriptors(new_descriptor, *descriptors),
6670 Map);
6671 }
6672
6673
6693 // Since this method is used to rewrite an existing transition tree, it can 6674 // Since this method is used to rewrite an existing transition tree, it can
6694 // always insert transitions without checking. 6675 // always insert transitions without checking.
6695 MaybeObject* Map::CopyInstallDescriptors(int new_descriptor, 6676 MaybeObject* Map::CopyInstallDescriptors(int new_descriptor,
6696 DescriptorArray* descriptors) { 6677 DescriptorArray* descriptors) {
6697 ASSERT(descriptors->IsSortedNoDuplicates()); 6678 ASSERT(descriptors->IsSortedNoDuplicates());
6698 6679
6699 Map* result; 6680 Map* result;
6700 MaybeObject* maybe_result = CopyDropDescriptors(); 6681 MaybeObject* maybe_result = CopyDropDescriptors();
6701 if (!maybe_result->To(&result)) return maybe_result; 6682 if (!maybe_result->To(&result)) return maybe_result;
6702 6683
(...skipping 1092 matching lines...) Expand 10 before | Expand all | Expand 10 after
7795 DescriptorArray* src, 7776 DescriptorArray* src,
7796 int src_index, 7777 int src_index,
7797 const WhitenessWitness& witness) { 7778 const WhitenessWitness& witness) {
7798 Object* value = src->GetValue(src_index); 7779 Object* value = src->GetValue(src_index);
7799 PropertyDetails details = src->GetDetails(src_index); 7780 PropertyDetails details = src->GetDetails(src_index);
7800 Descriptor desc(src->GetKey(src_index), value, details); 7781 Descriptor desc(src->GetKey(src_index), value, details);
7801 Set(dst_index, &desc, witness); 7782 Set(dst_index, &desc, witness);
7802 } 7783 }
7803 7784
7804 7785
7786 Handle<DescriptorArray> DescriptorArray::Merge(Handle<DescriptorArray> desc,
7787 int verbatim,
7788 int valid,
7789 int new_size,
7790 int modify_index,
7791 StoreMode store_mode,
7792 Handle<DescriptorArray> other) {
7793 CALL_HEAP_FUNCTION(desc->GetIsolate(),
7794 desc->Merge(verbatim, valid, new_size, modify_index,
7795 store_mode, *other),
7796 DescriptorArray);
7797 }
7798
7799
7805 // Generalize the |other| descriptor array by merging it into the (at least 7800 // Generalize the |other| descriptor array by merging it into the (at least
7806 // partly) updated |this| descriptor array. 7801 // partly) updated |this| descriptor array.
7807 // The method merges two descriptor array in three parts. Both descriptor arrays 7802 // 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|. 7803 // 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 7804 // Between |verbatim| and |valid|, the resulting descriptor type as well as the
7810 // representation are generalized from both |this| and |other|. Beyond |valid|, 7805 // representation are generalized from both |this| and |other|. Beyond |valid|,
7811 // the descriptors are copied verbatim from |other| up to |new_size|. 7806 // the descriptors are copied verbatim from |other| up to |new_size|.
7812 // In case of incompatible types, the type and representation of |other| is 7807 // In case of incompatible types, the type and representation of |other| is
7813 // used. 7808 // used.
7814 MaybeObject* DescriptorArray::Merge(int verbatim, 7809 MaybeObject* DescriptorArray::Merge(int verbatim,
(...skipping 6698 matching lines...) Expand 10 before | Expand all | Expand 10 after
14513 } 14508 }
14514 14509
14515 14510
14516 PropertyCell* GlobalObject::GetPropertyCell(LookupResult* result) { 14511 PropertyCell* GlobalObject::GetPropertyCell(LookupResult* result) {
14517 ASSERT(!HasFastProperties()); 14512 ASSERT(!HasFastProperties());
14518 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); 14513 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry());
14519 return PropertyCell::cast(value); 14514 return PropertyCell::cast(value);
14520 } 14515 }
14521 14516
14522 14517
14523 // TODO(mstarzinger): Temporary wrapper until handlified.
14524 static Handle<NameDictionary> NameDictionaryAdd(Handle<NameDictionary> dict,
14525 Handle<Name> name,
14526 Handle<Object> value,
14527 PropertyDetails details) {
14528 CALL_HEAP_FUNCTION(dict->GetIsolate(),
14529 dict->Add(*name, *value, details),
14530 NameDictionary);
14531 }
14532
14533
14534 Handle<PropertyCell> GlobalObject::EnsurePropertyCell( 14518 Handle<PropertyCell> GlobalObject::EnsurePropertyCell(
14535 Handle<GlobalObject> global, 14519 Handle<GlobalObject> global,
14536 Handle<Name> name) { 14520 Handle<Name> name) {
14537 ASSERT(!global->HasFastProperties()); 14521 ASSERT(!global->HasFastProperties());
14538 int entry = global->property_dictionary()->FindEntry(*name); 14522 int entry = global->property_dictionary()->FindEntry(*name);
14539 if (entry == NameDictionary::kNotFound) { 14523 if (entry == NameDictionary::kNotFound) {
14540 Isolate* isolate = global->GetIsolate(); 14524 Isolate* isolate = global->GetIsolate();
14541 Handle<PropertyCell> cell = isolate->factory()->NewPropertyCell( 14525 Handle<PropertyCell> cell = isolate->factory()->NewPropertyCell(
14542 isolate->factory()->the_hole_value()); 14526 isolate->factory()->the_hole_value());
14543 PropertyDetails details(NONE, NORMAL, 0); 14527 PropertyDetails details(NONE, NORMAL, 0);
(...skipping 1558 matching lines...) Expand 10 before | Expand all | Expand 10 after
16102 isolate, DependentCode::kPropertyCellChangedGroup); 16086 isolate, DependentCode::kPropertyCellChangedGroup);
16103 16087
16104 if (old_type->Is(Type::None()) || old_type->Is(Type::Undefined())) { 16088 if (old_type->Is(Type::None()) || old_type->Is(Type::Undefined())) {
16105 return *new_type; 16089 return *new_type;
16106 } 16090 }
16107 16091
16108 return Type::Any(); 16092 return Type::Any();
16109 } 16093 }
16110 16094
16111 16095
16096 void PropertyCell::SetValueInferType(Handle<PropertyCell> cell,
16097 Handle<Object> value,
16098 WriteBarrierMode mode) {
16099 CALL_HEAP_FUNCTION_VOID(cell->GetIsolate(),
16100 cell->SetValueInferType(*value, mode));
16101 }
16102
16103
16112 MaybeObject* PropertyCell::SetValueInferType(Object* value, 16104 MaybeObject* PropertyCell::SetValueInferType(Object* value,
16113 WriteBarrierMode ignored) { 16105 WriteBarrierMode ignored) {
16114 set_value(value, ignored); 16106 set_value(value, ignored);
16115 if (!Type::Any()->Is(type())) { 16107 if (!Type::Any()->Is(type())) {
16116 IdempotentPointerToHandleCodeTrampoline trampoline(GetIsolate()); 16108 IdempotentPointerToHandleCodeTrampoline trampoline(GetIsolate());
16117 MaybeObject* maybe_type = trampoline.CallWithReturnValue( 16109 MaybeObject* maybe_type = trampoline.CallWithReturnValue(
16118 &PropertyCell::UpdateType, 16110 &PropertyCell::UpdateType,
16119 Handle<PropertyCell>(this), 16111 Handle<PropertyCell>(this),
16120 Handle<Object>(value, GetIsolate())); 16112 Handle<Object>(value, GetIsolate()));
16121 Type* new_type = NULL; 16113 Type* new_type = NULL;
(...skipping 28 matching lines...) Expand all
16150 #define ERROR_MESSAGES_TEXTS(C, T) T, 16142 #define ERROR_MESSAGES_TEXTS(C, T) T,
16151 static const char* error_messages_[] = { 16143 static const char* error_messages_[] = {
16152 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16144 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16153 }; 16145 };
16154 #undef ERROR_MESSAGES_TEXTS 16146 #undef ERROR_MESSAGES_TEXTS
16155 return error_messages_[reason]; 16147 return error_messages_[reason];
16156 } 16148 }
16157 16149
16158 16150
16159 } } // namespace v8::internal 16151 } } // 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