| Index: src/objects.cc
|
| diff --git a/src/objects.cc b/src/objects.cc
|
| index 85b43bad7f10e6e67e3ee4a7ec5dc74f2776db94..666320a50adfec3c024636ae0697674b80f194e7 100644
|
| --- a/src/objects.cc
|
| +++ b/src/objects.cc
|
| @@ -247,18 +247,6 @@ MaybeObject* JSProxy::GetPropertyWithHandler(Object* receiver_raw,
|
| }
|
|
|
|
|
| -Handle<Object> Object::GetProperty(Handle<Object> object, Handle<String> name) {
|
| - // TODO(rossberg): The index test should not be here but in the GetProperty
|
| - // method (or somewhere else entirely). Needs more global clean-up.
|
| - uint32_t index;
|
| - if (name->AsArrayIndex(&index)) return GetElement(object, index);
|
| - Isolate* isolate = object->IsHeapObject()
|
| - ? Handle<HeapObject>::cast(object)->GetIsolate()
|
| - : Isolate::Current();
|
| - CALL_HEAP_FUNCTION(isolate, object->GetProperty(*name), Object);
|
| -}
|
| -
|
| -
|
| Handle<Object> Object::GetElement(Handle<Object> object, uint32_t index) {
|
| Isolate* isolate = object->IsHeapObject()
|
| ? Handle<HeapObject>::cast(object)->GetIsolate()
|
| @@ -3346,11 +3334,6 @@ PropertyAttributes JSObject::GetElementAttributeWithReceiver(
|
| return GetElementAttributeWithInterceptor(receiver, index, continue_search);
|
| }
|
|
|
| - // Handle [] on String objects.
|
| - if (this->IsStringObjectWithCharacterAt(index)) {
|
| - return static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
|
| - }
|
| -
|
| return GetElementAttributeWithoutInterceptor(
|
| receiver, index, continue_search);
|
| }
|
| @@ -9645,10 +9628,8 @@ AccessorPair* JSObject::GetLocalPropertyAccessorPair(String* name) {
|
| if (name->AsArrayIndex(&index)) {
|
| return GetLocalElementAccessorPair(index);
|
| }
|
| -
|
| LookupResult lookup(GetIsolate());
|
| - LocalLookupRealNamedProperty(name, &lookup);
|
| -
|
| + LocalLookup(name, &lookup);
|
| if (lookup.IsPropertyCallbacks() &&
|
| lookup.GetCallbackObject()->IsAccessorPair()) {
|
| return AccessorPair::cast(lookup.GetCallbackObject());
|
| @@ -9658,17 +9639,116 @@ AccessorPair* JSObject::GetLocalPropertyAccessorPair(String* name) {
|
|
|
|
|
| AccessorPair* JSObject::GetLocalElementAccessorPair(uint32_t index) {
|
| + return GetElementsAccessor()->GetAccessorPair(this, this, index);
|
| +}
|
| +
|
| +
|
| +JSObject::LocalElementKind JSObject::GetLocalElementKind(uint32_t index) {
|
| + // Check access rights if needed.
|
| + if (IsAccessCheckNeeded()) {
|
| + Heap* heap = GetHeap();
|
| + if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) {
|
| + heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
|
| + return UNDEFINED_ELEMENT;
|
| + }
|
| + }
|
| +
|
| if (IsJSGlobalProxy()) {
|
| Object* proto = GetPrototype();
|
| - if (proto->IsNull()) return NULL;
|
| + if (proto->IsNull()) return UNDEFINED_ELEMENT;
|
| ASSERT(proto->IsJSGlobalObject());
|
| - return JSObject::cast(proto)->GetLocalElementAccessorPair(index);
|
| + return JSObject::cast(proto)->GetLocalElementKind(index);
|
| }
|
|
|
| - // Check for lookup interceptor.
|
| - if (HasIndexedInterceptor()) return NULL;
|
| + // Check for lookup interceptor
|
| + if (HasIndexedInterceptor()) {
|
| + return GetElementAttributeWithInterceptor(this, index, false) != ABSENT
|
| + ? INTERCEPTED_ELEMENT : UNDEFINED_ELEMENT;
|
| + }
|
|
|
| - return GetElementsAccessor()->GetAccessorPair(this, this, index);
|
| + // Handle [] on String objects.
|
| + if (this->IsStringObjectWithCharacterAt(index)) {
|
| + return STRING_CHARACTER_ELEMENT;
|
| + }
|
| +
|
| + switch (GetElementsKind()) {
|
| + case FAST_SMI_ELEMENTS:
|
| + case FAST_ELEMENTS:
|
| + case FAST_HOLEY_SMI_ELEMENTS:
|
| + case FAST_HOLEY_ELEMENTS: {
|
| + uint32_t length = IsJSArray() ?
|
| + static_cast<uint32_t>
|
| + (Smi::cast(JSArray::cast(this)->length())->value()) :
|
| + static_cast<uint32_t>(FixedArray::cast(elements())->length());
|
| + if ((index < length) &&
|
| + !FixedArray::cast(elements())->get(index)->IsTheHole()) {
|
| + return FAST_ELEMENT;
|
| + }
|
| + break;
|
| + }
|
| + case FAST_DOUBLE_ELEMENTS:
|
| + case FAST_HOLEY_DOUBLE_ELEMENTS: {
|
| + uint32_t length = IsJSArray() ?
|
| + static_cast<uint32_t>
|
| + (Smi::cast(JSArray::cast(this)->length())->value()) :
|
| + static_cast<uint32_t>(FixedDoubleArray::cast(elements())->length());
|
| + if ((index < length) &&
|
| + !FixedDoubleArray::cast(elements())->is_the_hole(index)) {
|
| + return FAST_ELEMENT;
|
| + }
|
| + break;
|
| + }
|
| + case EXTERNAL_PIXEL_ELEMENTS: {
|
| + ExternalPixelArray* pixels = ExternalPixelArray::cast(elements());
|
| + if (index < static_cast<uint32_t>(pixels->length())) return FAST_ELEMENT;
|
| + break;
|
| + }
|
| + case EXTERNAL_BYTE_ELEMENTS:
|
| + case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
|
| + case EXTERNAL_SHORT_ELEMENTS:
|
| + case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
|
| + case EXTERNAL_INT_ELEMENTS:
|
| + case EXTERNAL_UNSIGNED_INT_ELEMENTS:
|
| + case EXTERNAL_FLOAT_ELEMENTS:
|
| + case EXTERNAL_DOUBLE_ELEMENTS: {
|
| + ExternalArray* array = ExternalArray::cast(elements());
|
| + if (index < static_cast<uint32_t>(array->length())) return FAST_ELEMENT;
|
| + break;
|
| + }
|
| + case DICTIONARY_ELEMENTS: {
|
| + if (element_dictionary()->FindEntry(index) !=
|
| + SeededNumberDictionary::kNotFound) {
|
| + return DICTIONARY_ELEMENT;
|
| + }
|
| + break;
|
| + }
|
| + case NON_STRICT_ARGUMENTS_ELEMENTS: {
|
| + // Aliased parameters and non-aliased elements in a fast backing store
|
| + // behave as FAST_ELEMENT. Non-aliased elements in a dictionary
|
| + // backing store behave as DICTIONARY_ELEMENT.
|
| + FixedArray* parameter_map = FixedArray::cast(elements());
|
| + uint32_t length = parameter_map->length();
|
| + Object* probe =
|
| + index < (length - 2) ? parameter_map->get(index + 2) : NULL;
|
| + if (probe != NULL && !probe->IsTheHole()) return FAST_ELEMENT;
|
| + // If not aliased, check the arguments.
|
| + FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
|
| + if (arguments->IsDictionary()) {
|
| + SeededNumberDictionary* dictionary =
|
| + SeededNumberDictionary::cast(arguments);
|
| + if (dictionary->FindEntry(index) != SeededNumberDictionary::kNotFound) {
|
| + return DICTIONARY_ELEMENT;
|
| + }
|
| + } else {
|
| + length = arguments->length();
|
| + probe = (index < length) ? arguments->get(index) : NULL;
|
| + if (probe != NULL && !probe->IsTheHole()) return FAST_ELEMENT;
|
| + }
|
| + break;
|
| + }
|
| + }
|
| +
|
| + return UNDEFINED_ELEMENT;
|
| }
|
|
|
|
|
|
|