Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(258)

Side by Side Diff: src/objects.cc

Issue 348313002: Introduce a PrototypeIterator template and use it all over the place (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: rebase Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698