| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/allocation-site-scopes.h" | 8 #include "src/allocation-site-scopes.h" |
| 9 #include "src/api.h" | 9 #include "src/api.h" |
| 10 #include "src/arguments.h" | 10 #include "src/arguments.h" |
| (...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 794 return map() != fun->initial_map() | 794 return map() != fun->initial_map() |
| 795 || !HasFastObjectElements() | 795 || !HasFastObjectElements() |
| 796 || !HasFastProperties(); | 796 || !HasFastProperties(); |
| 797 } | 797 } |
| 798 | 798 |
| 799 | 799 |
| 800 MaybeHandle<Object> Object::GetElementWithReceiver(Isolate* isolate, | 800 MaybeHandle<Object> Object::GetElementWithReceiver(Isolate* isolate, |
| 801 Handle<Object> object, | 801 Handle<Object> object, |
| 802 Handle<Object> receiver, | 802 Handle<Object> receiver, |
| 803 uint32_t index) { | 803 uint32_t index) { |
| 804 Handle<Object> holder; | |
| 805 | |
| 806 // Iterate up the prototype chain until an element is found or the null | 804 // Iterate up the prototype chain until an element is found or the null |
| 807 // prototype is encountered. | 805 // prototype is encountered. |
| 808 for (holder = object; | 806 for (PrototypeIterator<STORE_AS_HANDLE, TYPE_BASED_WALK, END_AT_NULL_VALUE> |
| 809 !holder->IsNull(); | 807 iter(isolate, object); !iter.IsAtEnd(); iter.Advance()) { |
| 810 holder = Handle<Object>(holder->GetPrototype(isolate), isolate)) { | 808 if (!iter.GetCurrent()->IsJSObject()) { |
| 811 if (!holder->IsJSObject()) { | 809 if (iter.GetCurrent()->IsJSProxy()) { |
| 812 if (holder->IsJSProxy()) { | |
| 813 return JSProxy::GetElementWithHandler( | 810 return JSProxy::GetElementWithHandler( |
| 814 Handle<JSProxy>::cast(holder), receiver, index); | 811 Handle<JSProxy>::cast(iter.GetCurrent()), receiver, index); |
| 815 } else if (holder->IsUndefined()) { | 812 } else if (iter.GetCurrent()->IsUndefined()) { |
| 816 // Undefined has no indexed properties. | 813 // Undefined has no indexed properties. |
| 817 return isolate->factory()->undefined_value(); | 814 return isolate->factory()->undefined_value(); |
| 818 } else { | 815 } else { |
| 819 holder = Handle<Object>(holder->GetPrototype(isolate), isolate); | 816 iter.Advance(); |
| 820 ASSERT(holder->IsJSObject()); | 817 ASSERT(iter.GetCurrent()->IsJSObject()); |
| 821 } | 818 } |
| 822 } | 819 } |
| 823 | 820 |
| 824 // Inline the case for JSObjects. Doing so significantly improves the | 821 // Inline the case for JSObjects. Doing so significantly improves the |
| 825 // performance of fetching elements where checking the prototype chain is | 822 // performance of fetching elements where checking the prototype chain is |
| 826 // necessary. | 823 // necessary. |
| 827 Handle<JSObject> js_object = Handle<JSObject>::cast(holder); | 824 Handle<JSObject> js_object = Handle<JSObject>::cast(iter.GetCurrent()); |
| 828 | 825 |
| 829 // Check access rights if needed. | 826 // Check access rights if needed. |
| 830 if (js_object->IsAccessCheckNeeded()) { | 827 if (js_object->IsAccessCheckNeeded()) { |
| 831 if (!isolate->MayIndexedAccess(js_object, index, v8::ACCESS_GET)) { | 828 if (!isolate->MayIndexedAccess(js_object, index, v8::ACCESS_GET)) { |
| 832 isolate->ReportFailedAccessCheck(js_object, v8::ACCESS_GET); | 829 isolate->ReportFailedAccessCheck(js_object, v8::ACCESS_GET); |
| 833 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 830 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 834 return isolate->factory()->undefined_value(); | 831 return isolate->factory()->undefined_value(); |
| 835 } | 832 } |
| 836 } | 833 } |
| 837 | 834 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 881 if (heap_object->IsBoolean()) { | 878 if (heap_object->IsBoolean()) { |
| 882 return context->boolean_function()->instance_prototype(); | 879 return context->boolean_function()->instance_prototype(); |
| 883 } else { | 880 } else { |
| 884 return isolate->heap()->null_value(); | 881 return isolate->heap()->null_value(); |
| 885 } | 882 } |
| 886 } | 883 } |
| 887 | 884 |
| 888 | 885 |
| 889 Handle<Object> Object::GetPrototype(Isolate* isolate, | 886 Handle<Object> Object::GetPrototype(Isolate* isolate, |
| 890 Handle<Object> object) { | 887 Handle<Object> object) { |
| 891 return handle(object->GetPrototype(isolate), isolate); | 888 return handle(SAFE_GET_PROTOTYPE(isolate, *object), isolate); |
| 892 } | 889 } |
| 893 | 890 |
| 894 | 891 |
| 895 Object* Object::GetHash() { | 892 Object* Object::GetHash() { |
| 896 // The object is either a number, a name, an odd-ball, | 893 // The object is either a number, a name, an odd-ball, |
| 897 // a real JS object, or a Harmony proxy. | 894 // a real JS object, or a Harmony proxy. |
| 898 if (IsNumber()) { | 895 if (IsNumber()) { |
| 899 uint32_t hash = ComputeLongHash(double_to_uint64(Number())); | 896 uint32_t hash = ComputeLongHash(double_to_uint64(Number())); |
| 900 return Smi::FromInt(hash & Smi::kMaxValue); | 897 return Smi::FromInt(hash & Smi::kMaxValue); |
| 901 } | 898 } |
| (...skipping 2065 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2967 } | 2964 } |
| 2968 | 2965 |
| 2969 | 2966 |
| 2970 MaybeHandle<Object> JSObject::SetElementWithCallbackSetterInPrototypes( | 2967 MaybeHandle<Object> JSObject::SetElementWithCallbackSetterInPrototypes( |
| 2971 Handle<JSObject> object, | 2968 Handle<JSObject> object, |
| 2972 uint32_t index, | 2969 uint32_t index, |
| 2973 Handle<Object> value, | 2970 Handle<Object> value, |
| 2974 bool* found, | 2971 bool* found, |
| 2975 StrictMode strict_mode) { | 2972 StrictMode strict_mode) { |
| 2976 Isolate *isolate = object->GetIsolate(); | 2973 Isolate *isolate = object->GetIsolate(); |
| 2977 for (Handle<Object> proto = handle(object->GetPrototype(), isolate); | 2974 for (PrototypeIterator<STORE_AS_HANDLE, TYPE_BASED_WALK, END_AT_NULL_VALUE> |
| 2978 !proto->IsNull(); | 2975 iter(isolate, handle(SAFE_GET_PROTOTYPE(isolate, *object), isolate)); |
| 2979 proto = handle(proto->GetPrototype(isolate), isolate)) { | 2976 !iter.IsAtEnd(); iter.Advance()) { |
| 2980 if (proto->IsJSProxy()) { | 2977 if (iter.GetCurrent()->IsJSProxy()) { |
| 2981 return JSProxy::SetPropertyViaPrototypesWithHandler( | 2978 return JSProxy::SetPropertyViaPrototypesWithHandler( |
| 2982 Handle<JSProxy>::cast(proto), | 2979 Handle<JSProxy>::cast(iter.GetCurrent()), |
| 2983 object, | 2980 object, |
| 2984 isolate->factory()->Uint32ToString(index), // name | 2981 isolate->factory()->Uint32ToString(index), // name |
| 2985 value, | 2982 value, |
| 2986 NONE, | 2983 NONE, |
| 2987 strict_mode, | 2984 strict_mode, |
| 2988 found); | 2985 found); |
| 2989 } | 2986 } |
| 2990 Handle<JSObject> js_proto = Handle<JSObject>::cast(proto); | 2987 Handle<JSObject> js_proto = Handle<JSObject>::cast(iter.GetCurrent()); |
| 2991 if (!js_proto->HasDictionaryElements()) { | 2988 if (!js_proto->HasDictionaryElements()) { |
| 2992 continue; | 2989 continue; |
| 2993 } | 2990 } |
| 2994 Handle<SeededNumberDictionary> dictionary(js_proto->element_dictionary()); | 2991 Handle<SeededNumberDictionary> dictionary(js_proto->element_dictionary()); |
| 2995 int entry = dictionary->FindEntry(index); | 2992 int entry = dictionary->FindEntry(index); |
| 2996 if (entry != SeededNumberDictionary::kNotFound) { | 2993 if (entry != SeededNumberDictionary::kNotFound) { |
| 2997 PropertyDetails details = dictionary->DetailsAt(entry); | 2994 PropertyDetails details = dictionary->DetailsAt(entry); |
| 2998 if (details.type() == CALLBACKS) { | 2995 if (details.type() == CALLBACKS) { |
| 2999 *found = true; | 2996 *found = true; |
| 3000 Handle<Object> structure(dictionary->ValueAt(entry), isolate); | 2997 Handle<Object> structure(dictionary->ValueAt(entry), isolate); |
| (...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3399 ElementsKind to_kind) { | 3396 ElementsKind to_kind) { |
| 3400 Handle<Map> map(object->map()); | 3397 Handle<Map> map(object->map()); |
| 3401 return Map::TransitionElementsTo(map, to_kind); | 3398 return Map::TransitionElementsTo(map, to_kind); |
| 3402 } | 3399 } |
| 3403 | 3400 |
| 3404 | 3401 |
| 3405 void JSObject::LookupOwnRealNamedProperty(Handle<Name> name, | 3402 void JSObject::LookupOwnRealNamedProperty(Handle<Name> name, |
| 3406 LookupResult* result) { | 3403 LookupResult* result) { |
| 3407 DisallowHeapAllocation no_gc; | 3404 DisallowHeapAllocation no_gc; |
| 3408 if (IsJSGlobalProxy()) { | 3405 if (IsJSGlobalProxy()) { |
| 3409 Object* proto = GetPrototype(); | 3406 Object* proto = SAFE_GET_PROTOTYPE_FAST(this); |
| 3410 if (proto->IsNull()) return result->NotFound(); | 3407 if (proto->IsNull()) return result->NotFound(); |
| 3411 ASSERT(proto->IsJSGlobalObject()); | 3408 ASSERT(proto->IsJSGlobalObject()); |
| 3412 return JSObject::cast(proto)->LookupOwnRealNamedProperty(name, result); | 3409 return JSObject::cast(proto)->LookupOwnRealNamedProperty(name, result); |
| 3413 } | 3410 } |
| 3414 | 3411 |
| 3415 if (HasFastProperties()) { | 3412 if (HasFastProperties()) { |
| 3416 map()->LookupDescriptor(this, *name, result); | 3413 map()->LookupDescriptor(this, *name, result); |
| 3417 // A property or a map transition was found. We return all of these result | 3414 // A property or a map transition was found. We return all of these result |
| 3418 // types because LookupOwnRealNamedProperty is used when setting | 3415 // types because LookupOwnRealNamedProperty is used when setting |
| 3419 // properties where map transitions are handled. | 3416 // properties where map transitions are handled. |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3458 if (result->IsFound()) return; | 3455 if (result->IsFound()) return; |
| 3459 | 3456 |
| 3460 LookupRealNamedPropertyInPrototypes(name, result); | 3457 LookupRealNamedPropertyInPrototypes(name, result); |
| 3461 } | 3458 } |
| 3462 | 3459 |
| 3463 | 3460 |
| 3464 void JSObject::LookupRealNamedPropertyInPrototypes(Handle<Name> name, | 3461 void JSObject::LookupRealNamedPropertyInPrototypes(Handle<Name> name, |
| 3465 LookupResult* result) { | 3462 LookupResult* result) { |
| 3466 DisallowHeapAllocation no_gc; | 3463 DisallowHeapAllocation no_gc; |
| 3467 Isolate* isolate = GetIsolate(); | 3464 Isolate* isolate = GetIsolate(); |
| 3468 Heap* heap = isolate->heap(); | 3465 for (PrototypeIterator<STORE_AS_POINTER, TYPE_BASED_WALK, END_AT_NULL_VALUE> |
| 3469 for (Object* pt = GetPrototype(); | 3466 iter(isolate, SAFE_GET_PROTOTYPE_FAST(this)); !iter.IsAtEnd(); |
| 3470 pt != heap->null_value(); | 3467 iter.Advance()) { |
| 3471 pt = pt->GetPrototype(isolate)) { | 3468 if (iter.GetCurrent()->IsJSProxy()) { |
| 3472 if (pt->IsJSProxy()) { | 3469 return result->HandlerResult(JSProxy::cast(iter.GetCurrent())); |
| 3473 return result->HandlerResult(JSProxy::cast(pt)); | |
| 3474 } | 3470 } |
| 3475 JSObject::cast(pt)->LookupOwnRealNamedProperty(name, result); | 3471 JSObject::cast(iter.GetCurrent())->LookupOwnRealNamedProperty(name, result); |
| 3476 ASSERT(!(result->IsFound() && result->type() == INTERCEPTOR)); | 3472 ASSERT(!(result->IsFound() && result->type() == INTERCEPTOR)); |
| 3477 if (result->IsFound()) return; | 3473 if (result->IsFound()) return; |
| 3478 } | 3474 } |
| 3479 result->NotFound(); | 3475 result->NotFound(); |
| 3480 } | 3476 } |
| 3481 | 3477 |
| 3482 | 3478 |
| 3483 MaybeHandle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object, | 3479 MaybeHandle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object, |
| 3484 LookupResult* result, | 3480 LookupResult* result, |
| 3485 Handle<Name> key, | 3481 Handle<Name> key, |
| (...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4033 | 4029 |
| 4034 // Check access rights if needed. | 4030 // Check access rights if needed. |
| 4035 if (object->IsAccessCheckNeeded()) { | 4031 if (object->IsAccessCheckNeeded()) { |
| 4036 if (!isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) { | 4032 if (!isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) { |
| 4037 return SetPropertyWithFailedAccessCheck(object, lookup, name, value, | 4033 return SetPropertyWithFailedAccessCheck(object, lookup, name, value, |
| 4038 true, strict_mode); | 4034 true, strict_mode); |
| 4039 } | 4035 } |
| 4040 } | 4036 } |
| 4041 | 4037 |
| 4042 if (object->IsJSGlobalProxy()) { | 4038 if (object->IsJSGlobalProxy()) { |
| 4043 Handle<Object> proto(object->GetPrototype(), isolate); | 4039 Handle<Object> proto(SAFE_GET_PROTOTYPE_FAST(*object), isolate); |
| 4044 if (proto->IsNull()) return value; | 4040 if (proto->IsNull()) return value; |
| 4045 ASSERT(proto->IsJSGlobalObject()); | 4041 ASSERT(proto->IsJSGlobalObject()); |
| 4046 return SetPropertyForResult(Handle<JSObject>::cast(proto), | 4042 return SetPropertyForResult(Handle<JSObject>::cast(proto), |
| 4047 lookup, name, value, attributes, strict_mode, store_mode); | 4043 lookup, name, value, attributes, strict_mode, store_mode); |
| 4048 } | 4044 } |
| 4049 | 4045 |
| 4050 ASSERT(!lookup->IsFound() || lookup->holder() == *object || | 4046 ASSERT(!lookup->IsFound() || lookup->holder() == *object || |
| 4051 lookup->holder()->map()->is_hidden_prototype()); | 4047 lookup->holder()->map()->is_hidden_prototype()); |
| 4052 | 4048 |
| 4053 if (!lookup->IsProperty() && !object->IsJSContextExtensionObject()) { | 4049 if (!lookup->IsProperty() && !object->IsJSContextExtensionObject()) { |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4173 | 4169 |
| 4174 // Check access rights if needed. | 4170 // Check access rights if needed. |
| 4175 if (object->IsAccessCheckNeeded()) { | 4171 if (object->IsAccessCheckNeeded()) { |
| 4176 if (!isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) { | 4172 if (!isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) { |
| 4177 return SetPropertyWithFailedAccessCheck(object, &lookup, name, value, | 4173 return SetPropertyWithFailedAccessCheck(object, &lookup, name, value, |
| 4178 false, SLOPPY); | 4174 false, SLOPPY); |
| 4179 } | 4175 } |
| 4180 } | 4176 } |
| 4181 | 4177 |
| 4182 if (object->IsJSGlobalProxy()) { | 4178 if (object->IsJSGlobalProxy()) { |
| 4183 Handle<Object> proto(object->GetPrototype(), isolate); | 4179 Handle<Object> proto(SAFE_GET_PROTOTYPE_FAST(*object), isolate); |
| 4184 if (proto->IsNull()) return value; | 4180 if (proto->IsNull()) return value; |
| 4185 ASSERT(proto->IsJSGlobalObject()); | 4181 ASSERT(proto->IsJSGlobalObject()); |
| 4186 return SetOwnPropertyIgnoreAttributes(Handle<JSObject>::cast(proto), | 4182 return SetOwnPropertyIgnoreAttributes(Handle<JSObject>::cast(proto), |
| 4187 name, value, attributes, value_type, mode, extensibility_check); | 4183 name, value, attributes, value_type, mode, extensibility_check); |
| 4188 } | 4184 } |
| 4189 | 4185 |
| 4190 if (lookup.IsInterceptor() || | 4186 if (lookup.IsInterceptor() || |
| 4191 (lookup.IsDescriptorOrDictionary() && lookup.type() == CALLBACKS)) { | 4187 (lookup.IsDescriptorOrDictionary() && lookup.type() == CALLBACKS)) { |
| 4192 object->LookupOwnRealNamedProperty(name, &lookup); | 4188 object->LookupOwnRealNamedProperty(name, &lookup); |
| 4193 } | 4189 } |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4406 // Check access rights if needed. | 4402 // Check access rights if needed. |
| 4407 if (object->IsAccessCheckNeeded()) { | 4403 if (object->IsAccessCheckNeeded()) { |
| 4408 if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_HAS)) { | 4404 if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_HAS)) { |
| 4409 isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS); | 4405 isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS); |
| 4410 // TODO(yangguo): Issue 3269, check for scheduled exception missing? | 4406 // TODO(yangguo): Issue 3269, check for scheduled exception missing? |
| 4411 return ABSENT; | 4407 return ABSENT; |
| 4412 } | 4408 } |
| 4413 } | 4409 } |
| 4414 | 4410 |
| 4415 if (object->IsJSGlobalProxy()) { | 4411 if (object->IsJSGlobalProxy()) { |
| 4416 Handle<Object> proto(object->GetPrototype(), isolate); | 4412 Handle<Object> proto(SAFE_GET_PROTOTYPE_FAST(*object), isolate); |
| 4417 if (proto->IsNull()) return ABSENT; | 4413 if (proto->IsNull()) return ABSENT; |
| 4418 ASSERT(proto->IsJSGlobalObject()); | 4414 ASSERT(proto->IsJSGlobalObject()); |
| 4419 return JSObject::GetElementAttributeWithReceiver( | 4415 return JSObject::GetElementAttributeWithReceiver( |
| 4420 Handle<JSObject>::cast(proto), receiver, index, check_prototype); | 4416 Handle<JSObject>::cast(proto), receiver, index, check_prototype); |
| 4421 } | 4417 } |
| 4422 | 4418 |
| 4423 // Check for lookup interceptor except when bootstrapping. | 4419 // Check for lookup interceptor except when bootstrapping. |
| 4424 if (object->HasIndexedInterceptor() && !isolate->bootstrapper()->IsActive()) { | 4420 if (object->HasIndexedInterceptor() && !isolate->bootstrapper()->IsActive()) { |
| 4425 return JSObject::GetElementAttributeWithInterceptor( | 4421 return JSObject::GetElementAttributeWithInterceptor( |
| 4426 object, receiver, index, check_prototype); | 4422 object, receiver, index, check_prototype); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4478 receiver, object, index); | 4474 receiver, object, index); |
| 4479 if (attr != ABSENT) return attr; | 4475 if (attr != ABSENT) return attr; |
| 4480 | 4476 |
| 4481 // Handle [] on String objects. | 4477 // Handle [] on String objects. |
| 4482 if (object->IsStringObjectWithCharacterAt(index)) { | 4478 if (object->IsStringObjectWithCharacterAt(index)) { |
| 4483 return static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE); | 4479 return static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE); |
| 4484 } | 4480 } |
| 4485 | 4481 |
| 4486 if (!check_prototype) return ABSENT; | 4482 if (!check_prototype) return ABSENT; |
| 4487 | 4483 |
| 4488 Handle<Object> proto(object->GetPrototype(), object->GetIsolate()); | 4484 Handle<Object> proto(SAFE_GET_PROTOTYPE_FAST(*object), object->GetIsolate()); |
| 4489 if (proto->IsJSProxy()) { | 4485 if (proto->IsJSProxy()) { |
| 4490 // We need to follow the spec and simulate a call to [[GetOwnProperty]]. | 4486 // We need to follow the spec and simulate a call to [[GetOwnProperty]]. |
| 4491 return JSProxy::GetElementAttributeWithHandler( | 4487 return JSProxy::GetElementAttributeWithHandler( |
| 4492 Handle<JSProxy>::cast(proto), receiver, index); | 4488 Handle<JSProxy>::cast(proto), receiver, index); |
| 4493 } | 4489 } |
| 4494 if (proto->IsNull()) return ABSENT; | 4490 if (proto->IsNull()) return ABSENT; |
| 4495 return GetElementAttributeWithReceiver( | 4491 return GetElementAttributeWithReceiver( |
| 4496 Handle<JSObject>::cast(proto), receiver, index, true); | 4492 Handle<JSObject>::cast(proto), receiver, index, true); |
| 4497 } | 4493 } |
| 4498 | 4494 |
| (...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4948 } | 4944 } |
| 4949 | 4945 |
| 4950 | 4946 |
| 4951 Object* JSObject::GetHiddenProperty(Handle<Name> key) { | 4947 Object* JSObject::GetHiddenProperty(Handle<Name> key) { |
| 4952 DisallowHeapAllocation no_gc; | 4948 DisallowHeapAllocation no_gc; |
| 4953 ASSERT(key->IsUniqueName()); | 4949 ASSERT(key->IsUniqueName()); |
| 4954 if (IsJSGlobalProxy()) { | 4950 if (IsJSGlobalProxy()) { |
| 4955 // JSGlobalProxies store their hash internally. | 4951 // JSGlobalProxies store their hash internally. |
| 4956 ASSERT(*key != GetHeap()->identity_hash_string()); | 4952 ASSERT(*key != GetHeap()->identity_hash_string()); |
| 4957 // For a proxy, use the prototype as target object. | 4953 // For a proxy, use the prototype as target object. |
| 4958 Object* proxy_parent = GetPrototype(); | 4954 Object* proxy_parent = SAFE_GET_PROTOTYPE_FAST(this); |
| 4959 // If the proxy is detached, return undefined. | 4955 // If the proxy is detached, return undefined. |
| 4960 if (proxy_parent->IsNull()) return GetHeap()->the_hole_value(); | 4956 if (proxy_parent->IsNull()) return GetHeap()->the_hole_value(); |
| 4961 ASSERT(proxy_parent->IsJSGlobalObject()); | 4957 ASSERT(proxy_parent->IsJSGlobalObject()); |
| 4962 return JSObject::cast(proxy_parent)->GetHiddenProperty(key); | 4958 return JSObject::cast(proxy_parent)->GetHiddenProperty(key); |
| 4963 } | 4959 } |
| 4964 ASSERT(!IsJSGlobalProxy()); | 4960 ASSERT(!IsJSGlobalProxy()); |
| 4965 Object* inline_value = GetHiddenPropertiesHashTable(); | 4961 Object* inline_value = GetHiddenPropertiesHashTable(); |
| 4966 | 4962 |
| 4967 if (inline_value->IsSmi()) { | 4963 if (inline_value->IsSmi()) { |
| 4968 // Handle inline-stored identity hash. | 4964 // Handle inline-stored identity hash. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 4984 Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> object, | 4980 Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> object, |
| 4985 Handle<Name> key, | 4981 Handle<Name> key, |
| 4986 Handle<Object> value) { | 4982 Handle<Object> value) { |
| 4987 Isolate* isolate = object->GetIsolate(); | 4983 Isolate* isolate = object->GetIsolate(); |
| 4988 | 4984 |
| 4989 ASSERT(key->IsUniqueName()); | 4985 ASSERT(key->IsUniqueName()); |
| 4990 if (object->IsJSGlobalProxy()) { | 4986 if (object->IsJSGlobalProxy()) { |
| 4991 // JSGlobalProxies store their hash internally. | 4987 // JSGlobalProxies store their hash internally. |
| 4992 ASSERT(*key != *isolate->factory()->identity_hash_string()); | 4988 ASSERT(*key != *isolate->factory()->identity_hash_string()); |
| 4993 // For a proxy, use the prototype as target object. | 4989 // For a proxy, use the prototype as target object. |
| 4994 Handle<Object> proxy_parent(object->GetPrototype(), isolate); | 4990 Handle<Object> proxy_parent(SAFE_GET_PROTOTYPE_FAST(*object), isolate); |
| 4995 // If the proxy is detached, return undefined. | 4991 // If the proxy is detached, return undefined. |
| 4996 if (proxy_parent->IsNull()) return isolate->factory()->undefined_value(); | 4992 if (proxy_parent->IsNull()) return isolate->factory()->undefined_value(); |
| 4997 ASSERT(proxy_parent->IsJSGlobalObject()); | 4993 ASSERT(proxy_parent->IsJSGlobalObject()); |
| 4998 return SetHiddenProperty(Handle<JSObject>::cast(proxy_parent), key, value); | 4994 return SetHiddenProperty(Handle<JSObject>::cast(proxy_parent), key, value); |
| 4999 } | 4995 } |
| 5000 ASSERT(!object->IsJSGlobalProxy()); | 4996 ASSERT(!object->IsJSGlobalProxy()); |
| 5001 | 4997 |
| 5002 Handle<Object> inline_value(object->GetHiddenPropertiesHashTable(), isolate); | 4998 Handle<Object> inline_value(object->GetHiddenPropertiesHashTable(), isolate); |
| 5003 | 4999 |
| 5004 // If there is no backing store yet, store the identity hash inline. | 5000 // If there is no backing store yet, store the identity hash inline. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 5023 // Return this to mark success. | 5019 // Return this to mark success. |
| 5024 return object; | 5020 return object; |
| 5025 } | 5021 } |
| 5026 | 5022 |
| 5027 | 5023 |
| 5028 void JSObject::DeleteHiddenProperty(Handle<JSObject> object, Handle<Name> key) { | 5024 void JSObject::DeleteHiddenProperty(Handle<JSObject> object, Handle<Name> key) { |
| 5029 Isolate* isolate = object->GetIsolate(); | 5025 Isolate* isolate = object->GetIsolate(); |
| 5030 ASSERT(key->IsUniqueName()); | 5026 ASSERT(key->IsUniqueName()); |
| 5031 | 5027 |
| 5032 if (object->IsJSGlobalProxy()) { | 5028 if (object->IsJSGlobalProxy()) { |
| 5033 Handle<Object> proto(object->GetPrototype(), isolate); | 5029 Handle<Object> proto(SAFE_GET_PROTOTYPE_FAST(*object), isolate); |
| 5034 if (proto->IsNull()) return; | 5030 if (proto->IsNull()) return; |
| 5035 ASSERT(proto->IsJSGlobalObject()); | 5031 ASSERT(proto->IsJSGlobalObject()); |
| 5036 return DeleteHiddenProperty(Handle<JSObject>::cast(proto), key); | 5032 return DeleteHiddenProperty(Handle<JSObject>::cast(proto), key); |
| 5037 } | 5033 } |
| 5038 | 5034 |
| 5039 Object* inline_value = object->GetHiddenPropertiesHashTable(); | 5035 Object* inline_value = object->GetHiddenPropertiesHashTable(); |
| 5040 | 5036 |
| 5041 // We never delete (inline-stored) identity hashes. | 5037 // We never delete (inline-stored) identity hashes. |
| 5042 ASSERT(*key != *isolate->factory()->identity_hash_string()); | 5038 ASSERT(*key != *isolate->factory()->identity_hash_string()); |
| 5043 if (inline_value->IsUndefined() || inline_value->IsSmi()) return; | 5039 if (inline_value->IsUndefined() || inline_value->IsSmi()) return; |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5266 Handle<Object> error = | 5262 Handle<Object> error = |
| 5267 factory->NewTypeError("strict_delete_property", | 5263 factory->NewTypeError("strict_delete_property", |
| 5268 HandleVector(args, 2)); | 5264 HandleVector(args, 2)); |
| 5269 isolate->Throw(*error); | 5265 isolate->Throw(*error); |
| 5270 return Handle<Object>(); | 5266 return Handle<Object>(); |
| 5271 } | 5267 } |
| 5272 return factory->false_value(); | 5268 return factory->false_value(); |
| 5273 } | 5269 } |
| 5274 | 5270 |
| 5275 if (object->IsJSGlobalProxy()) { | 5271 if (object->IsJSGlobalProxy()) { |
| 5276 Handle<Object> proto(object->GetPrototype(), isolate); | 5272 Handle<Object> proto(SAFE_GET_PROTOTYPE_FAST(*object), isolate); |
| 5277 if (proto->IsNull()) return factory->false_value(); | 5273 if (proto->IsNull()) return factory->false_value(); |
| 5278 ASSERT(proto->IsJSGlobalObject()); | 5274 ASSERT(proto->IsJSGlobalObject()); |
| 5279 return DeleteElement(Handle<JSObject>::cast(proto), index, mode); | 5275 return DeleteElement(Handle<JSObject>::cast(proto), index, mode); |
| 5280 } | 5276 } |
| 5281 | 5277 |
| 5282 Handle<Object> old_value; | 5278 Handle<Object> old_value; |
| 5283 bool should_enqueue_change_record = false; | 5279 bool should_enqueue_change_record = false; |
| 5284 if (object->map()->is_observed()) { | 5280 if (object->map()->is_observed()) { |
| 5285 should_enqueue_change_record = HasOwnElement(object, index); | 5281 should_enqueue_change_record = HasOwnElement(object, index); |
| 5286 if (should_enqueue_change_record) { | 5282 if (should_enqueue_change_record) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5321 | 5317 |
| 5322 // Check access rights if needed. | 5318 // Check access rights if needed. |
| 5323 if (object->IsAccessCheckNeeded() && | 5319 if (object->IsAccessCheckNeeded() && |
| 5324 !isolate->MayNamedAccess(object, name, v8::ACCESS_DELETE)) { | 5320 !isolate->MayNamedAccess(object, name, v8::ACCESS_DELETE)) { |
| 5325 isolate->ReportFailedAccessCheck(object, v8::ACCESS_DELETE); | 5321 isolate->ReportFailedAccessCheck(object, v8::ACCESS_DELETE); |
| 5326 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 5322 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 5327 return isolate->factory()->false_value(); | 5323 return isolate->factory()->false_value(); |
| 5328 } | 5324 } |
| 5329 | 5325 |
| 5330 if (object->IsJSGlobalProxy()) { | 5326 if (object->IsJSGlobalProxy()) { |
| 5331 Object* proto = object->GetPrototype(); | 5327 Object* proto = SAFE_GET_PROTOTYPE_FAST(*object); |
| 5332 if (proto->IsNull()) return isolate->factory()->false_value(); | 5328 if (proto->IsNull()) return isolate->factory()->false_value(); |
| 5333 ASSERT(proto->IsJSGlobalObject()); | 5329 ASSERT(proto->IsJSGlobalObject()); |
| 5334 return JSGlobalObject::DeleteProperty( | 5330 return JSGlobalObject::DeleteProperty( |
| 5335 handle(JSGlobalObject::cast(proto)), name, mode); | 5331 handle(JSGlobalObject::cast(proto)), name, mode); |
| 5336 } | 5332 } |
| 5337 | 5333 |
| 5338 uint32_t index = 0; | 5334 uint32_t index = 0; |
| 5339 if (name->AsArrayIndex(&index)) { | 5335 if (name->AsArrayIndex(&index)) { |
| 5340 return DeleteElement(object, index, mode); | 5336 return DeleteElement(object, index, mode); |
| 5341 } | 5337 } |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5555 | 5551 |
| 5556 if (object->IsAccessCheckNeeded() && | 5552 if (object->IsAccessCheckNeeded() && |
| 5557 !isolate->MayNamedAccess( | 5553 !isolate->MayNamedAccess( |
| 5558 object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { | 5554 object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { |
| 5559 isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS); | 5555 isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS); |
| 5560 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 5556 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 5561 return isolate->factory()->false_value(); | 5557 return isolate->factory()->false_value(); |
| 5562 } | 5558 } |
| 5563 | 5559 |
| 5564 if (object->IsJSGlobalProxy()) { | 5560 if (object->IsJSGlobalProxy()) { |
| 5565 Handle<Object> proto(object->GetPrototype(), isolate); | 5561 Handle<Object> proto(SAFE_GET_PROTOTYPE_FAST(*object), isolate); |
| 5566 if (proto->IsNull()) return object; | 5562 if (proto->IsNull()) return object; |
| 5567 ASSERT(proto->IsJSGlobalObject()); | 5563 ASSERT(proto->IsJSGlobalObject()); |
| 5568 return PreventExtensions(Handle<JSObject>::cast(proto)); | 5564 return PreventExtensions(Handle<JSObject>::cast(proto)); |
| 5569 } | 5565 } |
| 5570 | 5566 |
| 5571 // It's not possible to seal objects with external array elements | 5567 // It's not possible to seal objects with external array elements |
| 5572 if (object->HasExternalArrayElements() || | 5568 if (object->HasExternalArrayElements() || |
| 5573 object->HasFixedTypedArrayElements()) { | 5569 object->HasFixedTypedArrayElements()) { |
| 5574 Handle<Object> error = | 5570 Handle<Object> error = |
| 5575 isolate->factory()->NewTypeError( | 5571 isolate->factory()->NewTypeError( |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5637 Isolate* isolate = object->GetIsolate(); | 5633 Isolate* isolate = object->GetIsolate(); |
| 5638 if (object->IsAccessCheckNeeded() && | 5634 if (object->IsAccessCheckNeeded() && |
| 5639 !isolate->MayNamedAccess( | 5635 !isolate->MayNamedAccess( |
| 5640 object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { | 5636 object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { |
| 5641 isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS); | 5637 isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS); |
| 5642 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 5638 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 5643 return isolate->factory()->false_value(); | 5639 return isolate->factory()->false_value(); |
| 5644 } | 5640 } |
| 5645 | 5641 |
| 5646 if (object->IsJSGlobalProxy()) { | 5642 if (object->IsJSGlobalProxy()) { |
| 5647 Handle<Object> proto(object->GetPrototype(), isolate); | 5643 Handle<Object> proto(SAFE_GET_PROTOTYPE_FAST(*object), isolate); |
| 5648 if (proto->IsNull()) return object; | 5644 if (proto->IsNull()) return object; |
| 5649 ASSERT(proto->IsJSGlobalObject()); | 5645 ASSERT(proto->IsJSGlobalObject()); |
| 5650 return Freeze(Handle<JSObject>::cast(proto)); | 5646 return Freeze(Handle<JSObject>::cast(proto)); |
| 5651 } | 5647 } |
| 5652 | 5648 |
| 5653 // It's not possible to freeze objects with external array elements | 5649 // It's not possible to freeze objects with external array elements |
| 5654 if (object->HasExternalArrayElements() || | 5650 if (object->HasExternalArrayElements() || |
| 5655 object->HasFixedTypedArrayElements()) { | 5651 object->HasFixedTypedArrayElements()) { |
| 5656 Handle<Object> error = | 5652 Handle<Object> error = |
| 5657 isolate->factory()->NewTypeError( | 5653 isolate->factory()->NewTypeError( |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6026 return result; | 6022 return result; |
| 6027 } | 6023 } |
| 6028 | 6024 |
| 6029 | 6025 |
| 6030 // Tests for the fast common case for property enumeration: | 6026 // Tests for the fast common case for property enumeration: |
| 6031 // - This object and all prototypes has an enum cache (which means that | 6027 // - This object and all prototypes has an enum cache (which means that |
| 6032 // it is no proxy, has no interceptors and needs no access checks). | 6028 // it is no proxy, has no interceptors and needs no access checks). |
| 6033 // - This object has no elements. | 6029 // - This object has no elements. |
| 6034 // - No prototype has enumerable properties/elements. | 6030 // - No prototype has enumerable properties/elements. |
| 6035 bool JSReceiver::IsSimpleEnum() { | 6031 bool JSReceiver::IsSimpleEnum() { |
| 6036 Heap* heap = GetHeap(); | 6032 for (PrototypeIterator<STORE_AS_POINTER, MAP_BASED_WALK, END_AT_NULL_VALUE> |
| 6037 for (Object* o = this; | 6033 iter(this); !iter.IsAtEnd(); iter.Advance()) { |
| 6038 o != heap->null_value(); | 6034 if (!iter.GetCurrent()->IsJSObject()) return false; |
| 6039 o = JSObject::cast(o)->GetPrototype()) { | 6035 JSObject* curr = JSObject::cast(iter.GetCurrent()); |
| 6040 if (!o->IsJSObject()) return false; | |
| 6041 JSObject* curr = JSObject::cast(o); | |
| 6042 int enum_length = curr->map()->EnumLength(); | 6036 int enum_length = curr->map()->EnumLength(); |
| 6043 if (enum_length == kInvalidEnumCacheSentinel) return false; | 6037 if (enum_length == kInvalidEnumCacheSentinel) return false; |
| 6044 if (curr->IsAccessCheckNeeded()) return false; | 6038 if (curr->IsAccessCheckNeeded()) return false; |
| 6045 ASSERT(!curr->HasNamedInterceptor()); | 6039 ASSERT(!curr->HasNamedInterceptor()); |
| 6046 ASSERT(!curr->HasIndexedInterceptor()); | 6040 ASSERT(!curr->HasIndexedInterceptor()); |
| 6047 if (curr->NumberOfEnumElements() > 0) return false; | 6041 if (curr->NumberOfEnumElements() > 0) return false; |
| 6048 if (curr != this && enum_length != 0) return false; | 6042 if (curr != this && enum_length != 0) return false; |
| 6049 } | 6043 } |
| 6050 return true; | 6044 return true; |
| 6051 } | 6045 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6099 return max_index + 1; | 6093 return max_index + 1; |
| 6100 } | 6094 } |
| 6101 | 6095 |
| 6102 | 6096 |
| 6103 void JSReceiver::LookupOwn( | 6097 void JSReceiver::LookupOwn( |
| 6104 Handle<Name> name, LookupResult* result, bool search_hidden_prototypes) { | 6098 Handle<Name> name, LookupResult* result, bool search_hidden_prototypes) { |
| 6105 DisallowHeapAllocation no_gc; | 6099 DisallowHeapAllocation no_gc; |
| 6106 ASSERT(name->IsName()); | 6100 ASSERT(name->IsName()); |
| 6107 | 6101 |
| 6108 if (IsJSGlobalProxy()) { | 6102 if (IsJSGlobalProxy()) { |
| 6109 Object* proto = GetPrototype(); | 6103 Object* proto = SAFE_GET_PROTOTYPE_FAST(this); |
| 6110 if (proto->IsNull()) return result->NotFound(); | 6104 if (proto->IsNull()) return result->NotFound(); |
| 6111 ASSERT(proto->IsJSGlobalObject()); | 6105 ASSERT(proto->IsJSGlobalObject()); |
| 6112 return JSReceiver::cast(proto)->LookupOwn( | 6106 return JSReceiver::cast(proto)->LookupOwn( |
| 6113 name, result, search_hidden_prototypes); | 6107 name, result, search_hidden_prototypes); |
| 6114 } | 6108 } |
| 6115 | 6109 |
| 6116 if (IsJSProxy()) { | 6110 if (IsJSProxy()) { |
| 6117 result->HandlerResult(JSProxy::cast(this)); | 6111 result->HandlerResult(JSProxy::cast(this)); |
| 6118 return; | 6112 return; |
| 6119 } | 6113 } |
| 6120 | 6114 |
| 6121 // Do not use inline caching if the object is a non-global object | 6115 // Do not use inline caching if the object is a non-global object |
| 6122 // that requires access checks. | 6116 // that requires access checks. |
| 6123 if (IsAccessCheckNeeded()) { | 6117 if (IsAccessCheckNeeded()) { |
| 6124 result->DisallowCaching(); | 6118 result->DisallowCaching(); |
| 6125 } | 6119 } |
| 6126 | 6120 |
| 6127 JSObject* js_object = JSObject::cast(this); | 6121 JSObject* js_object = JSObject::cast(this); |
| 6128 | 6122 |
| 6129 // Check for lookup interceptor except when bootstrapping. | 6123 // Check for lookup interceptor except when bootstrapping. |
| 6130 if (js_object->HasNamedInterceptor() && | 6124 if (js_object->HasNamedInterceptor() && |
| 6131 !GetIsolate()->bootstrapper()->IsActive()) { | 6125 !GetIsolate()->bootstrapper()->IsActive()) { |
| 6132 result->InterceptorResult(js_object); | 6126 result->InterceptorResult(js_object); |
| 6133 return; | 6127 return; |
| 6134 } | 6128 } |
| 6135 | 6129 |
| 6136 js_object->LookupOwnRealNamedProperty(name, result); | 6130 js_object->LookupOwnRealNamedProperty(name, result); |
| 6137 if (result->IsFound() || !search_hidden_prototypes) return; | 6131 if (result->IsFound() || !search_hidden_prototypes) return; |
| 6138 | 6132 |
| 6139 Object* proto = js_object->GetPrototype(); | 6133 Object* proto = SAFE_GET_PROTOTYPE_FAST(js_object); |
| 6140 if (!proto->IsJSReceiver()) return; | 6134 if (!proto->IsJSReceiver()) return; |
| 6141 JSReceiver* receiver = JSReceiver::cast(proto); | 6135 JSReceiver* receiver = JSReceiver::cast(proto); |
| 6142 if (receiver->map()->is_hidden_prototype()) { | 6136 if (receiver->map()->is_hidden_prototype()) { |
| 6143 receiver->LookupOwn(name, result, search_hidden_prototypes); | 6137 receiver->LookupOwn(name, result, search_hidden_prototypes); |
| 6144 } | 6138 } |
| 6145 } | 6139 } |
| 6146 | 6140 |
| 6147 | 6141 |
| 6148 void JSReceiver::Lookup(Handle<Name> name, LookupResult* result) { | 6142 void JSReceiver::Lookup(Handle<Name> name, LookupResult* result) { |
| 6149 DisallowHeapAllocation no_gc; | 6143 DisallowHeapAllocation no_gc; |
| 6150 // Ecma-262 3rd 8.6.2.4 | 6144 // Ecma-262 3rd 8.6.2.4 |
| 6151 Handle<Object> null_value = GetIsolate()->factory()->null_value(); | 6145 for (PrototypeIterator<STORE_AS_POINTER, MAP_BASED_WALK, END_AT_NULL_VALUE> |
| 6152 for (Object* current = this; | 6146 iter(this); !iter.IsAtEnd(); iter.Advance()) { |
| 6153 current != *null_value; | 6147 JSReceiver::cast(iter.GetCurrent())->LookupOwn(name, result, false); |
| 6154 current = JSObject::cast(current)->GetPrototype()) { | |
| 6155 JSReceiver::cast(current)->LookupOwn(name, result, false); | |
| 6156 if (result->IsFound()) return; | 6148 if (result->IsFound()) return; |
| 6157 } | 6149 } |
| 6158 result->NotFound(); | 6150 result->NotFound(); |
| 6159 } | 6151 } |
| 6160 | 6152 |
| 6161 | 6153 |
| 6162 static bool ContainsOnlyValidKeys(Handle<FixedArray> array) { | 6154 static bool ContainsOnlyValidKeys(Handle<FixedArray> array) { |
| 6163 int len = array->length(); | 6155 int len = array->length(); |
| 6164 for (int i = 0; i < len; i++) { | 6156 for (int i = 0; i < len; i++) { |
| 6165 Object* e = array->get(i); | 6157 Object* e = array->get(i); |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6285 Isolate* isolate = object->GetIsolate(); | 6277 Isolate* isolate = object->GetIsolate(); |
| 6286 Handle<FixedArray> content = isolate->factory()->empty_fixed_array(); | 6278 Handle<FixedArray> content = isolate->factory()->empty_fixed_array(); |
| 6287 Handle<JSObject> arguments_boilerplate = Handle<JSObject>( | 6279 Handle<JSObject> arguments_boilerplate = Handle<JSObject>( |
| 6288 isolate->context()->native_context()->sloppy_arguments_boilerplate(), | 6280 isolate->context()->native_context()->sloppy_arguments_boilerplate(), |
| 6289 isolate); | 6281 isolate); |
| 6290 Handle<JSFunction> arguments_function = Handle<JSFunction>( | 6282 Handle<JSFunction> arguments_function = Handle<JSFunction>( |
| 6291 JSFunction::cast(arguments_boilerplate->map()->constructor()), | 6283 JSFunction::cast(arguments_boilerplate->map()->constructor()), |
| 6292 isolate); | 6284 isolate); |
| 6293 | 6285 |
| 6294 // Only collect keys if access is permitted. | 6286 // Only collect keys if access is permitted. |
| 6295 for (Handle<Object> p = object; | 6287 for (PrototypeIterator<STORE_AS_HANDLE, TYPE_BASED_WALK, END_AT_NULL_VALUE> |
| 6296 *p != isolate->heap()->null_value(); | 6288 iter(isolate, object); !iter.IsAtEnd(); iter.Advance()) { |
| 6297 p = Handle<Object>(p->GetPrototype(isolate), isolate)) { | 6289 if (iter.GetCurrent()->IsJSProxy()) { |
| 6298 if (p->IsJSProxy()) { | 6290 Handle<JSProxy> proxy(JSProxy::cast(*iter.GetCurrent()), isolate); |
| 6299 Handle<JSProxy> proxy(JSProxy::cast(*p), isolate); | |
| 6300 Handle<Object> args[] = { proxy }; | 6291 Handle<Object> args[] = { proxy }; |
| 6301 Handle<Object> names; | 6292 Handle<Object> names; |
| 6302 ASSIGN_RETURN_ON_EXCEPTION( | 6293 ASSIGN_RETURN_ON_EXCEPTION( |
| 6303 isolate, names, | 6294 isolate, names, |
| 6304 Execution::Call(isolate, | 6295 Execution::Call(isolate, |
| 6305 isolate->proxy_enumerate(), | 6296 isolate->proxy_enumerate(), |
| 6306 object, | 6297 object, |
| 6307 ARRAY_SIZE(args), | 6298 ARRAY_SIZE(args), |
| 6308 args), | 6299 args), |
| 6309 FixedArray); | 6300 FixedArray); |
| 6310 ASSIGN_RETURN_ON_EXCEPTION( | 6301 ASSIGN_RETURN_ON_EXCEPTION( |
| 6311 isolate, content, | 6302 isolate, content, |
| 6312 FixedArray::AddKeysFromArrayLike( | 6303 FixedArray::AddKeysFromArrayLike( |
| 6313 content, Handle<JSObject>::cast(names)), | 6304 content, Handle<JSObject>::cast(names)), |
| 6314 FixedArray); | 6305 FixedArray); |
| 6315 break; | 6306 break; |
| 6316 } | 6307 } |
| 6317 | 6308 |
| 6318 Handle<JSObject> current(JSObject::cast(*p), isolate); | 6309 Handle<JSObject> current(JSObject::cast(*iter.GetCurrent()), isolate); |
| 6319 | 6310 |
| 6320 // Check access rights if required. | 6311 // Check access rights if required. |
| 6321 if (current->IsAccessCheckNeeded() && | 6312 if (current->IsAccessCheckNeeded() && |
| 6322 !isolate->MayNamedAccess( | 6313 !isolate->MayNamedAccess( |
| 6323 current, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { | 6314 current, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { |
| 6324 isolate->ReportFailedAccessCheck(current, v8::ACCESS_KEYS); | 6315 isolate->ReportFailedAccessCheck(current, v8::ACCESS_KEYS); |
| 6325 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, FixedArray); | 6316 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, FixedArray); |
| 6326 break; | 6317 break; |
| 6327 } | 6318 } |
| 6328 | 6319 |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6526 } | 6517 } |
| 6527 | 6518 |
| 6528 Handle<AccessorPair> accessors = CreateAccessorPairFor(object, name); | 6519 Handle<AccessorPair> accessors = CreateAccessorPairFor(object, name); |
| 6529 accessors->SetComponents(*getter, *setter); | 6520 accessors->SetComponents(*getter, *setter); |
| 6530 | 6521 |
| 6531 SetPropertyCallback(object, name, accessors, attributes); | 6522 SetPropertyCallback(object, name, accessors, attributes); |
| 6532 } | 6523 } |
| 6533 | 6524 |
| 6534 | 6525 |
| 6535 bool Map::DictionaryElementsInPrototypeChainOnly() { | 6526 bool Map::DictionaryElementsInPrototypeChainOnly() { |
| 6536 Heap* heap = GetHeap(); | |
| 6537 | |
| 6538 if (IsDictionaryElementsKind(elements_kind())) { | 6527 if (IsDictionaryElementsKind(elements_kind())) { |
| 6539 return false; | 6528 return false; |
| 6540 } | 6529 } |
| 6541 | 6530 |
| 6542 for (Object* prototype = this->prototype(); | 6531 for (PrototypeIterator<STORE_AS_POINTER, TYPE_BASED_WALK, END_AT_NULL_VALUE> |
| 6543 prototype != heap->null_value(); | 6532 iter(GetIsolate(), this->prototype()); !iter.IsAtEnd(); |
| 6544 prototype = prototype->GetPrototype(GetIsolate())) { | 6533 iter.Advance()) { |
| 6545 if (prototype->IsJSProxy()) { | 6534 if (iter.GetCurrent()->IsJSProxy()) { |
| 6546 // Be conservative, don't walk into proxies. | 6535 // Be conservative, don't walk into proxies. |
| 6547 return true; | 6536 return true; |
| 6548 } | 6537 } |
| 6549 | 6538 |
| 6550 if (IsDictionaryElementsKind( | 6539 if (IsDictionaryElementsKind( |
| 6551 JSObject::cast(prototype)->map()->elements_kind())) { | 6540 JSObject::cast(iter.GetCurrent())->map()->elements_kind())) { |
| 6552 return true; | 6541 return true; |
| 6553 } | 6542 } |
| 6554 } | 6543 } |
| 6555 | 6544 |
| 6556 return false; | 6545 return false; |
| 6557 } | 6546 } |
| 6558 | 6547 |
| 6559 | 6548 |
| 6560 void JSObject::SetElementCallback(Handle<JSObject> object, | 6549 void JSObject::SetElementCallback(Handle<JSObject> object, |
| 6561 uint32_t index, | 6550 uint32_t index, |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6631 Isolate* isolate = object->GetIsolate(); | 6620 Isolate* isolate = object->GetIsolate(); |
| 6632 // Check access rights if needed. | 6621 // Check access rights if needed. |
| 6633 if (object->IsAccessCheckNeeded() && | 6622 if (object->IsAccessCheckNeeded() && |
| 6634 !isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) { | 6623 !isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) { |
| 6635 isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET); | 6624 isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET); |
| 6636 // TODO(yangguo): Issue 3269, check for scheduled exception missing? | 6625 // TODO(yangguo): Issue 3269, check for scheduled exception missing? |
| 6637 return; | 6626 return; |
| 6638 } | 6627 } |
| 6639 | 6628 |
| 6640 if (object->IsJSGlobalProxy()) { | 6629 if (object->IsJSGlobalProxy()) { |
| 6641 Handle<Object> proto(object->GetPrototype(), isolate); | 6630 Handle<Object> proto(SAFE_GET_PROTOTYPE_FAST(*object), isolate); |
| 6642 if (proto->IsNull()) return; | 6631 if (proto->IsNull()) return; |
| 6643 ASSERT(proto->IsJSGlobalObject()); | 6632 ASSERT(proto->IsJSGlobalObject()); |
| 6644 DefineAccessor(Handle<JSObject>::cast(proto), | 6633 DefineAccessor(Handle<JSObject>::cast(proto), |
| 6645 name, | 6634 name, |
| 6646 getter, | 6635 getter, |
| 6647 setter, | 6636 setter, |
| 6648 attributes); | 6637 attributes); |
| 6649 return; | 6638 return; |
| 6650 } | 6639 } |
| 6651 | 6640 |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6807 | 6796 |
| 6808 // Check access rights if needed. | 6797 // Check access rights if needed. |
| 6809 if (object->IsAccessCheckNeeded() && | 6798 if (object->IsAccessCheckNeeded() && |
| 6810 !isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) { | 6799 !isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) { |
| 6811 isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET); | 6800 isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET); |
| 6812 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 6801 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 6813 return factory->undefined_value(); | 6802 return factory->undefined_value(); |
| 6814 } | 6803 } |
| 6815 | 6804 |
| 6816 if (object->IsJSGlobalProxy()) { | 6805 if (object->IsJSGlobalProxy()) { |
| 6817 Handle<Object> proto(object->GetPrototype(), isolate); | 6806 Handle<Object> proto(SAFE_GET_PROTOTYPE_FAST(*object), isolate); |
| 6818 if (proto->IsNull()) return object; | 6807 if (proto->IsNull()) return object; |
| 6819 ASSERT(proto->IsJSGlobalObject()); | 6808 ASSERT(proto->IsJSGlobalObject()); |
| 6820 return SetAccessor(Handle<JSObject>::cast(proto), info); | 6809 return SetAccessor(Handle<JSObject>::cast(proto), info); |
| 6821 } | 6810 } |
| 6822 | 6811 |
| 6823 // Make sure that the top context does not change when doing callbacks or | 6812 // Make sure that the top context does not change when doing callbacks or |
| 6824 // interceptor calls. | 6813 // interceptor calls. |
| 6825 AssertNoContextChange ncc(isolate); | 6814 AssertNoContextChange ncc(isolate); |
| 6826 | 6815 |
| 6827 // Try to flatten before operating on the string. | 6816 // Try to flatten before operating on the string. |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6891 if (object->IsAccessCheckNeeded() && | 6880 if (object->IsAccessCheckNeeded() && |
| 6892 !isolate->MayNamedAccess(object, name, v8::ACCESS_HAS)) { | 6881 !isolate->MayNamedAccess(object, name, v8::ACCESS_HAS)) { |
| 6893 isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS); | 6882 isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS); |
| 6894 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 6883 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 6895 return isolate->factory()->undefined_value(); | 6884 return isolate->factory()->undefined_value(); |
| 6896 } | 6885 } |
| 6897 | 6886 |
| 6898 // Make the lookup and include prototypes. | 6887 // Make the lookup and include prototypes. |
| 6899 uint32_t index = 0; | 6888 uint32_t index = 0; |
| 6900 if (name->AsArrayIndex(&index)) { | 6889 if (name->AsArrayIndex(&index)) { |
| 6901 for (Handle<Object> obj = object; | 6890 for (PrototypeIterator<STORE_AS_HANDLE, MAP_BASED_WALK, END_AT_NULL_VALUE> |
| 6902 !obj->IsNull(); | 6891 iter(object); !iter.IsAtEnd(); iter.Advance()) { |
| 6903 obj = handle(JSReceiver::cast(*obj)->GetPrototype(), isolate)) { | 6892 if (iter.GetCurrent()->IsJSObject() && |
| 6904 if (obj->IsJSObject() && JSObject::cast(*obj)->HasDictionaryElements()) { | 6893 JSObject::cast(*iter.GetCurrent())->HasDictionaryElements()) { |
| 6905 JSObject* js_object = JSObject::cast(*obj); | 6894 JSObject* js_object = JSObject::cast(*iter.GetCurrent()); |
| 6906 SeededNumberDictionary* dictionary = js_object->element_dictionary(); | 6895 SeededNumberDictionary* dictionary = js_object->element_dictionary(); |
| 6907 int entry = dictionary->FindEntry(index); | 6896 int entry = dictionary->FindEntry(index); |
| 6908 if (entry != SeededNumberDictionary::kNotFound) { | 6897 if (entry != SeededNumberDictionary::kNotFound) { |
| 6909 Object* element = dictionary->ValueAt(entry); | 6898 Object* element = dictionary->ValueAt(entry); |
| 6910 if (dictionary->DetailsAt(entry).type() == CALLBACKS && | 6899 if (dictionary->DetailsAt(entry).type() == CALLBACKS && |
| 6911 element->IsAccessorPair()) { | 6900 element->IsAccessorPair()) { |
| 6912 return handle(AccessorPair::cast(element)->GetComponent(component), | 6901 return handle(AccessorPair::cast(element)->GetComponent(component), |
| 6913 isolate); | 6902 isolate); |
| 6914 } | 6903 } |
| 6915 } | 6904 } |
| 6916 } | 6905 } |
| 6917 } | 6906 } |
| 6918 } else { | 6907 } else { |
| 6919 for (Handle<Object> obj = object; | 6908 for (PrototypeIterator<STORE_AS_HANDLE, MAP_BASED_WALK, END_AT_NULL_VALUE> |
| 6920 !obj->IsNull(); | 6909 iter(object); !iter.IsAtEnd(); iter.Advance()) { |
| 6921 obj = handle(JSReceiver::cast(*obj)->GetPrototype(), isolate)) { | |
| 6922 LookupResult result(isolate); | 6910 LookupResult result(isolate); |
| 6923 JSReceiver::cast(*obj)->LookupOwn(name, &result); | 6911 JSReceiver::cast(*iter.GetCurrent())->LookupOwn(name, &result); |
| 6924 if (result.IsFound()) { | 6912 if (result.IsFound()) { |
| 6925 if (result.IsReadOnly()) return isolate->factory()->undefined_value(); | 6913 if (result.IsReadOnly()) return isolate->factory()->undefined_value(); |
| 6926 if (result.IsPropertyCallbacks()) { | 6914 if (result.IsPropertyCallbacks()) { |
| 6927 Object* obj = result.GetCallbackObject(); | 6915 Object* callback = result.GetCallbackObject(); |
| 6928 if (obj->IsAccessorPair()) { | 6916 if (callback->IsAccessorPair()) { |
| 6929 return handle(AccessorPair::cast(obj)->GetComponent(component), | 6917 return handle(AccessorPair::cast(callback)->GetComponent(component), |
| 6930 isolate); | 6918 isolate); |
| 6931 } | 6919 } |
| 6932 } | 6920 } |
| 6933 } | 6921 } |
| 6934 } | 6922 } |
| 6935 } | 6923 } |
| 6936 return isolate->factory()->undefined_value(); | 6924 return isolate->factory()->undefined_value(); |
| 6937 } | 6925 } |
| 6938 | 6926 |
| 6939 | 6927 |
| (...skipping 3113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10053 instance_type = JS_OBJECT_TYPE; | 10041 instance_type = JS_OBJECT_TYPE; |
| 10054 instance_size = function->shared()->CalculateInstanceSize(); | 10042 instance_size = function->shared()->CalculateInstanceSize(); |
| 10055 in_object_properties = function->shared()->CalculateInObjectProperties(); | 10043 in_object_properties = function->shared()->CalculateInObjectProperties(); |
| 10056 } | 10044 } |
| 10057 Handle<Map> map = isolate->factory()->NewMap(instance_type, instance_size); | 10045 Handle<Map> map = isolate->factory()->NewMap(instance_type, instance_size); |
| 10058 | 10046 |
| 10059 // Fetch or allocate prototype. | 10047 // Fetch or allocate prototype. |
| 10060 Handle<Object> prototype; | 10048 Handle<Object> prototype; |
| 10061 if (function->has_instance_prototype()) { | 10049 if (function->has_instance_prototype()) { |
| 10062 prototype = handle(function->instance_prototype(), isolate); | 10050 prototype = handle(function->instance_prototype(), isolate); |
| 10063 for (Handle<Object> p = prototype; !p->IsNull() && !p->IsJSProxy(); | 10051 for (PrototypeIterator<STORE_AS_HANDLE, TYPE_BASED_WALK, END_AT_NULL_VALUE> |
| 10064 p = Object::GetPrototype(isolate, p)) { | 10052 iter(isolate, prototype); |
| 10065 JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(p)); | 10053 !iter.IsAtEnd() && !iter.GetCurrent()->IsJSProxy(); iter.Advance()) { |
| 10054 JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(iter.GetCurrent())); |
| 10066 } | 10055 } |
| 10067 } else { | 10056 } else { |
| 10068 prototype = isolate->factory()->NewFunctionPrototype(function); | 10057 prototype = isolate->factory()->NewFunctionPrototype(function); |
| 10069 } | 10058 } |
| 10070 map->set_inobject_properties(in_object_properties); | 10059 map->set_inobject_properties(in_object_properties); |
| 10071 map->set_unused_property_fields(in_object_properties); | 10060 map->set_unused_property_fields(in_object_properties); |
| 10072 map->set_prototype(*prototype); | 10061 map->set_prototype(*prototype); |
| 10073 ASSERT(map->has_fast_object_elements()); | 10062 ASSERT(map->has_fast_object_elements()); |
| 10074 | 10063 |
| 10075 // Finally link initial map and constructor function. | 10064 // Finally link initial map and constructor function. |
| (...skipping 2051 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12127 Handle<Object> args[] = { object }; | 12116 Handle<Object> args[] = { object }; |
| 12128 Handle<Object> error = isolate->factory()->NewTypeError( | 12117 Handle<Object> error = isolate->factory()->NewTypeError( |
| 12129 "non_extensible_proto", HandleVector(args, ARRAY_SIZE(args))); | 12118 "non_extensible_proto", HandleVector(args, ARRAY_SIZE(args))); |
| 12130 return isolate->Throw<Object>(error); | 12119 return isolate->Throw<Object>(error); |
| 12131 } | 12120 } |
| 12132 | 12121 |
| 12133 // Before we can set the prototype we need to be sure | 12122 // Before we can set the prototype we need to be sure |
| 12134 // prototype cycles are prevented. | 12123 // prototype cycles are prevented. |
| 12135 // It is sufficient to validate that the receiver is not in the new prototype | 12124 // It is sufficient to validate that the receiver is not in the new prototype |
| 12136 // chain. | 12125 // chain. |
| 12137 for (Object* pt = *value; | 12126 for (PrototypeIterator<STORE_AS_POINTER, TYPE_BASED_WALK, END_AT_NULL_VALUE> |
| 12138 pt != heap->null_value(); | 12127 iter(isolate, *value); !iter.IsAtEnd(); iter.Advance()) { |
| 12139 pt = pt->GetPrototype(isolate)) { | 12128 if (JSReceiver::cast(iter.GetCurrent()) == *object) { |
| 12140 if (JSReceiver::cast(pt) == *object) { | |
| 12141 // Cycle detected. | 12129 // Cycle detected. |
| 12142 Handle<Object> error = isolate->factory()->NewError( | 12130 Handle<Object> error = isolate->factory()->NewError( |
| 12143 "cyclic_proto", HandleVector<Object>(NULL, 0)); | 12131 "cyclic_proto", HandleVector<Object>(NULL, 0)); |
| 12144 return isolate->Throw<Object>(error); | 12132 return isolate->Throw<Object>(error); |
| 12145 } | 12133 } |
| 12146 } | 12134 } |
| 12147 | 12135 |
| 12148 bool dictionary_elements_in_chain = | 12136 bool dictionary_elements_in_chain = |
| 12149 object->map()->DictionaryElementsInPrototypeChainOnly(); | 12137 object->map()->DictionaryElementsInPrototypeChainOnly(); |
| 12150 Handle<JSObject> real_receiver = object; | 12138 Handle<JSObject> real_receiver = object; |
| 12151 | 12139 |
| 12152 if (skip_hidden_prototypes) { | 12140 if (skip_hidden_prototypes) { |
| 12153 // Find the first object in the chain whose prototype object is not | 12141 // Find the first object in the chain whose prototype object is not |
| 12154 // hidden and set the new prototype on that object. | 12142 // hidden and set the new prototype on that object. |
| 12155 Object* current_proto = real_receiver->GetPrototype(); | 12143 for (PrototypeIterator<STORE_AS_POINTER, TYPE_BASED_WALK, END_AT_NON_HIDDEN> |
| 12156 while (current_proto->IsJSObject() && | 12144 iter(isolate, *real_receiver); !iter.IsAtEnd(); iter.Advance()) { |
| 12157 JSObject::cast(current_proto)->map()->is_hidden_prototype()) { | 12145 real_receiver = handle(JSObject::cast(iter.GetCurrent()), isolate); |
| 12158 real_receiver = handle(JSObject::cast(current_proto), isolate); | |
| 12159 current_proto = current_proto->GetPrototype(isolate); | |
| 12160 } | 12146 } |
| 12161 } | 12147 } |
| 12162 | 12148 |
| 12163 // Set the new prototype of the object. | 12149 // Set the new prototype of the object. |
| 12164 Handle<Map> map(real_receiver->map()); | 12150 Handle<Map> map(real_receiver->map()); |
| 12165 | 12151 |
| 12166 // Nothing to do if prototype is already set. | 12152 // Nothing to do if prototype is already set. |
| 12167 if (map->prototype() == *value) return value; | 12153 if (map->prototype() == *value) return value; |
| 12168 | 12154 |
| 12169 if (value->IsJSObject()) { | 12155 if (value->IsJSObject()) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 12198 // direction. | 12184 // direction. |
| 12199 return EnsureCanContainElements( | 12185 return EnsureCanContainElements( |
| 12200 object, args->arguments() - first_arg - (arg_count - 1), arg_count, mode); | 12186 object, args->arguments() - first_arg - (arg_count - 1), arg_count, mode); |
| 12201 } | 12187 } |
| 12202 | 12188 |
| 12203 | 12189 |
| 12204 MaybeHandle<AccessorPair> JSObject::GetOwnElementAccessorPair( | 12190 MaybeHandle<AccessorPair> JSObject::GetOwnElementAccessorPair( |
| 12205 Handle<JSObject> object, | 12191 Handle<JSObject> object, |
| 12206 uint32_t index) { | 12192 uint32_t index) { |
| 12207 if (object->IsJSGlobalProxy()) { | 12193 if (object->IsJSGlobalProxy()) { |
| 12208 Handle<Object> proto(object->GetPrototype(), object->GetIsolate()); | 12194 Handle<Object> proto(SAFE_GET_PROTOTYPE_FAST(*object), |
| 12195 object->GetIsolate()); |
| 12209 if (proto->IsNull()) return MaybeHandle<AccessorPair>(); | 12196 if (proto->IsNull()) return MaybeHandle<AccessorPair>(); |
| 12210 ASSERT(proto->IsJSGlobalObject()); | 12197 ASSERT(proto->IsJSGlobalObject()); |
| 12211 return GetOwnElementAccessorPair(Handle<JSObject>::cast(proto), index); | 12198 return GetOwnElementAccessorPair(Handle<JSObject>::cast(proto), index); |
| 12212 } | 12199 } |
| 12213 | 12200 |
| 12214 // Check for lookup interceptor. | 12201 // Check for lookup interceptor. |
| 12215 if (object->HasIndexedInterceptor()) return MaybeHandle<AccessorPair>(); | 12202 if (object->HasIndexedInterceptor()) return MaybeHandle<AccessorPair>(); |
| 12216 | 12203 |
| 12217 return object->GetElementsAccessor()->GetAccessorPair(object, object, index); | 12204 return object->GetElementsAccessor()->GetAccessorPair(object, object, index); |
| 12218 } | 12205 } |
| (...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12803 // Check access rights if needed. | 12790 // Check access rights if needed. |
| 12804 if (object->IsAccessCheckNeeded()) { | 12791 if (object->IsAccessCheckNeeded()) { |
| 12805 if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_SET)) { | 12792 if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_SET)) { |
| 12806 isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET); | 12793 isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET); |
| 12807 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 12794 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 12808 return value; | 12795 return value; |
| 12809 } | 12796 } |
| 12810 } | 12797 } |
| 12811 | 12798 |
| 12812 if (object->IsJSGlobalProxy()) { | 12799 if (object->IsJSGlobalProxy()) { |
| 12813 Handle<Object> proto(object->GetPrototype(), isolate); | 12800 Handle<Object> proto(SAFE_GET_PROTOTYPE_FAST(*object), isolate); |
| 12814 if (proto->IsNull()) return value; | 12801 if (proto->IsNull()) return value; |
| 12815 ASSERT(proto->IsJSGlobalObject()); | 12802 ASSERT(proto->IsJSGlobalObject()); |
| 12816 return SetElement(Handle<JSObject>::cast(proto), index, value, attributes, | 12803 return SetElement(Handle<JSObject>::cast(proto), index, value, attributes, |
| 12817 strict_mode, | 12804 strict_mode, |
| 12818 check_prototype, | 12805 check_prototype, |
| 12819 set_mode); | 12806 set_mode); |
| 12820 } | 12807 } |
| 12821 | 12808 |
| 12822 // Don't allow element properties to be redefined for external arrays. | 12809 // Don't allow element properties to be redefined for external arrays. |
| 12823 if ((object->HasExternalArrayElements() || | 12810 if ((object->HasExternalArrayElements() || |
| (...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13307 } | 13294 } |
| 13308 } | 13295 } |
| 13309 | 13296 |
| 13310 ElementsAccessor* handler = object->GetElementsAccessor(); | 13297 ElementsAccessor* handler = object->GetElementsAccessor(); |
| 13311 Handle<Object> result; | 13298 Handle<Object> result; |
| 13312 ASSIGN_RETURN_ON_EXCEPTION( | 13299 ASSIGN_RETURN_ON_EXCEPTION( |
| 13313 isolate, result, handler->Get(receiver, object, index), | 13300 isolate, result, handler->Get(receiver, object, index), |
| 13314 Object); | 13301 Object); |
| 13315 if (!result->IsTheHole()) return result; | 13302 if (!result->IsTheHole()) return result; |
| 13316 | 13303 |
| 13317 Handle<Object> proto(object->GetPrototype(), isolate); | 13304 Handle<Object> proto(SAFE_GET_PROTOTYPE_FAST(*object), isolate); |
| 13318 if (proto->IsNull()) return isolate->factory()->undefined_value(); | 13305 if (proto->IsNull()) return isolate->factory()->undefined_value(); |
| 13319 return Object::GetElementWithReceiver(isolate, proto, receiver, index); | 13306 return Object::GetElementWithReceiver(isolate, proto, receiver, index); |
| 13320 } | 13307 } |
| 13321 | 13308 |
| 13322 | 13309 |
| 13323 bool JSObject::HasDenseElements() { | 13310 bool JSObject::HasDenseElements() { |
| 13324 int capacity = 0; | 13311 int capacity = 0; |
| 13325 int used = 0; | 13312 int used = 0; |
| 13326 GetElementsCapacityAndUsage(&capacity, &used); | 13313 GetElementsCapacityAndUsage(&capacity, &used); |
| 13327 return (capacity == 0) || (used > (capacity / 2)); | 13314 return (capacity == 0) || (used > (capacity / 2)); |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13672 if (object->IsAccessCheckNeeded()) { | 13659 if (object->IsAccessCheckNeeded()) { |
| 13673 if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_HAS)) { | 13660 if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_HAS)) { |
| 13674 isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS); | 13661 isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS); |
| 13675 // TODO(yangguo): Issue 3269, check for scheduled exception missing? | 13662 // TODO(yangguo): Issue 3269, check for scheduled exception missing? |
| 13676 return false; | 13663 return false; |
| 13677 } | 13664 } |
| 13678 } | 13665 } |
| 13679 | 13666 |
| 13680 if (object->IsJSGlobalProxy()) { | 13667 if (object->IsJSGlobalProxy()) { |
| 13681 HandleScope scope(isolate); | 13668 HandleScope scope(isolate); |
| 13682 Handle<Object> proto(object->GetPrototype(), isolate); | 13669 Handle<Object> proto(SAFE_GET_PROTOTYPE_FAST(*object), isolate); |
| 13683 if (proto->IsNull()) return false; | 13670 if (proto->IsNull()) return false; |
| 13684 ASSERT(proto->IsJSGlobalObject()); | 13671 ASSERT(proto->IsJSGlobalObject()); |
| 13685 return HasRealElementProperty(Handle<JSObject>::cast(proto), index); | 13672 return HasRealElementProperty(Handle<JSObject>::cast(proto), index); |
| 13686 } | 13673 } |
| 13687 | 13674 |
| 13688 return GetElementAttributeWithoutInterceptor( | 13675 return GetElementAttributeWithoutInterceptor( |
| 13689 object, object, index, false) != ABSENT; | 13676 object, object, index, false) != ABSENT; |
| 13690 } | 13677 } |
| 13691 | 13678 |
| 13692 | 13679 |
| (...skipping 3265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16958 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16945 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 16959 static const char* error_messages_[] = { | 16946 static const char* error_messages_[] = { |
| 16960 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16947 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 16961 }; | 16948 }; |
| 16962 #undef ERROR_MESSAGES_TEXTS | 16949 #undef ERROR_MESSAGES_TEXTS |
| 16963 return error_messages_[reason]; | 16950 return error_messages_[reason]; |
| 16964 } | 16951 } |
| 16965 | 16952 |
| 16966 | 16953 |
| 16967 } } // namespace v8::internal | 16954 } } // namespace v8::internal |
| OLD | NEW |