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

Side by Side Diff: src/objects.cc

Issue 7064027: Change calls to undefined property setters to not throw (fixes issue 1355). (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | test/mjsunit/getter-in-prototype.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/objects.h ('k') | test/mjsunit/getter-in-prototype.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698