| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 1753 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1764 StrictModeFlag strict_mode) { | 1764 StrictModeFlag strict_mode) { |
| 1765 LookupResult result; | 1765 LookupResult result; |
| 1766 LocalLookup(name, &result); | 1766 LocalLookup(name, &result); |
| 1767 return SetProperty(&result, name, value, attributes, strict_mode); | 1767 return SetProperty(&result, name, value, attributes, strict_mode); |
| 1768 } | 1768 } |
| 1769 | 1769 |
| 1770 | 1770 |
| 1771 MaybeObject* JSObject::SetPropertyWithCallback(Object* structure, | 1771 MaybeObject* JSObject::SetPropertyWithCallback(Object* structure, |
| 1772 String* name, | 1772 String* name, |
| 1773 Object* value, | 1773 Object* value, |
| 1774 JSObject* holder) { | 1774 JSObject* holder, |
| 1775 StrictModeFlag strict_mode) { |
| 1775 Isolate* isolate = GetIsolate(); | 1776 Isolate* isolate = GetIsolate(); |
| 1776 HandleScope scope(isolate); | 1777 HandleScope scope(isolate); |
| 1777 | 1778 |
| 1778 // We should never get here to initialize a const with the hole | 1779 // We should never get here to initialize a const with the hole |
| 1779 // value since a const declaration would conflict with the setter. | 1780 // value since a const declaration would conflict with the setter. |
| 1780 ASSERT(!value->IsTheHole()); | 1781 ASSERT(!value->IsTheHole()); |
| 1781 Handle<Object> value_handle(value, isolate); | 1782 Handle<Object> value_handle(value, isolate); |
| 1782 | 1783 |
| 1783 // To accommodate both the old and the new api we switch on the | 1784 // To accommodate both the old and the new api we switch on the |
| 1784 // data structure used to store the callbacks. Eventually foreign | 1785 // data structure used to store the callbacks. Eventually foreign |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1812 } | 1813 } |
| 1813 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 1814 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 1814 return *value_handle; | 1815 return *value_handle; |
| 1815 } | 1816 } |
| 1816 | 1817 |
| 1817 if (structure->IsFixedArray()) { | 1818 if (structure->IsFixedArray()) { |
| 1818 Object* setter = FixedArray::cast(structure)->get(kSetterIndex); | 1819 Object* setter = FixedArray::cast(structure)->get(kSetterIndex); |
| 1819 if (setter->IsJSFunction()) { | 1820 if (setter->IsJSFunction()) { |
| 1820 return SetPropertyWithDefinedSetter(JSFunction::cast(setter), value); | 1821 return SetPropertyWithDefinedSetter(JSFunction::cast(setter), value); |
| 1821 } else { | 1822 } else { |
| 1823 if (strict_mode == kNonStrictMode) { |
| 1824 return value; |
| 1825 } |
| 1822 Handle<String> key(name); | 1826 Handle<String> key(name); |
| 1823 Handle<Object> holder_handle(holder, isolate); | 1827 Handle<Object> holder_handle(holder, isolate); |
| 1824 Handle<Object> args[2] = { key, holder_handle }; | 1828 Handle<Object> args[2] = { key, holder_handle }; |
| 1825 return isolate->Throw( | 1829 return isolate->Throw( |
| 1826 *isolate->factory()->NewTypeError("no_setter_in_callback", | 1830 *isolate->factory()->NewTypeError("no_setter_in_callback", |
| 1827 HandleVector(args, 2))); | 1831 HandleVector(args, 2))); |
| 1828 } | 1832 } |
| 1829 } | 1833 } |
| 1830 | 1834 |
| 1831 UNREACHABLE(); | 1835 UNREACHABLE(); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1869 } | 1873 } |
| 1870 if (result->type() == CALLBACKS) { | 1874 if (result->type() == CALLBACKS) { |
| 1871 return; | 1875 return; |
| 1872 } | 1876 } |
| 1873 } | 1877 } |
| 1874 } | 1878 } |
| 1875 result->NotFound(); | 1879 result->NotFound(); |
| 1876 } | 1880 } |
| 1877 | 1881 |
| 1878 | 1882 |
| 1879 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes(uint32_t index, | 1883 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes( |
| 1880 Object* value, | 1884 uint32_t index, |
| 1881 bool* found) { | 1885 Object* value, |
| 1886 bool* found, |
| 1887 StrictModeFlag strict_mode) { |
| 1882 Heap* heap = GetHeap(); | 1888 Heap* heap = GetHeap(); |
| 1883 for (Object* pt = GetPrototype(); | 1889 for (Object* pt = GetPrototype(); |
| 1884 pt != heap->null_value(); | 1890 pt != heap->null_value(); |
| 1885 pt = pt->GetPrototype()) { | 1891 pt = pt->GetPrototype()) { |
| 1886 if (!JSObject::cast(pt)->HasDictionaryElements()) { | 1892 if (!JSObject::cast(pt)->HasDictionaryElements()) { |
| 1887 continue; | 1893 continue; |
| 1888 } | 1894 } |
| 1889 NumberDictionary* dictionary = JSObject::cast(pt)->element_dictionary(); | 1895 NumberDictionary* dictionary = JSObject::cast(pt)->element_dictionary(); |
| 1890 int entry = dictionary->FindEntry(index); | 1896 int entry = dictionary->FindEntry(index); |
| 1891 if (entry != NumberDictionary::kNotFound) { | 1897 if (entry != NumberDictionary::kNotFound) { |
| 1892 PropertyDetails details = dictionary->DetailsAt(entry); | 1898 PropertyDetails details = dictionary->DetailsAt(entry); |
| 1893 if (details.type() == CALLBACKS) { | 1899 if (details.type() == CALLBACKS) { |
| 1894 *found = true; | 1900 *found = true; |
| 1895 return SetElementWithCallback( | 1901 return SetElementWithCallback(dictionary->ValueAt(entry), |
| 1896 dictionary->ValueAt(entry), index, value, JSObject::cast(pt)); | 1902 index, |
| 1903 value, |
| 1904 JSObject::cast(pt), |
| 1905 strict_mode); |
| 1897 } | 1906 } |
| 1898 } | 1907 } |
| 1899 } | 1908 } |
| 1900 *found = false; | 1909 *found = false; |
| 1901 return heap->the_hole_value(); | 1910 return heap->the_hole_value(); |
| 1902 } | 1911 } |
| 1903 | 1912 |
| 1904 | 1913 |
| 1905 void JSObject::LookupInDescriptor(String* name, LookupResult* result) { | 1914 void JSObject::LookupInDescriptor(String* name, LookupResult* result) { |
| 1906 DescriptorArray* descriptors = map()->instance_descriptors(); | 1915 DescriptorArray* descriptors = map()->instance_descriptors(); |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2067 pt != heap->null_value(); | 2076 pt != heap->null_value(); |
| 2068 pt = JSObject::cast(pt)->GetPrototype()) { | 2077 pt = JSObject::cast(pt)->GetPrototype()) { |
| 2069 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); | 2078 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); |
| 2070 if (result->IsProperty() && (result->type() != INTERCEPTOR)) return; | 2079 if (result->IsProperty() && (result->type() != INTERCEPTOR)) return; |
| 2071 } | 2080 } |
| 2072 result->NotFound(); | 2081 result->NotFound(); |
| 2073 } | 2082 } |
| 2074 | 2083 |
| 2075 | 2084 |
| 2076 // We only need to deal with CALLBACKS and INTERCEPTORS | 2085 // We only need to deal with CALLBACKS and INTERCEPTORS |
| 2077 MaybeObject* JSObject::SetPropertyWithFailedAccessCheck(LookupResult* result, | 2086 MaybeObject* JSObject::SetPropertyWithFailedAccessCheck( |
| 2078 String* name, | 2087 LookupResult* result, |
| 2079 Object* value, | 2088 String* name, |
| 2080 bool check_prototype) { | 2089 Object* value, |
| 2090 bool check_prototype, |
| 2091 StrictModeFlag strict_mode) { |
| 2081 if (check_prototype && !result->IsProperty()) { | 2092 if (check_prototype && !result->IsProperty()) { |
| 2082 LookupCallbackSetterInPrototypes(name, result); | 2093 LookupCallbackSetterInPrototypes(name, result); |
| 2083 } | 2094 } |
| 2084 | 2095 |
| 2085 if (result->IsProperty()) { | 2096 if (result->IsProperty()) { |
| 2086 if (!result->IsReadOnly()) { | 2097 if (!result->IsReadOnly()) { |
| 2087 switch (result->type()) { | 2098 switch (result->type()) { |
| 2088 case CALLBACKS: { | 2099 case CALLBACKS: { |
| 2089 Object* obj = result->GetCallbackObject(); | 2100 Object* obj = result->GetCallbackObject(); |
| 2090 if (obj->IsAccessorInfo()) { | 2101 if (obj->IsAccessorInfo()) { |
| 2091 AccessorInfo* info = AccessorInfo::cast(obj); | 2102 AccessorInfo* info = AccessorInfo::cast(obj); |
| 2092 if (info->all_can_write()) { | 2103 if (info->all_can_write()) { |
| 2093 return SetPropertyWithCallback(result->GetCallbackObject(), | 2104 return SetPropertyWithCallback(result->GetCallbackObject(), |
| 2094 name, | 2105 name, |
| 2095 value, | 2106 value, |
| 2096 result->holder()); | 2107 result->holder(), |
| 2108 strict_mode); |
| 2097 } | 2109 } |
| 2098 } | 2110 } |
| 2099 break; | 2111 break; |
| 2100 } | 2112 } |
| 2101 case INTERCEPTOR: { | 2113 case INTERCEPTOR: { |
| 2102 // Try lookup real named properties. Note that only property can be | 2114 // Try lookup real named properties. Note that only property can be |
| 2103 // set is callbacks marked as ALL_CAN_WRITE on the prototype chain. | 2115 // set is callbacks marked as ALL_CAN_WRITE on the prototype chain. |
| 2104 LookupResult r; | 2116 LookupResult r; |
| 2105 LookupRealNamedProperty(name, &r); | 2117 LookupRealNamedProperty(name, &r); |
| 2106 if (r.IsProperty()) { | 2118 if (r.IsProperty()) { |
| 2107 return SetPropertyWithFailedAccessCheck(&r, name, value, | 2119 return SetPropertyWithFailedAccessCheck(&r, |
| 2108 check_prototype); | 2120 name, |
| 2121 value, |
| 2122 check_prototype, |
| 2123 strict_mode); |
| 2109 } | 2124 } |
| 2110 break; | 2125 break; |
| 2111 } | 2126 } |
| 2112 default: { | 2127 default: { |
| 2113 break; | 2128 break; |
| 2114 } | 2129 } |
| 2115 } | 2130 } |
| 2116 } | 2131 } |
| 2117 } | 2132 } |
| 2118 | 2133 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2142 { MaybeObject* maybe_symbol_version = heap->LookupSymbol(name); | 2157 { MaybeObject* maybe_symbol_version = heap->LookupSymbol(name); |
| 2143 if (maybe_symbol_version->ToObject(&symbol_version)) { | 2158 if (maybe_symbol_version->ToObject(&symbol_version)) { |
| 2144 name = String::cast(symbol_version); | 2159 name = String::cast(symbol_version); |
| 2145 } | 2160 } |
| 2146 } | 2161 } |
| 2147 } | 2162 } |
| 2148 | 2163 |
| 2149 // Check access rights if needed. | 2164 // Check access rights if needed. |
| 2150 if (IsAccessCheckNeeded() | 2165 if (IsAccessCheckNeeded() |
| 2151 && !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_SET)) { | 2166 && !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_SET)) { |
| 2152 return SetPropertyWithFailedAccessCheck(result, name, value, true); | 2167 return SetPropertyWithFailedAccessCheck(result, |
| 2168 name, |
| 2169 value, |
| 2170 true, |
| 2171 strict_mode); |
| 2153 } | 2172 } |
| 2154 | 2173 |
| 2155 if (IsJSGlobalProxy()) { | 2174 if (IsJSGlobalProxy()) { |
| 2156 Object* proto = GetPrototype(); | 2175 Object* proto = GetPrototype(); |
| 2157 if (proto->IsNull()) return value; | 2176 if (proto->IsNull()) return value; |
| 2158 ASSERT(proto->IsJSGlobalObject()); | 2177 ASSERT(proto->IsJSGlobalObject()); |
| 2159 return JSObject::cast(proto)->SetProperty( | 2178 return JSObject::cast(proto)->SetProperty( |
| 2160 result, name, value, attributes, strict_mode); | 2179 result, name, value, attributes, strict_mode); |
| 2161 } | 2180 } |
| 2162 | 2181 |
| 2163 if (!result->IsProperty() && !IsJSContextExtensionObject()) { | 2182 if (!result->IsProperty() && !IsJSContextExtensionObject()) { |
| 2164 // We could not find a local property so let's check whether there is an | 2183 // We could not find a local property so let's check whether there is an |
| 2165 // accessor that wants to handle the property. | 2184 // accessor that wants to handle the property. |
| 2166 LookupResult accessor_result; | 2185 LookupResult accessor_result; |
| 2167 LookupCallbackSetterInPrototypes(name, &accessor_result); | 2186 LookupCallbackSetterInPrototypes(name, &accessor_result); |
| 2168 if (accessor_result.IsProperty()) { | 2187 if (accessor_result.IsProperty()) { |
| 2169 return SetPropertyWithCallback(accessor_result.GetCallbackObject(), | 2188 return SetPropertyWithCallback(accessor_result.GetCallbackObject(), |
| 2170 name, | 2189 name, |
| 2171 value, | 2190 value, |
| 2172 accessor_result.holder()); | 2191 accessor_result.holder(), |
| 2192 strict_mode); |
| 2173 } | 2193 } |
| 2174 } | 2194 } |
| 2175 if (!result->IsFound()) { | 2195 if (!result->IsFound()) { |
| 2176 // Neither properties nor transitions found. | 2196 // Neither properties nor transitions found. |
| 2177 return AddProperty(name, value, attributes, strict_mode); | 2197 return AddProperty(name, value, attributes, strict_mode); |
| 2178 } | 2198 } |
| 2179 if (result->IsReadOnly() && result->IsProperty()) { | 2199 if (result->IsReadOnly() && result->IsProperty()) { |
| 2180 if (strict_mode == kStrictMode) { | 2200 if (strict_mode == kStrictMode) { |
| 2181 HandleScope scope; | 2201 HandleScope scope; |
| 2182 Handle<String> key(name); | 2202 Handle<String> key(name); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2206 case CONSTANT_FUNCTION: | 2226 case CONSTANT_FUNCTION: |
| 2207 // Only replace the function if necessary. | 2227 // Only replace the function if necessary. |
| 2208 if (value == result->GetConstantFunction()) return value; | 2228 if (value == result->GetConstantFunction()) return value; |
| 2209 // Preserve the attributes of this existing property. | 2229 // Preserve the attributes of this existing property. |
| 2210 attributes = result->GetAttributes(); | 2230 attributes = result->GetAttributes(); |
| 2211 return ConvertDescriptorToField(name, value, attributes); | 2231 return ConvertDescriptorToField(name, value, attributes); |
| 2212 case CALLBACKS: | 2232 case CALLBACKS: |
| 2213 return SetPropertyWithCallback(result->GetCallbackObject(), | 2233 return SetPropertyWithCallback(result->GetCallbackObject(), |
| 2214 name, | 2234 name, |
| 2215 value, | 2235 value, |
| 2216 result->holder()); | 2236 result->holder(), |
| 2237 strict_mode); |
| 2217 case INTERCEPTOR: | 2238 case INTERCEPTOR: |
| 2218 return SetPropertyWithInterceptor(name, value, attributes, strict_mode); | 2239 return SetPropertyWithInterceptor(name, value, attributes, strict_mode); |
| 2219 case CONSTANT_TRANSITION: { | 2240 case CONSTANT_TRANSITION: { |
| 2220 // If the same constant function is being added we can simply | 2241 // If the same constant function is being added we can simply |
| 2221 // transition to the target map. | 2242 // transition to the target map. |
| 2222 Map* target_map = result->GetTransitionMap(); | 2243 Map* target_map = result->GetTransitionMap(); |
| 2223 DescriptorArray* target_descriptors = target_map->instance_descriptors(); | 2244 DescriptorArray* target_descriptors = target_map->instance_descriptors(); |
| 2224 int number = target_descriptors->SearchWithCache(name); | 2245 int number = target_descriptors->SearchWithCache(name); |
| 2225 ASSERT(number != DescriptorArray::kNotFound); | 2246 ASSERT(number != DescriptorArray::kNotFound); |
| 2226 ASSERT(target_descriptors->GetType(number) == CONSTANT_FUNCTION); | 2247 ASSERT(target_descriptors->GetType(number) == CONSTANT_FUNCTION); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2259 | 2280 |
| 2260 // Make sure that the top context does not change when doing callbacks or | 2281 // Make sure that the top context does not change when doing callbacks or |
| 2261 // interceptor calls. | 2282 // interceptor calls. |
| 2262 AssertNoContextChange ncc; | 2283 AssertNoContextChange ncc; |
| 2263 LookupResult result; | 2284 LookupResult result; |
| 2264 LocalLookup(name, &result); | 2285 LocalLookup(name, &result); |
| 2265 // Check access rights if needed. | 2286 // Check access rights if needed. |
| 2266 if (IsAccessCheckNeeded()) { | 2287 if (IsAccessCheckNeeded()) { |
| 2267 Heap* heap = GetHeap(); | 2288 Heap* heap = GetHeap(); |
| 2268 if (!heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_SET)) { | 2289 if (!heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_SET)) { |
| 2269 return SetPropertyWithFailedAccessCheck(&result, name, value, false); | 2290 return SetPropertyWithFailedAccessCheck(&result, |
| 2291 name, |
| 2292 value, |
| 2293 false, |
| 2294 kNonStrictMode); |
| 2270 } | 2295 } |
| 2271 } | 2296 } |
| 2272 | 2297 |
| 2273 if (IsJSGlobalProxy()) { | 2298 if (IsJSGlobalProxy()) { |
| 2274 Object* proto = GetPrototype(); | 2299 Object* proto = GetPrototype(); |
| 2275 if (proto->IsNull()) return value; | 2300 if (proto->IsNull()) return value; |
| 2276 ASSERT(proto->IsJSGlobalObject()); | 2301 ASSERT(proto->IsJSGlobalObject()); |
| 2277 return JSObject::cast(proto)->SetLocalPropertyIgnoreAttributes( | 2302 return JSObject::cast(proto)->SetLocalPropertyIgnoreAttributes( |
| 2278 name, | 2303 name, |
| 2279 value, | 2304 value, |
| (...skipping 5119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7399 } | 7424 } |
| 7400 | 7425 |
| 7401 UNREACHABLE(); | 7426 UNREACHABLE(); |
| 7402 return NULL; | 7427 return NULL; |
| 7403 } | 7428 } |
| 7404 | 7429 |
| 7405 | 7430 |
| 7406 MaybeObject* JSObject::SetElementWithCallback(Object* structure, | 7431 MaybeObject* JSObject::SetElementWithCallback(Object* structure, |
| 7407 uint32_t index, | 7432 uint32_t index, |
| 7408 Object* value, | 7433 Object* value, |
| 7409 JSObject* holder) { | 7434 JSObject* holder, |
| 7435 StrictModeFlag strict_mode) { |
| 7410 Isolate* isolate = GetIsolate(); | 7436 Isolate* isolate = GetIsolate(); |
| 7411 HandleScope scope(isolate); | 7437 HandleScope scope(isolate); |
| 7412 | 7438 |
| 7413 // We should never get here to initialize a const with the hole | 7439 // We should never get here to initialize a const with the hole |
| 7414 // value since a const declaration would conflict with the setter. | 7440 // value since a const declaration would conflict with the setter. |
| 7415 ASSERT(!value->IsTheHole()); | 7441 ASSERT(!value->IsTheHole()); |
| 7416 Handle<Object> value_handle(value, isolate); | 7442 Handle<Object> value_handle(value, isolate); |
| 7417 | 7443 |
| 7418 // To accommodate both the old and the new api we switch on the | 7444 // To accommodate both the old and the new api we switch on the |
| 7419 // data structure used to store the callbacks. Eventually foreign | 7445 // data structure used to store the callbacks. Eventually foreign |
| (...skipping 18 matching lines...) Expand all Loading... |
| 7438 VMState state(isolate, EXTERNAL); | 7464 VMState state(isolate, EXTERNAL); |
| 7439 call_fun(v8::Utils::ToLocal(key), | 7465 call_fun(v8::Utils::ToLocal(key), |
| 7440 v8::Utils::ToLocal(value_handle), | 7466 v8::Utils::ToLocal(value_handle), |
| 7441 info); | 7467 info); |
| 7442 } | 7468 } |
| 7443 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 7469 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 7444 return *value_handle; | 7470 return *value_handle; |
| 7445 } | 7471 } |
| 7446 | 7472 |
| 7447 if (structure->IsFixedArray()) { | 7473 if (structure->IsFixedArray()) { |
| 7448 Object* setter = FixedArray::cast(structure)->get(kSetterIndex); | 7474 Handle<Object> setter(FixedArray::cast(structure)->get(kSetterIndex)); |
| 7449 if (setter->IsJSFunction()) { | 7475 if (setter->IsJSFunction()) { |
| 7450 return SetPropertyWithDefinedSetter(JSFunction::cast(setter), value); | 7476 return SetPropertyWithDefinedSetter(JSFunction::cast(*setter), value); |
| 7451 } else { | 7477 } else { |
| 7478 if (strict_mode == kNonStrictMode) { |
| 7479 return value; |
| 7480 } |
| 7452 Handle<Object> holder_handle(holder, isolate); | 7481 Handle<Object> holder_handle(holder, isolate); |
| 7453 Handle<Object> key(isolate->factory()->NewNumberFromUint(index)); | 7482 Handle<Object> key(isolate->factory()->NewNumberFromUint(index)); |
| 7454 Handle<Object> args[2] = { key, holder_handle }; | 7483 Handle<Object> args[2] = { key, holder_handle }; |
| 7455 return isolate->Throw( | 7484 return isolate->Throw( |
| 7456 *isolate->factory()->NewTypeError("no_setter_in_callback", | 7485 *isolate->factory()->NewTypeError("no_setter_in_callback", |
| 7457 HandleVector(args, 2))); | 7486 HandleVector(args, 2))); |
| 7458 } | 7487 } |
| 7459 } | 7488 } |
| 7460 | 7489 |
| 7461 UNREACHABLE(); | 7490 UNREACHABLE(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 7475 Object* elms_obj; | 7504 Object* elms_obj; |
| 7476 { MaybeObject* maybe_elms_obj = EnsureWritableFastElements(); | 7505 { MaybeObject* maybe_elms_obj = EnsureWritableFastElements(); |
| 7477 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; | 7506 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; |
| 7478 } | 7507 } |
| 7479 FixedArray* elms = FixedArray::cast(elms_obj); | 7508 FixedArray* elms = FixedArray::cast(elms_obj); |
| 7480 uint32_t elms_length = static_cast<uint32_t>(elms->length()); | 7509 uint32_t elms_length = static_cast<uint32_t>(elms->length()); |
| 7481 | 7510 |
| 7482 if (check_prototype && | 7511 if (check_prototype && |
| 7483 (index >= elms_length || elms->get(index)->IsTheHole())) { | 7512 (index >= elms_length || elms->get(index)->IsTheHole())) { |
| 7484 bool found; | 7513 bool found; |
| 7485 MaybeObject* result = | 7514 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(index, |
| 7486 SetElementWithCallbackSetterInPrototypes(index, value, &found); | 7515 value, |
| 7516 &found, |
| 7517 strict_mode); |
| 7487 if (found) return result; | 7518 if (found) return result; |
| 7488 } | 7519 } |
| 7489 | 7520 |
| 7490 | 7521 |
| 7491 // Check whether there is extra space in fixed array.. | 7522 // Check whether there is extra space in fixed array.. |
| 7492 if (index < elms_length) { | 7523 if (index < elms_length) { |
| 7493 elms->set(index, value); | 7524 elms->set(index, value); |
| 7494 if (IsJSArray()) { | 7525 if (IsJSArray()) { |
| 7495 // Update the length of the array if needed. | 7526 // Update the length of the array if needed. |
| 7496 uint32_t array_length = 0; | 7527 uint32_t array_length = 0; |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7620 case DICTIONARY_ELEMENTS: { | 7651 case DICTIONARY_ELEMENTS: { |
| 7621 // Insert element in the dictionary. | 7652 // Insert element in the dictionary. |
| 7622 FixedArray* elms = FixedArray::cast(elements()); | 7653 FixedArray* elms = FixedArray::cast(elements()); |
| 7623 NumberDictionary* dictionary = NumberDictionary::cast(elms); | 7654 NumberDictionary* dictionary = NumberDictionary::cast(elms); |
| 7624 | 7655 |
| 7625 int entry = dictionary->FindEntry(index); | 7656 int entry = dictionary->FindEntry(index); |
| 7626 if (entry != NumberDictionary::kNotFound) { | 7657 if (entry != NumberDictionary::kNotFound) { |
| 7627 Object* element = dictionary->ValueAt(entry); | 7658 Object* element = dictionary->ValueAt(entry); |
| 7628 PropertyDetails details = dictionary->DetailsAt(entry); | 7659 PropertyDetails details = dictionary->DetailsAt(entry); |
| 7629 if (details.type() == CALLBACKS) { | 7660 if (details.type() == CALLBACKS) { |
| 7630 return SetElementWithCallback(element, index, value, this); | 7661 return SetElementWithCallback(element, |
| 7662 index, |
| 7663 value, |
| 7664 this, |
| 7665 strict_mode); |
| 7631 } else { | 7666 } else { |
| 7632 dictionary->UpdateMaxNumberKey(index); | 7667 dictionary->UpdateMaxNumberKey(index); |
| 7633 // If put fails instrict mode, throw exception. | 7668 // If put fails instrict mode, throw exception. |
| 7634 if (!dictionary->ValueAtPut(entry, value) && | 7669 if (!dictionary->ValueAtPut(entry, value) && |
| 7635 strict_mode == kStrictMode) { | 7670 strict_mode == kStrictMode) { |
| 7636 Handle<Object> holder(this); | 7671 Handle<Object> holder(this); |
| 7637 Handle<Object> number(isolate->factory()->NewNumberFromUint(index)); | 7672 Handle<Object> number(isolate->factory()->NewNumberFromUint(index)); |
| 7638 Handle<Object> args[2] = { number, holder }; | 7673 Handle<Object> args[2] = { number, holder }; |
| 7639 return isolate->Throw( | 7674 return isolate->Throw( |
| 7640 *isolate->factory()->NewTypeError("strict_read_only_property", | 7675 *isolate->factory()->NewTypeError("strict_read_only_property", |
| 7641 HandleVector(args, 2))); | 7676 HandleVector(args, 2))); |
| 7642 } | 7677 } |
| 7643 } | 7678 } |
| 7644 } else { | 7679 } else { |
| 7645 // Index not already used. Look for an accessor in the prototype chain. | 7680 // Index not already used. Look for an accessor in the prototype chain. |
| 7646 if (check_prototype) { | 7681 if (check_prototype) { |
| 7647 bool found; | 7682 bool found; |
| 7648 MaybeObject* result = | 7683 MaybeObject* result = |
| 7649 // Strict mode not needed. No-setter case already handled. | 7684 // Strict mode not needed. No-setter case already handled. |
| 7650 SetElementWithCallbackSetterInPrototypes(index, value, &found); | 7685 SetElementWithCallbackSetterInPrototypes(index, |
| 7686 value, |
| 7687 &found, |
| 7688 strict_mode); |
| 7651 if (found) return result; | 7689 if (found) return result; |
| 7652 } | 7690 } |
| 7653 // When we set the is_extensible flag to false we always force | 7691 // When we set the is_extensible flag to false we always force |
| 7654 // the element into dictionary mode (and force them to stay there). | 7692 // the element into dictionary mode (and force them to stay there). |
| 7655 if (!map()->is_extensible()) { | 7693 if (!map()->is_extensible()) { |
| 7656 if (strict_mode == kNonStrictMode) { | 7694 if (strict_mode == kNonStrictMode) { |
| 7657 return isolate->heap()->undefined_value(); | 7695 return isolate->heap()->undefined_value(); |
| 7658 } else { | 7696 } else { |
| 7659 Handle<Object> number(isolate->factory()->NewNumberFromUint(index)); | 7697 Handle<Object> number(isolate->factory()->NewNumberFromUint(index)); |
| 7660 Handle<String> index_string( | 7698 Handle<String> index_string( |
| (...skipping 2915 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10576 if (break_point_objects()->IsUndefined()) return 0; | 10614 if (break_point_objects()->IsUndefined()) return 0; |
| 10577 // Single beak point. | 10615 // Single beak point. |
| 10578 if (!break_point_objects()->IsFixedArray()) return 1; | 10616 if (!break_point_objects()->IsFixedArray()) return 1; |
| 10579 // Multiple break points. | 10617 // Multiple break points. |
| 10580 return FixedArray::cast(break_point_objects())->length(); | 10618 return FixedArray::cast(break_point_objects())->length(); |
| 10581 } | 10619 } |
| 10582 #endif | 10620 #endif |
| 10583 | 10621 |
| 10584 | 10622 |
| 10585 } } // namespace v8::internal | 10623 } } // namespace v8::internal |
| OLD | NEW |