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

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

Powered by Google App Engine
This is Rietveld 408576698