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

Side by Side Diff: src/objects.cc

Issue 118374: Introduce an API to force the deletion of a property ignoring... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/runtime.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 367 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 Handle<String> name_handle(name); 378 Handle<String> name_handle(name);
379 Handle<Object> value_handle(value); 379 Handle<Object> value_handle(value);
380 bool pending_exception; 380 bool pending_exception;
381 LoadLazy(Handle<JSObject>(JSObject::cast(result->GetLazyValue())), 381 LoadLazy(Handle<JSObject>(JSObject::cast(result->GetLazyValue())),
382 &pending_exception); 382 &pending_exception);
383 if (pending_exception) return Failure::Exception(); 383 if (pending_exception) return Failure::Exception();
384 return this_handle->SetProperty(*name_handle, *value_handle, attributes); 384 return this_handle->SetProperty(*name_handle, *value_handle, attributes);
385 } 385 }
386 386
387 387
388 Object* JSObject::DeleteLazyProperty(LookupResult* result, String* name) { 388 Object* JSObject::DeleteLazyProperty(LookupResult* result,
389 String* name,
390 DeleteMode mode) {
389 HandleScope scope; 391 HandleScope scope;
390 Handle<JSObject> this_handle(this); 392 Handle<JSObject> this_handle(this);
391 Handle<String> name_handle(name); 393 Handle<String> name_handle(name);
392 bool pending_exception; 394 bool pending_exception;
393 LoadLazy(Handle<JSObject>(JSObject::cast(result->GetLazyValue())), 395 LoadLazy(Handle<JSObject>(JSObject::cast(result->GetLazyValue())),
394 &pending_exception); 396 &pending_exception);
395 if (pending_exception) return Failure::Exception(); 397 if (pending_exception) return Failure::Exception();
396 return this_handle->DeleteProperty(*name_handle); 398 return this_handle->DeleteProperty(*name_handle, mode);
397 } 399 }
398 400
399 401
400 Object* Object::GetProperty(Object* receiver, 402 Object* Object::GetProperty(Object* receiver,
401 LookupResult* result, 403 LookupResult* result,
402 String* name, 404 String* name,
403 PropertyAttributes* attributes) { 405 PropertyAttributes* attributes) {
404 // Make sure that the top context does not change when doing 406 // Make sure that the top context does not change when doing
405 // callbacks or interceptor calls. 407 // callbacks or interceptor calls.
406 AssertNoContextChange ncc; 408 AssertNoContextChange ncc;
(...skipping 1706 matching lines...) Expand 10 before | Expand all | Expand 10 after
2113 if (FLAG_trace_normalization) { 2115 if (FLAG_trace_normalization) {
2114 PrintF("Object elements have been normalized:\n"); 2116 PrintF("Object elements have been normalized:\n");
2115 Print(); 2117 Print();
2116 } 2118 }
2117 #endif 2119 #endif
2118 2120
2119 return this; 2121 return this;
2120 } 2122 }
2121 2123
2122 2124
2123 Object* JSObject::DeletePropertyPostInterceptor(String* name) { 2125 Object* JSObject::DeletePropertyPostInterceptor(String* name, DeleteMode mode) {
2124 // Check local property, ignore interceptor. 2126 // Check local property, ignore interceptor.
2125 LookupResult result; 2127 LookupResult result;
2126 LocalLookupRealNamedProperty(name, &result); 2128 LocalLookupRealNamedProperty(name, &result);
2127 if (!result.IsValid()) return Heap::true_value(); 2129 if (!result.IsValid()) return Heap::true_value();
2128 2130
2129 // Normalize object if needed. 2131 // Normalize object if needed.
2130 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES); 2132 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES);
2131 if (obj->IsFailure()) return obj; 2133 if (obj->IsFailure()) return obj;
2132 2134
2133 ASSERT(!HasFastProperties()); 2135 ASSERT(!HasFastProperties());
2134 // Attempt to remove the property from the property dictionary. 2136 // Attempt to remove the property from the property dictionary.
2135 Dictionary* dictionary = property_dictionary(); 2137 Dictionary* dictionary = property_dictionary();
2136 int entry = dictionary->FindStringEntry(name); 2138 int entry = dictionary->FindStringEntry(name);
2137 if (entry != -1) return dictionary->DeleteProperty(entry); 2139 if (entry != -1) return dictionary->DeleteProperty(entry, mode);
2138 return Heap::true_value(); 2140 return Heap::true_value();
2139 } 2141 }
2140 2142
2141 2143
2142 Object* JSObject::DeletePropertyWithInterceptor(String* name) { 2144 Object* JSObject::DeletePropertyWithInterceptor(String* name) {
2143 HandleScope scope; 2145 HandleScope scope;
2144 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); 2146 Handle<InterceptorInfo> interceptor(GetNamedInterceptor());
2145 Handle<String> name_handle(name); 2147 Handle<String> name_handle(name);
2146 Handle<JSObject> this_handle(this); 2148 Handle<JSObject> this_handle(this);
2147 if (!interceptor->deleter()->IsUndefined()) { 2149 if (!interceptor->deleter()->IsUndefined()) {
2148 v8::NamedPropertyDeleter deleter = 2150 v8::NamedPropertyDeleter deleter =
2149 v8::ToCData<v8::NamedPropertyDeleter>(interceptor->deleter()); 2151 v8::ToCData<v8::NamedPropertyDeleter>(interceptor->deleter());
2150 Handle<Object> data_handle(interceptor->data()); 2152 Handle<Object> data_handle(interceptor->data());
2151 LOG(ApiNamedPropertyAccess("interceptor-named-delete", *this_handle, name)); 2153 LOG(ApiNamedPropertyAccess("interceptor-named-delete", *this_handle, name));
2152 v8::AccessorInfo info(v8::Utils::ToLocal(this_handle), 2154 v8::AccessorInfo info(v8::Utils::ToLocal(this_handle),
2153 v8::Utils::ToLocal(data_handle), 2155 v8::Utils::ToLocal(data_handle),
2154 v8::Utils::ToLocal(this_handle)); 2156 v8::Utils::ToLocal(this_handle));
2155 v8::Handle<v8::Boolean> result; 2157 v8::Handle<v8::Boolean> result;
2156 { 2158 {
2157 // Leaving JavaScript. 2159 // Leaving JavaScript.
2158 VMState state(EXTERNAL); 2160 VMState state(EXTERNAL);
2159 result = deleter(v8::Utils::ToLocal(name_handle), info); 2161 result = deleter(v8::Utils::ToLocal(name_handle), info);
2160 } 2162 }
2161 RETURN_IF_SCHEDULED_EXCEPTION(); 2163 RETURN_IF_SCHEDULED_EXCEPTION();
2162 if (!result.IsEmpty()) { 2164 if (!result.IsEmpty()) {
2163 ASSERT(result->IsBoolean()); 2165 ASSERT(result->IsBoolean());
2164 return *v8::Utils::OpenHandle(*result); 2166 return *v8::Utils::OpenHandle(*result);
2165 } 2167 }
2166 } 2168 }
2167 Object* raw_result = this_handle->DeletePropertyPostInterceptor(*name_handle); 2169 Object* raw_result =
2170 this_handle->DeletePropertyPostInterceptor(*name_handle, NORMAL_DELETION);
2168 RETURN_IF_SCHEDULED_EXCEPTION(); 2171 RETURN_IF_SCHEDULED_EXCEPTION();
2169 return raw_result; 2172 return raw_result;
2170 } 2173 }
2171 2174
2172 2175
2173 Object* JSObject::DeleteElementPostInterceptor(uint32_t index) { 2176 Object* JSObject::DeleteElementPostInterceptor(uint32_t index,
2177 DeleteMode mode) {
2174 if (HasFastElements()) { 2178 if (HasFastElements()) {
2175 uint32_t length = IsJSArray() ? 2179 uint32_t length = IsJSArray() ?
2176 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : 2180 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) :
2177 static_cast<uint32_t>(FixedArray::cast(elements())->length()); 2181 static_cast<uint32_t>(FixedArray::cast(elements())->length());
2178 if (index < length) { 2182 if (index < length) {
2179 FixedArray::cast(elements())->set_the_hole(index); 2183 FixedArray::cast(elements())->set_the_hole(index);
2180 } 2184 }
2181 return Heap::true_value(); 2185 return Heap::true_value();
2182 } 2186 }
2183 ASSERT(!HasFastElements()); 2187 ASSERT(!HasFastElements());
2184 Dictionary* dictionary = element_dictionary(); 2188 Dictionary* dictionary = element_dictionary();
2185 int entry = dictionary->FindNumberEntry(index); 2189 int entry = dictionary->FindNumberEntry(index);
2186 if (entry != -1) return dictionary->DeleteProperty(entry); 2190 if (entry != -1) return dictionary->DeleteProperty(entry, mode);
2187 return Heap::true_value(); 2191 return Heap::true_value();
2188 } 2192 }
2189 2193
2190 2194
2191 Object* JSObject::DeleteElementWithInterceptor(uint32_t index) { 2195 Object* JSObject::DeleteElementWithInterceptor(uint32_t index) {
2192 // Make sure that the top context does not change when doing 2196 // Make sure that the top context does not change when doing
2193 // callbacks or interceptor calls. 2197 // callbacks or interceptor calls.
2194 AssertNoContextChange ncc; 2198 AssertNoContextChange ncc;
2195 HandleScope scope; 2199 HandleScope scope;
2196 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); 2200 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor());
(...skipping 10 matching lines...) Expand all
2207 { 2211 {
2208 // Leaving JavaScript. 2212 // Leaving JavaScript.
2209 VMState state(EXTERNAL); 2213 VMState state(EXTERNAL);
2210 result = deleter(index, info); 2214 result = deleter(index, info);
2211 } 2215 }
2212 RETURN_IF_SCHEDULED_EXCEPTION(); 2216 RETURN_IF_SCHEDULED_EXCEPTION();
2213 if (!result.IsEmpty()) { 2217 if (!result.IsEmpty()) {
2214 ASSERT(result->IsBoolean()); 2218 ASSERT(result->IsBoolean());
2215 return *v8::Utils::OpenHandle(*result); 2219 return *v8::Utils::OpenHandle(*result);
2216 } 2220 }
2217 Object* raw_result = this_handle->DeleteElementPostInterceptor(index); 2221 Object* raw_result =
2222 this_handle->DeleteElementPostInterceptor(index, NORMAL_DELETION);
2218 RETURN_IF_SCHEDULED_EXCEPTION(); 2223 RETURN_IF_SCHEDULED_EXCEPTION();
2219 return raw_result; 2224 return raw_result;
2220 } 2225 }
2221 2226
2222 2227
2223 Object* JSObject::DeleteElement(uint32_t index) { 2228 Object* JSObject::DeleteElement(uint32_t index, DeleteMode mode) {
2224 // Check access rights if needed. 2229 // Check access rights if needed.
2225 if (IsAccessCheckNeeded() && 2230 if (IsAccessCheckNeeded() &&
2226 !Top::MayIndexedAccess(this, index, v8::ACCESS_DELETE)) { 2231 !Top::MayIndexedAccess(this, index, v8::ACCESS_DELETE)) {
2227 Top::ReportFailedAccessCheck(this, v8::ACCESS_DELETE); 2232 Top::ReportFailedAccessCheck(this, v8::ACCESS_DELETE);
2228 return Heap::false_value(); 2233 return Heap::false_value();
2229 } 2234 }
2230 2235
2231 if (IsJSGlobalProxy()) { 2236 if (IsJSGlobalProxy()) {
2232 Object* proto = GetPrototype(); 2237 Object* proto = GetPrototype();
2233 if (proto->IsNull()) return Heap::false_value(); 2238 if (proto->IsNull()) return Heap::false_value();
2234 ASSERT(proto->IsJSGlobalObject()); 2239 ASSERT(proto->IsJSGlobalObject());
2235 return JSGlobalObject::cast(proto)->DeleteElement(index); 2240 return JSGlobalObject::cast(proto)->DeleteElement(index, mode);
2236 } 2241 }
2237 2242
2238 if (HasIndexedInterceptor()) { 2243 if (HasIndexedInterceptor()) {
2244 // Skip interceptor if forcing deletion.
2245 if (mode == FORCE_DELETION) {
2246 return DeleteElementPostInterceptor(index, mode);
2247 }
2239 return DeleteElementWithInterceptor(index); 2248 return DeleteElementWithInterceptor(index);
2240 } 2249 }
2241 2250
2242 if (HasFastElements()) { 2251 if (HasFastElements()) {
2243 uint32_t length = IsJSArray() ? 2252 uint32_t length = IsJSArray() ?
2244 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : 2253 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) :
2245 static_cast<uint32_t>(FixedArray::cast(elements())->length()); 2254 static_cast<uint32_t>(FixedArray::cast(elements())->length());
2246 if (index < length) { 2255 if (index < length) {
2247 FixedArray::cast(elements())->set_the_hole(index); 2256 FixedArray::cast(elements())->set_the_hole(index);
2248 } 2257 }
2249 return Heap::true_value(); 2258 return Heap::true_value();
2250 } else { 2259 } else {
2251 Dictionary* dictionary = element_dictionary(); 2260 Dictionary* dictionary = element_dictionary();
2252 int entry = dictionary->FindNumberEntry(index); 2261 int entry = dictionary->FindNumberEntry(index);
2253 if (entry != -1) return dictionary->DeleteProperty(entry); 2262 if (entry != -1) return dictionary->DeleteProperty(entry, mode);
2254 } 2263 }
2255 return Heap::true_value(); 2264 return Heap::true_value();
2256 } 2265 }
2257 2266
2258 2267
2259 Object* JSObject::DeleteProperty(String* name) { 2268 Object* JSObject::DeleteProperty(String* name, DeleteMode mode) {
2260 // ECMA-262, 3rd, 8.6.2.5 2269 // ECMA-262, 3rd, 8.6.2.5
2261 ASSERT(name->IsString()); 2270 ASSERT(name->IsString());
2262 2271
2263 // Check access rights if needed. 2272 // Check access rights if needed.
2264 if (IsAccessCheckNeeded() && 2273 if (IsAccessCheckNeeded() &&
2265 !Top::MayNamedAccess(this, name, v8::ACCESS_DELETE)) { 2274 !Top::MayNamedAccess(this, name, v8::ACCESS_DELETE)) {
2266 Top::ReportFailedAccessCheck(this, v8::ACCESS_DELETE); 2275 Top::ReportFailedAccessCheck(this, v8::ACCESS_DELETE);
2267 return Heap::false_value(); 2276 return Heap::false_value();
2268 } 2277 }
2269 2278
2270 if (IsJSGlobalProxy()) { 2279 if (IsJSGlobalProxy()) {
2271 Object* proto = GetPrototype(); 2280 Object* proto = GetPrototype();
2272 if (proto->IsNull()) return Heap::false_value(); 2281 if (proto->IsNull()) return Heap::false_value();
2273 ASSERT(proto->IsJSGlobalObject()); 2282 ASSERT(proto->IsJSGlobalObject());
2274 return JSGlobalObject::cast(proto)->DeleteProperty(name); 2283 return JSGlobalObject::cast(proto)->DeleteProperty(name, mode);
2275 } 2284 }
2276 2285
2277 uint32_t index = 0; 2286 uint32_t index = 0;
2278 if (name->AsArrayIndex(&index)) { 2287 if (name->AsArrayIndex(&index)) {
2279 return DeleteElement(index); 2288 return DeleteElement(index, mode);
2280 } else { 2289 } else {
2281 LookupResult result; 2290 LookupResult result;
2282 LocalLookup(name, &result); 2291 LocalLookup(name, &result);
2283 if (!result.IsValid()) return Heap::true_value(); 2292 if (!result.IsValid()) return Heap::true_value();
2284 if (result.IsDontDelete()) return Heap::false_value(); 2293 // Ignore attributes if forcing a deletion.
2294 if (result.IsDontDelete() && mode != FORCE_DELETION) {
2295 return Heap::false_value();
2296 }
2285 // Check for interceptor. 2297 // Check for interceptor.
2286 if (result.type() == INTERCEPTOR) { 2298 if (result.type() == INTERCEPTOR) {
2299 // Skip interceptor if forcing a deletion.
2300 if (mode == FORCE_DELETION) {
2301 return DeletePropertyPostInterceptor(name, mode);
2302 }
2287 return DeletePropertyWithInterceptor(name); 2303 return DeletePropertyWithInterceptor(name);
2288 } 2304 }
2289 if (!result.IsLoaded()) { 2305 if (!result.IsLoaded()) {
2290 return JSObject::cast(this)->DeleteLazyProperty(&result, name); 2306 return JSObject::cast(this)->DeleteLazyProperty(&result,
2307 name,
2308 mode);
2291 } 2309 }
2292 // Normalize object if needed. 2310 // Normalize object if needed.
2293 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES); 2311 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES);
2294 if (obj->IsFailure()) return obj; 2312 if (obj->IsFailure()) return obj;
2295 // Make sure the properties are normalized before removing the entry. 2313 // Make sure the properties are normalized before removing the entry.
2296 Dictionary* dictionary = property_dictionary(); 2314 Dictionary* dictionary = property_dictionary();
2297 int entry = dictionary->FindStringEntry(name); 2315 int entry = dictionary->FindStringEntry(name);
2298 if (entry != -1) return dictionary->DeleteProperty(entry); 2316 if (entry != -1) return dictionary->DeleteProperty(entry, mode);
2299 return Heap::true_value(); 2317 return Heap::true_value();
2300 } 2318 }
2301 } 2319 }
2302 2320
2303 2321
2304 // Check whether this object references another object. 2322 // Check whether this object references another object.
2305 bool JSObject::ReferencesObject(Object* obj) { 2323 bool JSObject::ReferencesObject(Object* obj) {
2306 AssertNoAllocation no_alloc; 2324 AssertNoAllocation no_alloc;
2307 2325
2308 // Is the object the constructor for this object? 2326 // Is the object the constructor for this object?
(...skipping 4627 matching lines...) Expand 10 before | Expand all | Expand 10 after
6936 removed_entries++; 6954 removed_entries++;
6937 } 6955 }
6938 } 6956 }
6939 } 6957 }
6940 6958
6941 // Update the number of elements. 6959 // Update the number of elements.
6942 SetNumberOfElements(NumberOfElements() - removed_entries); 6960 SetNumberOfElements(NumberOfElements() - removed_entries);
6943 } 6961 }
6944 6962
6945 6963
6946 Object* Dictionary::DeleteProperty(int entry) { 6964 Object* Dictionary::DeleteProperty(int entry, JSObject::DeleteMode mode) {
6947 PropertyDetails details = DetailsAt(entry); 6965 PropertyDetails details = DetailsAt(entry);
6948 if (details.IsDontDelete()) return Heap::false_value(); 6966 // Ignore attributes if forcing a deletion.
6967 if (details.IsDontDelete() && mode == JSObject::NORMAL_DELETION) {
6968 return Heap::false_value();
6969 }
6949 SetEntry(entry, Heap::null_value(), Heap::null_value(), Smi::FromInt(0)); 6970 SetEntry(entry, Heap::null_value(), Heap::null_value(), Smi::FromInt(0));
6950 ElementRemoved(); 6971 ElementRemoved();
6951 return Heap::true_value(); 6972 return Heap::true_value();
6952 } 6973 }
6953 6974
6954 6975
6955 int Dictionary::FindStringEntry(String* key) { 6976 int Dictionary::FindStringEntry(String* key) {
6956 StringKey k(key); 6977 StringKey k(key);
6957 return FindEntry(&k); 6978 return FindEntry(&k);
6958 } 6979 }
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after
7537 // No break point. 7558 // No break point.
7538 if (break_point_objects()->IsUndefined()) return 0; 7559 if (break_point_objects()->IsUndefined()) return 0;
7539 // Single beak point. 7560 // Single beak point.
7540 if (!break_point_objects()->IsFixedArray()) return 1; 7561 if (!break_point_objects()->IsFixedArray()) return 1;
7541 // Multiple break points. 7562 // Multiple break points.
7542 return FixedArray::cast(break_point_objects())->length(); 7563 return FixedArray::cast(break_point_objects())->length();
7543 } 7564 }
7544 #endif 7565 #endif
7545 7566
7546 } } // namespace v8::internal 7567 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/runtime.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698