OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/api.h" | 8 #include "src/api.h" |
9 #include "src/arguments.h" | 9 #include "src/arguments.h" |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 1527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1538 Object::SetProperty(object, name, value, language_mode()), Object); | 1538 Object::SetProperty(object, name, value, language_mode()), Object); |
1539 return result; | 1539 return result; |
1540 } | 1540 } |
1541 | 1541 |
1542 // If the object is undefined or null it's illegal to try to set any | 1542 // If the object is undefined or null it's illegal to try to set any |
1543 // properties on it; throw a TypeError in that case. | 1543 // properties on it; throw a TypeError in that case. |
1544 if (object->IsUndefined() || object->IsNull()) { | 1544 if (object->IsUndefined() || object->IsNull()) { |
1545 return TypeError(MessageTemplate::kNonObjectPropertyStore, object, name); | 1545 return TypeError(MessageTemplate::kNonObjectPropertyStore, object, name); |
1546 } | 1546 } |
1547 | 1547 |
1548 // Check if the given name is an array index. | |
1549 uint32_t index; | |
1550 if (name->AsArrayIndex(&index)) { | |
1551 // Ignore other stores where the receiver is not a JSObject. | |
1552 // TODO(1475): Must check prototype chains of object wrappers. | |
1553 if (!object->IsJSObject()) return value; | |
1554 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | |
1555 | |
1556 Handle<Object> result; | |
1557 ASSIGN_RETURN_ON_EXCEPTION( | |
1558 isolate(), result, | |
1559 Object::SetElement(isolate(), receiver, index, value, language_mode()), | |
1560 Object); | |
1561 return value; | |
1562 } | |
1563 | |
1564 // Observed objects are always modified through the runtime. | 1548 // Observed objects are always modified through the runtime. |
1565 if (object->IsHeapObject() && | 1549 if (object->IsHeapObject() && |
1566 Handle<HeapObject>::cast(object)->map()->is_observed()) { | 1550 Handle<HeapObject>::cast(object)->map()->is_observed()) { |
1567 Handle<Object> result; | 1551 Handle<Object> result; |
1568 ASSIGN_RETURN_ON_EXCEPTION( | 1552 ASSIGN_RETURN_ON_EXCEPTION( |
1569 isolate(), result, | 1553 isolate(), result, |
1570 Object::SetProperty(object, name, value, language_mode(), store_mode), | 1554 Object::SetProperty(object, name, value, language_mode(), store_mode), |
1571 Object); | 1555 Object); |
1572 return result; | 1556 return result; |
1573 } | 1557 } |
(...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2109 return result; | 2093 return result; |
2110 } | 2094 } |
2111 | 2095 |
2112 // Check for non-string values that can be converted into an | 2096 // Check for non-string values that can be converted into an |
2113 // internalized string directly or is representable as a smi. | 2097 // internalized string directly or is representable as a smi. |
2114 key = TryConvertKey(key, isolate()); | 2098 key = TryConvertKey(key, isolate()); |
2115 | 2099 |
2116 Handle<Object> store_handle; | 2100 Handle<Object> store_handle; |
2117 Handle<Code> stub = megamorphic_stub(); | 2101 Handle<Code> stub = megamorphic_stub(); |
2118 | 2102 |
2119 if (key->IsInternalizedString() || key->IsSymbol()) { | 2103 uint32_t index; |
| 2104 if ((key->IsInternalizedString() && |
| 2105 !String::cast(*key)->AsArrayIndex(&index)) || |
| 2106 key->IsSymbol()) { |
2120 ASSIGN_RETURN_ON_EXCEPTION( | 2107 ASSIGN_RETURN_ON_EXCEPTION( |
2121 isolate(), store_handle, | 2108 isolate(), store_handle, |
2122 StoreIC::Store(object, Handle<Name>::cast(key), value, | 2109 StoreIC::Store(object, Handle<Name>::cast(key), value, |
2123 JSReceiver::MAY_BE_STORE_FROM_KEYED), | 2110 JSReceiver::MAY_BE_STORE_FROM_KEYED), |
2124 Object); | 2111 Object); |
2125 if (FLAG_vector_stores) { | 2112 if (FLAG_vector_stores) { |
2126 if (!is_vector_set()) { | 2113 if (!is_vector_set()) { |
2127 ConfigureVectorState(MEGAMORPHIC); | 2114 ConfigureVectorState(MEGAMORPHIC); |
2128 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", | 2115 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", |
2129 "unhandled internalized string key"); | 2116 "unhandled internalized string key"); |
(...skipping 19 matching lines...) Expand all Loading... |
2149 // expect to be able to trap element sets to objects with those maps in | 2136 // expect to be able to trap element sets to objects with those maps in |
2150 // the runtime to enable optimization of element hole access. | 2137 // the runtime to enable optimization of element hole access. |
2151 Handle<HeapObject> heap_object = Handle<HeapObject>::cast(object); | 2138 Handle<HeapObject> heap_object = Handle<HeapObject>::cast(object); |
2152 if (heap_object->map()->IsMapInArrayPrototypeChain()) { | 2139 if (heap_object->map()->IsMapInArrayPrototypeChain()) { |
2153 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "map in array prototype"); | 2140 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "map in array prototype"); |
2154 use_ic = false; | 2141 use_ic = false; |
2155 } | 2142 } |
2156 } | 2143 } |
2157 | 2144 |
2158 if (use_ic) { | 2145 if (use_ic) { |
2159 DCHECK(!object->IsAccessCheckNeeded()); | |
2160 | |
2161 if (object->IsJSObject()) { | 2146 if (object->IsJSObject()) { |
2162 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | 2147 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
2163 bool key_is_smi_like = !Object::ToSmi(isolate(), key).is_null(); | 2148 bool key_is_smi_like = !Object::ToSmi(isolate(), key).is_null(); |
2164 if (receiver->elements()->map() == | 2149 if (receiver->elements()->map() == |
2165 isolate()->heap()->sloppy_arguments_elements_map() && | 2150 isolate()->heap()->sloppy_arguments_elements_map() && |
2166 !is_sloppy(language_mode())) { | 2151 !is_sloppy(language_mode())) { |
2167 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "arguments receiver"); | 2152 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "arguments receiver"); |
2168 } else if (key_is_smi_like) { | 2153 } else if (key_is_smi_like) { |
2169 // We should go generic if receiver isn't a dictionary, but our | 2154 // We should go generic if receiver isn't a dictionary, but our |
2170 // prototype chain does have dictionary elements. This ensures that | 2155 // prototype chain does have dictionary elements. This ensures that |
(...skipping 934 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3105 static const Address IC_utilities[] = { | 3090 static const Address IC_utilities[] = { |
3106 #define ADDR(name) FUNCTION_ADDR(name), | 3091 #define ADDR(name) FUNCTION_ADDR(name), |
3107 IC_UTIL_LIST(ADDR) NULL | 3092 IC_UTIL_LIST(ADDR) NULL |
3108 #undef ADDR | 3093 #undef ADDR |
3109 }; | 3094 }; |
3110 | 3095 |
3111 | 3096 |
3112 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } | 3097 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } |
3113 } // namespace internal | 3098 } // namespace internal |
3114 } // namespace v8 | 3099 } // namespace v8 |
OLD | NEW |