| OLD | NEW | 
|---|
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 6777 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 6788   // Handle [] on String objects. | 6788   // Handle [] on String objects. | 
| 6789   if (this->IsStringObjectWithCharacterAt(index)) return true; | 6789   if (this->IsStringObjectWithCharacterAt(index)) return true; | 
| 6790 | 6790 | 
| 6791   Object* pt = GetPrototype(); | 6791   Object* pt = GetPrototype(); | 
| 6792   if (pt == Heap::null_value()) return false; | 6792   if (pt == Heap::null_value()) return false; | 
| 6793   return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); | 6793   return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); | 
| 6794 } | 6794 } | 
| 6795 | 6795 | 
| 6796 | 6796 | 
| 6797 MaybeObject* JSObject::SetElementWithInterceptor(uint32_t index, | 6797 MaybeObject* JSObject::SetElementWithInterceptor(uint32_t index, | 
| 6798                                                  Object* value) { | 6798                                                  Object* value, | 
|  | 6799                                                  bool own) { | 
| 6799   // Make sure that the top context does not change when doing | 6800   // Make sure that the top context does not change when doing | 
| 6800   // callbacks or interceptor calls. | 6801   // callbacks or interceptor calls. | 
| 6801   AssertNoContextChange ncc; | 6802   AssertNoContextChange ncc; | 
| 6802   HandleScope scope; | 6803   HandleScope scope; | 
| 6803   Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); | 6804   Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); | 
| 6804   Handle<JSObject> this_handle(this); | 6805   Handle<JSObject> this_handle(this); | 
| 6805   Handle<Object> value_handle(value); | 6806   Handle<Object> value_handle(value); | 
| 6806   if (!interceptor->setter()->IsUndefined()) { | 6807   if (!interceptor->setter()->IsUndefined()) { | 
| 6807     v8::IndexedPropertySetter setter = | 6808     v8::IndexedPropertySetter setter = | 
| 6808         v8::ToCData<v8::IndexedPropertySetter>(interceptor->setter()); | 6809         v8::ToCData<v8::IndexedPropertySetter>(interceptor->setter()); | 
| 6809     LOG(ApiIndexedPropertyAccess("interceptor-indexed-set", this, index)); | 6810     LOG(ApiIndexedPropertyAccess("interceptor-indexed-set", this, index)); | 
| 6810     CustomArguments args(interceptor->data(), this, this); | 6811     CustomArguments args(interceptor->data(), this, this); | 
| 6811     v8::AccessorInfo info(args.end()); | 6812     v8::AccessorInfo info(args.end()); | 
| 6812     v8::Handle<v8::Value> result; | 6813     v8::Handle<v8::Value> result; | 
| 6813     { | 6814     { | 
| 6814       // Leaving JavaScript. | 6815       // Leaving JavaScript. | 
| 6815       VMState state(EXTERNAL); | 6816       VMState state(EXTERNAL); | 
| 6816       result = setter(index, v8::Utils::ToLocal(value_handle), info); | 6817       result = setter(index, v8::Utils::ToLocal(value_handle), info); | 
| 6817     } | 6818     } | 
| 6818     RETURN_IF_SCHEDULED_EXCEPTION(); | 6819     RETURN_IF_SCHEDULED_EXCEPTION(); | 
| 6819     if (!result.IsEmpty()) return *value_handle; | 6820     if (!result.IsEmpty()) return *value_handle; | 
| 6820   } | 6821   } | 
| 6821   MaybeObject* raw_result = | 6822   MaybeObject* raw_result = | 
| 6822       this_handle->SetElementWithoutInterceptor(index, *value_handle); | 6823       this_handle->SetElementWithoutInterceptor(index, *value_handle, own); | 
| 6823   RETURN_IF_SCHEDULED_EXCEPTION(); | 6824   RETURN_IF_SCHEDULED_EXCEPTION(); | 
| 6824   return raw_result; | 6825   return raw_result; | 
| 6825 } | 6826 } | 
| 6826 | 6827 | 
| 6827 | 6828 | 
| 6828 MaybeObject* JSObject::GetElementWithCallback(Object* receiver, | 6829 MaybeObject* JSObject::GetElementWithCallback(Object* receiver, | 
| 6829                                               Object* structure, | 6830                                               Object* structure, | 
| 6830                                               uint32_t index, | 6831                                               uint32_t index, | 
| 6831                                               Object* holder) { | 6832                                               Object* holder) { | 
| 6832   ASSERT(!structure->IsProxy()); | 6833   ASSERT(!structure->IsProxy()); | 
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 6923   } | 6924   } | 
| 6924 | 6925 | 
| 6925   UNREACHABLE(); | 6926   UNREACHABLE(); | 
| 6926   return NULL; | 6927   return NULL; | 
| 6927 } | 6928 } | 
| 6928 | 6929 | 
| 6929 | 6930 | 
| 6930 // Adding n elements in fast case is O(n*n). | 6931 // Adding n elements in fast case is O(n*n). | 
| 6931 // Note: revisit design to have dual undefined values to capture absent | 6932 // Note: revisit design to have dual undefined values to capture absent | 
| 6932 // elements. | 6933 // elements. | 
| 6933 MaybeObject* JSObject::SetFastElement(uint32_t index, Object* value) { | 6934 MaybeObject* JSObject::SetFastElement(uint32_t index, Object* value, bool own) { | 
| 6934   ASSERT(HasFastElements()); | 6935   ASSERT(HasFastElements()); | 
| 6935 | 6936 | 
| 6936   Object* elms_obj; | 6937   Object* elms_obj; | 
| 6937   { MaybeObject* maybe_elms_obj = EnsureWritableFastElements(); | 6938   { MaybeObject* maybe_elms_obj = EnsureWritableFastElements(); | 
| 6938     if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; | 6939     if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; | 
| 6939   } | 6940   } | 
| 6940   FixedArray* elms = FixedArray::cast(elms_obj); | 6941   FixedArray* elms = FixedArray::cast(elms_obj); | 
| 6941   uint32_t elms_length = static_cast<uint32_t>(elms->length()); | 6942   uint32_t elms_length = static_cast<uint32_t>(elms->length()); | 
| 6942 | 6943 | 
| 6943   if (!IsJSArray() && (index >= elms_length || elms->get(index)->IsTheHole())) { | 6944   if (!own && !IsJSArray() && | 
|  | 6945       (index >= elms_length || elms->get(index)->IsTheHole())) { | 
| 6944     if (SetElementWithCallbackSetterInPrototypes(index, value)) { | 6946     if (SetElementWithCallbackSetterInPrototypes(index, value)) { | 
| 6945       return value; | 6947       return value; | 
| 6946     } | 6948     } | 
| 6947   } | 6949   } | 
| 6948 | 6950 | 
| 6949   // Check whether there is extra space in fixed array.. | 6951   // Check whether there is extra space in fixed array.. | 
| 6950   if (index < elms_length) { | 6952   if (index < elms_length) { | 
| 6951     elms->set(index, value); | 6953     elms->set(index, value); | 
| 6952     if (IsJSArray()) { | 6954     if (IsJSArray()) { | 
| 6953       // Update the length of the array if needed. | 6955       // Update the length of the array if needed. | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
| 6976       return value; | 6978       return value; | 
| 6977     } | 6979     } | 
| 6978   } | 6980   } | 
| 6979 | 6981 | 
| 6980   // Otherwise default to slow case. | 6982   // Otherwise default to slow case. | 
| 6981   Object* obj; | 6983   Object* obj; | 
| 6982   { MaybeObject* maybe_obj = NormalizeElements(); | 6984   { MaybeObject* maybe_obj = NormalizeElements(); | 
| 6983     if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 6985     if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 
| 6984   } | 6986   } | 
| 6985   ASSERT(HasDictionaryElements()); | 6987   ASSERT(HasDictionaryElements()); | 
| 6986   return SetElement(index, value); | 6988   return SetElement(index, value, own); | 
| 6987 } | 6989 } | 
| 6988 | 6990 | 
| 6989 | 6991 | 
| 6990 MaybeObject* JSObject::SetElement(uint32_t index, Object* value) { | 6992 MaybeObject* JSObject::SetElement(uint32_t index, Object* value, bool own) { | 
| 6991   // Check access rights if needed. | 6993   // Check access rights if needed. | 
| 6992   if (IsAccessCheckNeeded() && | 6994   if (IsAccessCheckNeeded() && | 
| 6993       !Top::MayIndexedAccess(this, index, v8::ACCESS_SET)) { | 6995       !Top::MayIndexedAccess(this, index, v8::ACCESS_SET)) { | 
| 6994     HandleScope scope; | 6996     HandleScope scope; | 
| 6995     Handle<Object> value_handle(value); | 6997     Handle<Object> value_handle(value); | 
| 6996     Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); | 6998     Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); | 
| 6997     return *value_handle; | 6999     return *value_handle; | 
| 6998   } | 7000   } | 
| 6999 | 7001 | 
| 7000   if (IsJSGlobalProxy()) { | 7002   if (IsJSGlobalProxy()) { | 
| 7001     Object* proto = GetPrototype(); | 7003     Object* proto = GetPrototype(); | 
| 7002     if (proto->IsNull()) return value; | 7004     if (proto->IsNull()) return value; | 
| 7003     ASSERT(proto->IsJSGlobalObject()); | 7005     ASSERT(proto->IsJSGlobalObject()); | 
| 7004     return JSObject::cast(proto)->SetElement(index, value); | 7006     return JSObject::cast(proto)->SetElement(index, value, own); | 
| 7005   } | 7007   } | 
| 7006 | 7008 | 
| 7007   // Check for lookup interceptor | 7009   // Check for lookup interceptor | 
| 7008   if (HasIndexedInterceptor()) { | 7010   if (HasIndexedInterceptor()) { | 
| 7009     return SetElementWithInterceptor(index, value); | 7011     return SetElementWithInterceptor(index, value, own); | 
| 7010   } | 7012   } | 
| 7011 | 7013 | 
| 7012   return SetElementWithoutInterceptor(index, value); | 7014   return SetElementWithoutInterceptor(index, value, own); | 
| 7013 } | 7015 } | 
| 7014 | 7016 | 
| 7015 | 7017 | 
| 7016 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, | 7018 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, | 
| 7017                                                     Object* value) { | 7019                                                     Object* value, | 
|  | 7020                                                     bool own) { | 
| 7018   switch (GetElementsKind()) { | 7021   switch (GetElementsKind()) { | 
| 7019     case FAST_ELEMENTS: | 7022     case FAST_ELEMENTS: | 
| 7020       // Fast case. | 7023       // Fast case. | 
| 7021       return SetFastElement(index, value); | 7024       return SetFastElement(index, value, own); | 
| 7022     case PIXEL_ELEMENTS: { | 7025     case PIXEL_ELEMENTS: { | 
| 7023       PixelArray* pixels = PixelArray::cast(elements()); | 7026       PixelArray* pixels = PixelArray::cast(elements()); | 
| 7024       return pixels->SetValue(index, value); | 7027       return pixels->SetValue(index, value); | 
| 7025     } | 7028     } | 
| 7026     case EXTERNAL_BYTE_ELEMENTS: { | 7029     case EXTERNAL_BYTE_ELEMENTS: { | 
| 7027       ExternalByteArray* array = ExternalByteArray::cast(elements()); | 7030       ExternalByteArray* array = ExternalByteArray::cast(elements()); | 
| 7028       return array->SetValue(index, value); | 7031       return array->SetValue(index, value); | 
| 7029     } | 7032     } | 
| 7030     case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { | 7033     case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { | 
| 7031       ExternalUnsignedByteArray* array = | 7034       ExternalUnsignedByteArray* array = | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 7064         Object* element = dictionary->ValueAt(entry); | 7067         Object* element = dictionary->ValueAt(entry); | 
| 7065         PropertyDetails details = dictionary->DetailsAt(entry); | 7068         PropertyDetails details = dictionary->DetailsAt(entry); | 
| 7066         if (details.type() == CALLBACKS) { | 7069         if (details.type() == CALLBACKS) { | 
| 7067           return SetElementWithCallback(element, index, value, this); | 7070           return SetElementWithCallback(element, index, value, this); | 
| 7068         } else { | 7071         } else { | 
| 7069           dictionary->UpdateMaxNumberKey(index); | 7072           dictionary->UpdateMaxNumberKey(index); | 
| 7070           dictionary->ValueAtPut(entry, value); | 7073           dictionary->ValueAtPut(entry, value); | 
| 7071         } | 7074         } | 
| 7072       } else { | 7075       } else { | 
| 7073         // Index not already used. Look for an accessor in the prototype chain. | 7076         // Index not already used. Look for an accessor in the prototype chain. | 
| 7074         if (!IsJSArray()) { | 7077         if (!own && !IsJSArray() && | 
| 7075           if (SetElementWithCallbackSetterInPrototypes(index, value)) { | 7078             SetElementWithCallbackSetterInPrototypes(index, value)) { | 
| 7076             return value; | 7079           return value; | 
| 7077           } |  | 
| 7078         } | 7080         } | 
| 7079         // When we set the is_extensible flag to false we always force | 7081         // When we set the is_extensible flag to false we always force | 
| 7080         // the element into dictionary mode (and force them to stay there). | 7082         // the element into dictionary mode (and force them to stay there). | 
| 7081         if (!map()->is_extensible()) { | 7083         if (!map()->is_extensible()) { | 
| 7082           Handle<Object> number(Factory::NewNumberFromUint(index)); | 7084           Handle<Object> number(Factory::NewNumberFromUint(index)); | 
| 7083           Handle<String> index_string(Factory::NumberToString(number)); | 7085           Handle<String> index_string(Factory::NumberToString(number)); | 
| 7084           Handle<Object> args[1] = { index_string }; | 7086           Handle<Object> args[1] = { index_string }; | 
| 7085           return Top::Throw(*Factory::NewTypeError("object_not_extensible", | 7087           return Top::Throw(*Factory::NewTypeError("object_not_extensible", | 
| 7086                                                    HandleVector(args, 1))); | 7088                                                    HandleVector(args, 1))); | 
| 7087         } | 7089         } | 
| (...skipping 2771 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 9859   if (break_point_objects()->IsUndefined()) return 0; | 9861   if (break_point_objects()->IsUndefined()) return 0; | 
| 9860   // Single beak point. | 9862   // Single beak point. | 
| 9861   if (!break_point_objects()->IsFixedArray()) return 1; | 9863   if (!break_point_objects()->IsFixedArray()) return 1; | 
| 9862   // Multiple break points. | 9864   // Multiple break points. | 
| 9863   return FixedArray::cast(break_point_objects())->length(); | 9865   return FixedArray::cast(break_point_objects())->length(); | 
| 9864 } | 9866 } | 
| 9865 #endif | 9867 #endif | 
| 9866 | 9868 | 
| 9867 | 9869 | 
| 9868 } }  // namespace v8::internal | 9870 } }  // namespace v8::internal | 
| OLD | NEW | 
|---|