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 |