| OLD | NEW |
| 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 5185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5196 | 5196 |
| 5197 // Handle [] on String objects. | 5197 // Handle [] on String objects. |
| 5198 if (this->IsStringObjectWithCharacterAt(index)) return true; | 5198 if (this->IsStringObjectWithCharacterAt(index)) return true; |
| 5199 | 5199 |
| 5200 Object* pt = GetPrototype(); | 5200 Object* pt = GetPrototype(); |
| 5201 if (pt == Heap::null_value()) return false; | 5201 if (pt == Heap::null_value()) return false; |
| 5202 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); | 5202 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); |
| 5203 } | 5203 } |
| 5204 | 5204 |
| 5205 | 5205 |
| 5206 Object* JSObject::SetElementPostInterceptor(uint32_t index, Object* value) { | |
| 5207 if (HasFastElements()) return SetFastElement(index, value); | |
| 5208 | |
| 5209 // Dictionary case. | |
| 5210 ASSERT(!HasFastElements()); | |
| 5211 | |
| 5212 FixedArray* elms = FixedArray::cast(elements()); | |
| 5213 Object* result = Dictionary::cast(elms)->AtNumberPut(index, value); | |
| 5214 if (result->IsFailure()) return result; | |
| 5215 if (elms != FixedArray::cast(result)) { | |
| 5216 set_elements(FixedArray::cast(result)); | |
| 5217 } | |
| 5218 | |
| 5219 if (IsJSArray()) { | |
| 5220 return JSArray::cast(this)->JSArrayUpdateLengthFromIndex(index, value); | |
| 5221 } | |
| 5222 | |
| 5223 return value; | |
| 5224 } | |
| 5225 | |
| 5226 | |
| 5227 Object* JSObject::SetElementWithInterceptor(uint32_t index, Object* value) { | 5206 Object* JSObject::SetElementWithInterceptor(uint32_t index, Object* value) { |
| 5228 // Make sure that the top context does not change when doing | 5207 // Make sure that the top context does not change when doing |
| 5229 // callbacks or interceptor calls. | 5208 // callbacks or interceptor calls. |
| 5230 AssertNoContextChange ncc; | 5209 AssertNoContextChange ncc; |
| 5231 HandleScope scope; | 5210 HandleScope scope; |
| 5232 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); | 5211 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); |
| 5233 Handle<JSObject> this_handle(this); | 5212 Handle<JSObject> this_handle(this); |
| 5234 Handle<Object> value_handle(value); | 5213 Handle<Object> value_handle(value); |
| 5235 if (!interceptor->setter()->IsUndefined()) { | 5214 if (!interceptor->setter()->IsUndefined()) { |
| 5236 v8::IndexedPropertySetter setter = | 5215 v8::IndexedPropertySetter setter = |
| 5237 v8::ToCData<v8::IndexedPropertySetter>(interceptor->setter()); | 5216 v8::ToCData<v8::IndexedPropertySetter>(interceptor->setter()); |
| 5238 Handle<Object> data_handle(interceptor->data()); | 5217 Handle<Object> data_handle(interceptor->data()); |
| 5239 LOG(ApiIndexedPropertyAccess("interceptor-indexed-set", this, index)); | 5218 LOG(ApiIndexedPropertyAccess("interceptor-indexed-set", this, index)); |
| 5240 v8::AccessorInfo info(v8::Utils::ToLocal(this_handle), | 5219 v8::AccessorInfo info(v8::Utils::ToLocal(this_handle), |
| 5241 v8::Utils::ToLocal(data_handle), | 5220 v8::Utils::ToLocal(data_handle), |
| 5242 v8::Utils::ToLocal(this_handle)); | 5221 v8::Utils::ToLocal(this_handle)); |
| 5243 v8::Handle<v8::Value> result; | 5222 v8::Handle<v8::Value> result; |
| 5244 { | 5223 { |
| 5245 // Leaving JavaScript. | 5224 // Leaving JavaScript. |
| 5246 VMState state(EXTERNAL); | 5225 VMState state(EXTERNAL); |
| 5247 result = setter(index, v8::Utils::ToLocal(value_handle), info); | 5226 result = setter(index, v8::Utils::ToLocal(value_handle), info); |
| 5248 } | 5227 } |
| 5249 RETURN_IF_SCHEDULED_EXCEPTION(); | 5228 RETURN_IF_SCHEDULED_EXCEPTION(); |
| 5250 if (!result.IsEmpty()) return *value_handle; | 5229 if (!result.IsEmpty()) return *value_handle; |
| 5251 } | 5230 } |
| 5252 Object* raw_result = | 5231 Object* raw_result = |
| 5253 this_handle->SetElementPostInterceptor(index, *value_handle); | 5232 this_handle->SetElementWithoutInterceptor(index, *value_handle); |
| 5254 RETURN_IF_SCHEDULED_EXCEPTION(); | 5233 RETURN_IF_SCHEDULED_EXCEPTION(); |
| 5255 return raw_result; | 5234 return raw_result; |
| 5256 } | 5235 } |
| 5257 | 5236 |
| 5258 | 5237 |
| 5259 // Adding n elements in fast case is O(n*n). | 5238 // Adding n elements in fast case is O(n*n). |
| 5260 // Note: revisit design to have dual undefined values to capture absent | 5239 // Note: revisit design to have dual undefined values to capture absent |
| 5261 // elements. | 5240 // elements. |
| 5262 Object* JSObject::SetFastElement(uint32_t index, Object* value) { | 5241 Object* JSObject::SetFastElement(uint32_t index, Object* value) { |
| 5263 ASSERT(HasFastElements()); | 5242 ASSERT(HasFastElements()); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5325 if (proto->IsNull()) return value; | 5304 if (proto->IsNull()) return value; |
| 5326 ASSERT(proto->IsJSGlobalObject()); | 5305 ASSERT(proto->IsJSGlobalObject()); |
| 5327 return JSObject::cast(proto)->SetElement(index, value); | 5306 return JSObject::cast(proto)->SetElement(index, value); |
| 5328 } | 5307 } |
| 5329 | 5308 |
| 5330 // Check for lookup interceptor | 5309 // Check for lookup interceptor |
| 5331 if (HasIndexedInterceptor()) { | 5310 if (HasIndexedInterceptor()) { |
| 5332 return SetElementWithInterceptor(index, value); | 5311 return SetElementWithInterceptor(index, value); |
| 5333 } | 5312 } |
| 5334 | 5313 |
| 5314 return SetElementWithoutInterceptor(index, value); |
| 5315 } |
| 5316 |
| 5317 |
| 5318 Object* JSObject::SetElementWithoutInterceptor(uint32_t index, Object* value) { |
| 5335 // Fast case. | 5319 // Fast case. |
| 5336 if (HasFastElements()) return SetFastElement(index, value); | 5320 if (HasFastElements()) return SetFastElement(index, value); |
| 5337 | 5321 |
| 5338 // Dictionary case. | 5322 // Dictionary case. |
| 5339 ASSERT(!HasFastElements()); | 5323 ASSERT(!HasFastElements()); |
| 5340 | 5324 |
| 5341 // Insert element in the dictionary. | 5325 // Insert element in the dictionary. |
| 5342 FixedArray* elms = FixedArray::cast(elements()); | 5326 FixedArray* elms = FixedArray::cast(elements()); |
| 5343 Dictionary* dictionary = Dictionary::cast(elms); | 5327 Dictionary* dictionary = Dictionary::cast(elms); |
| 5344 | 5328 |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5431 if (HasFastElements()) { | 5415 if (HasFastElements()) { |
| 5432 FixedArray* elms = FixedArray::cast(elements()); | 5416 FixedArray* elms = FixedArray::cast(elements()); |
| 5433 if (index < static_cast<uint32_t>(elms->length())) { | 5417 if (index < static_cast<uint32_t>(elms->length())) { |
| 5434 Object* value = elms->get(index); | 5418 Object* value = elms->get(index); |
| 5435 if (!value->IsTheHole()) return value; | 5419 if (!value->IsTheHole()) return value; |
| 5436 } | 5420 } |
| 5437 } else { | 5421 } else { |
| 5438 Dictionary* dictionary = element_dictionary(); | 5422 Dictionary* dictionary = element_dictionary(); |
| 5439 int entry = dictionary->FindNumberEntry(index); | 5423 int entry = dictionary->FindNumberEntry(index); |
| 5440 if (entry != -1) { | 5424 if (entry != -1) { |
| 5441 return dictionary->ValueAt(entry); | 5425 Object* element = dictionary->ValueAt(entry); |
| 5426 PropertyDetails details = dictionary->DetailsAt(entry); |
| 5427 if (details.type() == CALLBACKS) { |
| 5428 // Only accessors allowed as elements. |
| 5429 FixedArray* structure = FixedArray::cast(element); |
| 5430 Object* getter = structure->get(kGetterIndex); |
| 5431 if (getter->IsJSFunction()) { |
| 5432 return GetPropertyWithDefinedGetter(receiver, |
| 5433 JSFunction::cast(getter)); |
| 5434 } else { |
| 5435 // Getter is not a function. |
| 5436 return Heap::undefined_value(); |
| 5437 } |
| 5438 } |
| 5439 return element; |
| 5442 } | 5440 } |
| 5443 } | 5441 } |
| 5444 | 5442 |
| 5445 // Continue searching via the prototype chain. | 5443 // Continue searching via the prototype chain. |
| 5446 Object* pt = GetPrototype(); | 5444 Object* pt = GetPrototype(); |
| 5447 if (pt == Heap::null_value()) return Heap::undefined_value(); | 5445 if (pt == Heap::null_value()) return Heap::undefined_value(); |
| 5448 return pt->GetElementWithReceiver(receiver, index); | 5446 return pt->GetElementWithReceiver(receiver, index); |
| 5449 } | 5447 } |
| 5450 | 5448 |
| 5451 | 5449 |
| (...skipping 2108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7560 // No break point. | 7558 // No break point. |
| 7561 if (break_point_objects()->IsUndefined()) return 0; | 7559 if (break_point_objects()->IsUndefined()) return 0; |
| 7562 // Single beak point. | 7560 // Single beak point. |
| 7563 if (!break_point_objects()->IsFixedArray()) return 1; | 7561 if (!break_point_objects()->IsFixedArray()) return 1; |
| 7564 // Multiple break points. | 7562 // Multiple break points. |
| 7565 return FixedArray::cast(break_point_objects())->length(); | 7563 return FixedArray::cast(break_point_objects())->length(); |
| 7566 } | 7564 } |
| 7567 #endif | 7565 #endif |
| 7568 | 7566 |
| 7569 } } // namespace v8::internal | 7567 } } // namespace v8::internal |
| OLD | NEW |