| 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 3431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3442 ElementsKind to_kind) { | 3442 ElementsKind to_kind) { |
| 3443 Handle<Map> map(object->map()); | 3443 Handle<Map> map(object->map()); |
| 3444 return Map::TransitionElementsTo(map, to_kind); | 3444 return Map::TransitionElementsTo(map, to_kind); |
| 3445 } | 3445 } |
| 3446 | 3446 |
| 3447 | 3447 |
| 3448 void JSObject::LookupOwnRealNamedProperty(Handle<Name> name, | 3448 void JSObject::LookupOwnRealNamedProperty(Handle<Name> name, |
| 3449 LookupResult* result) { | 3449 LookupResult* result) { |
| 3450 DisallowHeapAllocation no_gc; | 3450 DisallowHeapAllocation no_gc; |
| 3451 if (IsJSGlobalProxy()) { | 3451 if (IsJSGlobalProxy()) { |
| 3452 Object* proto = GetPrototype(); | 3452 PrototypeIterator iter(GetIsolate(), this); |
| 3453 if (proto->IsNull()) return result->NotFound(); | 3453 if (iter.IsAtEnd()) return result->NotFound(); |
| 3454 ASSERT(proto->IsJSGlobalObject()); | 3454 ASSERT(iter.GetCurrent()->IsJSGlobalObject()); |
| 3455 return JSObject::cast(proto)->LookupOwnRealNamedProperty(name, result); | 3455 return JSObject::cast(iter.GetCurrent()) |
| 3456 ->LookupOwnRealNamedProperty(name, result); |
| 3456 } | 3457 } |
| 3457 | 3458 |
| 3458 if (HasFastProperties()) { | 3459 if (HasFastProperties()) { |
| 3459 map()->LookupDescriptor(this, *name, result); | 3460 map()->LookupDescriptor(this, *name, result); |
| 3460 // A property or a map transition was found. We return all of these result | 3461 // A property or a map transition was found. We return all of these result |
| 3461 // types because LookupOwnRealNamedProperty is used when setting | 3462 // types because LookupOwnRealNamedProperty is used when setting |
| 3462 // properties where map transitions are handled. | 3463 // properties where map transitions are handled. |
| 3463 ASSERT(!result->IsFound() || | 3464 ASSERT(!result->IsFound() || |
| 3464 (result->holder() == this && result->IsFastPropertyType())); | 3465 (result->holder() == this && result->IsFastPropertyType())); |
| 3465 // Disallow caching for uninitialized constants. These can only | 3466 // Disallow caching for uninitialized constants. These can only |
| (...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4069 | 4070 |
| 4070 // Check access rights if needed. | 4071 // Check access rights if needed. |
| 4071 if (object->IsAccessCheckNeeded()) { | 4072 if (object->IsAccessCheckNeeded()) { |
| 4072 if (!isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) { | 4073 if (!isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) { |
| 4073 return SetPropertyWithFailedAccessCheck(object, lookup, name, value, | 4074 return SetPropertyWithFailedAccessCheck(object, lookup, name, value, |
| 4074 true, strict_mode); | 4075 true, strict_mode); |
| 4075 } | 4076 } |
| 4076 } | 4077 } |
| 4077 | 4078 |
| 4078 if (object->IsJSGlobalProxy()) { | 4079 if (object->IsJSGlobalProxy()) { |
| 4079 Handle<Object> proto(object->GetPrototype(), isolate); | 4080 PrototypeIterator iter(isolate, object); |
| 4080 if (proto->IsNull()) return value; | 4081 if (iter.IsAtEnd()) return value; |
| 4081 ASSERT(proto->IsJSGlobalObject()); | 4082 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
| 4082 return SetPropertyForResult(Handle<JSObject>::cast(proto), lookup, name, | 4083 return SetPropertyForResult( |
| 4083 value, strict_mode, store_mode); | 4084 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), lookup, |
| 4085 name, value, strict_mode, store_mode); |
| 4084 } | 4086 } |
| 4085 | 4087 |
| 4086 ASSERT(!lookup->IsFound() || lookup->holder() == *object || | 4088 ASSERT(!lookup->IsFound() || lookup->holder() == *object || |
| 4087 lookup->holder()->map()->is_hidden_prototype()); | 4089 lookup->holder()->map()->is_hidden_prototype()); |
| 4088 | 4090 |
| 4089 if (!lookup->IsProperty() && !object->IsJSContextExtensionObject()) { | 4091 if (!lookup->IsProperty() && !object->IsJSContextExtensionObject()) { |
| 4090 bool done = false; | 4092 bool done = false; |
| 4091 Handle<Object> result_object; | 4093 Handle<Object> result_object; |
| 4092 ASSIGN_RETURN_ON_EXCEPTION( | 4094 ASSIGN_RETURN_ON_EXCEPTION( |
| 4093 isolate, result_object, | 4095 isolate, result_object, |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4223 | 4225 |
| 4224 // Check access rights if needed. | 4226 // Check access rights if needed. |
| 4225 if (object->IsAccessCheckNeeded()) { | 4227 if (object->IsAccessCheckNeeded()) { |
| 4226 if (!isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) { | 4228 if (!isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) { |
| 4227 return SetPropertyWithFailedAccessCheck(object, &lookup, name, value, | 4229 return SetPropertyWithFailedAccessCheck(object, &lookup, name, value, |
| 4228 false, SLOPPY); | 4230 false, SLOPPY); |
| 4229 } | 4231 } |
| 4230 } | 4232 } |
| 4231 | 4233 |
| 4232 if (object->IsJSGlobalProxy()) { | 4234 if (object->IsJSGlobalProxy()) { |
| 4233 Handle<Object> proto(object->GetPrototype(), isolate); | 4235 PrototypeIterator iter(isolate, object); |
| 4234 if (proto->IsNull()) return value; | 4236 if (iter.IsAtEnd()) return value; |
| 4235 ASSERT(proto->IsJSGlobalObject()); | 4237 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
| 4236 return SetOwnPropertyIgnoreAttributes(Handle<JSObject>::cast(proto), name, | 4238 return SetOwnPropertyIgnoreAttributes( |
| 4237 value, attributes, mode, | 4239 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), name, |
| 4238 extensibility_check); | 4240 value, attributes, mode, extensibility_check); |
| 4239 } | 4241 } |
| 4240 | 4242 |
| 4241 if (lookup.IsInterceptor() || | 4243 if (lookup.IsInterceptor() || |
| 4242 (lookup.IsDescriptorOrDictionary() && lookup.type() == CALLBACKS)) { | 4244 (lookup.IsDescriptorOrDictionary() && lookup.type() == CALLBACKS)) { |
| 4243 object->LookupOwnRealNamedProperty(name, &lookup); | 4245 object->LookupOwnRealNamedProperty(name, &lookup); |
| 4244 } | 4246 } |
| 4245 | 4247 |
| 4246 // Check for accessor in prototype chain removed here in clone. | 4248 // Check for accessor in prototype chain removed here in clone. |
| 4247 if (!lookup.IsFound()) { | 4249 if (!lookup.IsFound()) { |
| 4248 object->map()->LookupTransition(*object, *name, &lookup); | 4250 object->map()->LookupTransition(*object, *name, &lookup); |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4458 // Check access rights if needed. | 4460 // Check access rights if needed. |
| 4459 if (object->IsAccessCheckNeeded()) { | 4461 if (object->IsAccessCheckNeeded()) { |
| 4460 if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_HAS)) { | 4462 if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_HAS)) { |
| 4461 isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS); | 4463 isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS); |
| 4462 // TODO(yangguo): Issue 3269, check for scheduled exception missing? | 4464 // TODO(yangguo): Issue 3269, check for scheduled exception missing? |
| 4463 return ABSENT; | 4465 return ABSENT; |
| 4464 } | 4466 } |
| 4465 } | 4467 } |
| 4466 | 4468 |
| 4467 if (object->IsJSGlobalProxy()) { | 4469 if (object->IsJSGlobalProxy()) { |
| 4468 Handle<Object> proto(object->GetPrototype(), isolate); | 4470 PrototypeIterator iter(isolate, object); |
| 4469 if (proto->IsNull()) return ABSENT; | 4471 if (iter.IsAtEnd()) return ABSENT; |
| 4470 ASSERT(proto->IsJSGlobalObject()); | 4472 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
| 4471 return JSObject::GetElementAttributeWithReceiver( | 4473 return JSObject::GetElementAttributeWithReceiver( |
| 4472 Handle<JSObject>::cast(proto), receiver, index, check_prototype); | 4474 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), receiver, |
| 4475 index, check_prototype); |
| 4473 } | 4476 } |
| 4474 | 4477 |
| 4475 // Check for lookup interceptor except when bootstrapping. | 4478 // Check for lookup interceptor except when bootstrapping. |
| 4476 if (object->HasIndexedInterceptor() && !isolate->bootstrapper()->IsActive()) { | 4479 if (object->HasIndexedInterceptor() && !isolate->bootstrapper()->IsActive()) { |
| 4477 return JSObject::GetElementAttributeWithInterceptor( | 4480 return JSObject::GetElementAttributeWithInterceptor( |
| 4478 object, receiver, index, check_prototype); | 4481 object, receiver, index, check_prototype); |
| 4479 } | 4482 } |
| 4480 | 4483 |
| 4481 return GetElementAttributeWithoutInterceptor( | 4484 return GetElementAttributeWithoutInterceptor( |
| 4482 object, receiver, index, check_prototype); | 4485 object, receiver, index, check_prototype); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4530 receiver, object, index); | 4533 receiver, object, index); |
| 4531 if (attr != ABSENT) return attr; | 4534 if (attr != ABSENT) return attr; |
| 4532 | 4535 |
| 4533 // Handle [] on String objects. | 4536 // Handle [] on String objects. |
| 4534 if (object->IsStringObjectWithCharacterAt(index)) { | 4537 if (object->IsStringObjectWithCharacterAt(index)) { |
| 4535 return static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE); | 4538 return static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE); |
| 4536 } | 4539 } |
| 4537 | 4540 |
| 4538 if (!check_prototype) return ABSENT; | 4541 if (!check_prototype) return ABSENT; |
| 4539 | 4542 |
| 4540 Handle<Object> proto(object->GetPrototype(), object->GetIsolate()); | 4543 PrototypeIterator iter(object->GetIsolate(), object); |
| 4541 if (proto->IsJSProxy()) { | 4544 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) { |
| 4542 // We need to follow the spec and simulate a call to [[GetOwnProperty]]. | 4545 // We need to follow the spec and simulate a call to [[GetOwnProperty]]. |
| 4543 return JSProxy::GetElementAttributeWithHandler( | 4546 return JSProxy::GetElementAttributeWithHandler( |
| 4544 Handle<JSProxy>::cast(proto), receiver, index); | 4547 Handle<JSProxy>::cast(PrototypeIterator::GetCurrent(iter)), receiver, |
| 4548 index); |
| 4545 } | 4549 } |
| 4546 if (proto->IsNull()) return ABSENT; | 4550 if (iter.IsAtEnd()) return ABSENT; |
| 4547 return GetElementAttributeWithReceiver( | 4551 return GetElementAttributeWithReceiver( |
| 4548 Handle<JSObject>::cast(proto), receiver, index, true); | 4552 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), receiver, |
| 4553 index, true); |
| 4549 } | 4554 } |
| 4550 | 4555 |
| 4551 | 4556 |
| 4552 Handle<NormalizedMapCache> NormalizedMapCache::New(Isolate* isolate) { | 4557 Handle<NormalizedMapCache> NormalizedMapCache::New(Isolate* isolate) { |
| 4553 Handle<FixedArray> array( | 4558 Handle<FixedArray> array( |
| 4554 isolate->factory()->NewFixedArray(kEntries, TENURED)); | 4559 isolate->factory()->NewFixedArray(kEntries, TENURED)); |
| 4555 return Handle<NormalizedMapCache>::cast(array); | 4560 return Handle<NormalizedMapCache>::cast(array); |
| 4556 } | 4561 } |
| 4557 | 4562 |
| 4558 | 4563 |
| (...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5016 } | 5021 } |
| 5017 | 5022 |
| 5018 | 5023 |
| 5019 Object* JSObject::GetHiddenProperty(Handle<Name> key) { | 5024 Object* JSObject::GetHiddenProperty(Handle<Name> key) { |
| 5020 DisallowHeapAllocation no_gc; | 5025 DisallowHeapAllocation no_gc; |
| 5021 ASSERT(key->IsUniqueName()); | 5026 ASSERT(key->IsUniqueName()); |
| 5022 if (IsJSGlobalProxy()) { | 5027 if (IsJSGlobalProxy()) { |
| 5023 // JSGlobalProxies store their hash internally. | 5028 // JSGlobalProxies store their hash internally. |
| 5024 ASSERT(*key != GetHeap()->identity_hash_string()); | 5029 ASSERT(*key != GetHeap()->identity_hash_string()); |
| 5025 // For a proxy, use the prototype as target object. | 5030 // For a proxy, use the prototype as target object. |
| 5026 Object* proxy_parent = GetPrototype(); | 5031 PrototypeIterator iter(GetIsolate(), this); |
| 5027 // If the proxy is detached, return undefined. | 5032 // If the proxy is detached, return undefined. |
| 5028 if (proxy_parent->IsNull()) return GetHeap()->the_hole_value(); | 5033 if (iter.IsAtEnd()) return GetHeap()->the_hole_value(); |
| 5029 ASSERT(proxy_parent->IsJSGlobalObject()); | 5034 ASSERT(iter.GetCurrent()->IsJSGlobalObject()); |
| 5030 return JSObject::cast(proxy_parent)->GetHiddenProperty(key); | 5035 return JSObject::cast(iter.GetCurrent())->GetHiddenProperty(key); |
| 5031 } | 5036 } |
| 5032 ASSERT(!IsJSGlobalProxy()); | 5037 ASSERT(!IsJSGlobalProxy()); |
| 5033 Object* inline_value = GetHiddenPropertiesHashTable(); | 5038 Object* inline_value = GetHiddenPropertiesHashTable(); |
| 5034 | 5039 |
| 5035 if (inline_value->IsSmi()) { | 5040 if (inline_value->IsSmi()) { |
| 5036 // Handle inline-stored identity hash. | 5041 // Handle inline-stored identity hash. |
| 5037 if (*key == GetHeap()->identity_hash_string()) { | 5042 if (*key == GetHeap()->identity_hash_string()) { |
| 5038 return inline_value; | 5043 return inline_value; |
| 5039 } else { | 5044 } else { |
| 5040 return GetHeap()->the_hole_value(); | 5045 return GetHeap()->the_hole_value(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 5052 Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> object, | 5057 Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> object, |
| 5053 Handle<Name> key, | 5058 Handle<Name> key, |
| 5054 Handle<Object> value) { | 5059 Handle<Object> value) { |
| 5055 Isolate* isolate = object->GetIsolate(); | 5060 Isolate* isolate = object->GetIsolate(); |
| 5056 | 5061 |
| 5057 ASSERT(key->IsUniqueName()); | 5062 ASSERT(key->IsUniqueName()); |
| 5058 if (object->IsJSGlobalProxy()) { | 5063 if (object->IsJSGlobalProxy()) { |
| 5059 // JSGlobalProxies store their hash internally. | 5064 // JSGlobalProxies store their hash internally. |
| 5060 ASSERT(*key != *isolate->factory()->identity_hash_string()); | 5065 ASSERT(*key != *isolate->factory()->identity_hash_string()); |
| 5061 // For a proxy, use the prototype as target object. | 5066 // For a proxy, use the prototype as target object. |
| 5062 Handle<Object> proxy_parent(object->GetPrototype(), isolate); | 5067 PrototypeIterator iter(isolate, object); |
| 5063 // If the proxy is detached, return undefined. | 5068 // If the proxy is detached, return undefined. |
| 5064 if (proxy_parent->IsNull()) return isolate->factory()->undefined_value(); | 5069 if (iter.IsAtEnd()) return isolate->factory()->undefined_value(); |
| 5065 ASSERT(proxy_parent->IsJSGlobalObject()); | 5070 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
| 5066 return SetHiddenProperty(Handle<JSObject>::cast(proxy_parent), key, value); | 5071 return SetHiddenProperty( |
| 5072 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), key, |
| 5073 value); |
| 5067 } | 5074 } |
| 5068 ASSERT(!object->IsJSGlobalProxy()); | 5075 ASSERT(!object->IsJSGlobalProxy()); |
| 5069 | 5076 |
| 5070 Handle<Object> inline_value(object->GetHiddenPropertiesHashTable(), isolate); | 5077 Handle<Object> inline_value(object->GetHiddenPropertiesHashTable(), isolate); |
| 5071 | 5078 |
| 5072 // If there is no backing store yet, store the identity hash inline. | 5079 // If there is no backing store yet, store the identity hash inline. |
| 5073 if (value->IsSmi() && | 5080 if (value->IsSmi() && |
| 5074 *key == *isolate->factory()->identity_hash_string() && | 5081 *key == *isolate->factory()->identity_hash_string() && |
| 5075 (inline_value->IsUndefined() || inline_value->IsSmi())) { | 5082 (inline_value->IsUndefined() || inline_value->IsSmi())) { |
| 5076 return JSObject::SetHiddenPropertiesHashTable(object, value); | 5083 return JSObject::SetHiddenPropertiesHashTable(object, value); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 5091 // Return this to mark success. | 5098 // Return this to mark success. |
| 5092 return object; | 5099 return object; |
| 5093 } | 5100 } |
| 5094 | 5101 |
| 5095 | 5102 |
| 5096 void JSObject::DeleteHiddenProperty(Handle<JSObject> object, Handle<Name> key) { | 5103 void JSObject::DeleteHiddenProperty(Handle<JSObject> object, Handle<Name> key) { |
| 5097 Isolate* isolate = object->GetIsolate(); | 5104 Isolate* isolate = object->GetIsolate(); |
| 5098 ASSERT(key->IsUniqueName()); | 5105 ASSERT(key->IsUniqueName()); |
| 5099 | 5106 |
| 5100 if (object->IsJSGlobalProxy()) { | 5107 if (object->IsJSGlobalProxy()) { |
| 5101 Handle<Object> proto(object->GetPrototype(), isolate); | 5108 PrototypeIterator iter(isolate, object); |
| 5102 if (proto->IsNull()) return; | 5109 if (iter.IsAtEnd()) return; |
| 5103 ASSERT(proto->IsJSGlobalObject()); | 5110 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
| 5104 return DeleteHiddenProperty(Handle<JSObject>::cast(proto), key); | 5111 return DeleteHiddenProperty( |
| 5112 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), key); |
| 5105 } | 5113 } |
| 5106 | 5114 |
| 5107 Object* inline_value = object->GetHiddenPropertiesHashTable(); | 5115 Object* inline_value = object->GetHiddenPropertiesHashTable(); |
| 5108 | 5116 |
| 5109 // We never delete (inline-stored) identity hashes. | 5117 // We never delete (inline-stored) identity hashes. |
| 5110 ASSERT(*key != *isolate->factory()->identity_hash_string()); | 5118 ASSERT(*key != *isolate->factory()->identity_hash_string()); |
| 5111 if (inline_value->IsUndefined() || inline_value->IsSmi()) return; | 5119 if (inline_value->IsUndefined() || inline_value->IsSmi()) return; |
| 5112 | 5120 |
| 5113 Handle<ObjectHashTable> hashtable(ObjectHashTable::cast(inline_value)); | 5121 Handle<ObjectHashTable> hashtable(ObjectHashTable::cast(inline_value)); |
| 5114 bool was_present = false; | 5122 bool was_present = false; |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5325 Handle<Object> error = | 5333 Handle<Object> error = |
| 5326 factory->NewTypeError("strict_delete_property", | 5334 factory->NewTypeError("strict_delete_property", |
| 5327 HandleVector(args, 2)); | 5335 HandleVector(args, 2)); |
| 5328 isolate->Throw(*error); | 5336 isolate->Throw(*error); |
| 5329 return Handle<Object>(); | 5337 return Handle<Object>(); |
| 5330 } | 5338 } |
| 5331 return factory->false_value(); | 5339 return factory->false_value(); |
| 5332 } | 5340 } |
| 5333 | 5341 |
| 5334 if (object->IsJSGlobalProxy()) { | 5342 if (object->IsJSGlobalProxy()) { |
| 5335 Handle<Object> proto(object->GetPrototype(), isolate); | 5343 PrototypeIterator iter(isolate, object); |
| 5336 if (proto->IsNull()) return factory->false_value(); | 5344 if (iter.IsAtEnd()) return factory->false_value(); |
| 5337 ASSERT(proto->IsJSGlobalObject()); | 5345 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
| 5338 return DeleteElement(Handle<JSObject>::cast(proto), index, mode); | 5346 return DeleteElement( |
| 5347 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), index, |
| 5348 mode); |
| 5339 } | 5349 } |
| 5340 | 5350 |
| 5341 Handle<Object> old_value; | 5351 Handle<Object> old_value; |
| 5342 bool should_enqueue_change_record = false; | 5352 bool should_enqueue_change_record = false; |
| 5343 if (object->map()->is_observed()) { | 5353 if (object->map()->is_observed()) { |
| 5344 should_enqueue_change_record = HasOwnElement(object, index); | 5354 should_enqueue_change_record = HasOwnElement(object, index); |
| 5345 if (should_enqueue_change_record) { | 5355 if (should_enqueue_change_record) { |
| 5346 if (!GetOwnElementAccessorPair(object, index).is_null()) { | 5356 if (!GetOwnElementAccessorPair(object, index).is_null()) { |
| 5347 old_value = Handle<Object>::cast(factory->the_hole_value()); | 5357 old_value = Handle<Object>::cast(factory->the_hole_value()); |
| 5348 } else { | 5358 } else { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5380 | 5390 |
| 5381 // Check access rights if needed. | 5391 // Check access rights if needed. |
| 5382 if (object->IsAccessCheckNeeded() && | 5392 if (object->IsAccessCheckNeeded() && |
| 5383 !isolate->MayNamedAccess(object, name, v8::ACCESS_DELETE)) { | 5393 !isolate->MayNamedAccess(object, name, v8::ACCESS_DELETE)) { |
| 5384 isolate->ReportFailedAccessCheck(object, v8::ACCESS_DELETE); | 5394 isolate->ReportFailedAccessCheck(object, v8::ACCESS_DELETE); |
| 5385 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 5395 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 5386 return isolate->factory()->false_value(); | 5396 return isolate->factory()->false_value(); |
| 5387 } | 5397 } |
| 5388 | 5398 |
| 5389 if (object->IsJSGlobalProxy()) { | 5399 if (object->IsJSGlobalProxy()) { |
| 5390 Object* proto = object->GetPrototype(); | 5400 PrototypeIterator iter(isolate, object); |
| 5391 if (proto->IsNull()) return isolate->factory()->false_value(); | 5401 if (iter.IsAtEnd()) return isolate->factory()->false_value(); |
| 5392 ASSERT(proto->IsJSGlobalObject()); | 5402 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
| 5393 return JSGlobalObject::DeleteProperty( | 5403 return JSGlobalObject::DeleteProperty( |
| 5394 handle(JSGlobalObject::cast(proto)), name, mode); | 5404 Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter)), name, |
| 5405 mode); |
| 5395 } | 5406 } |
| 5396 | 5407 |
| 5397 uint32_t index = 0; | 5408 uint32_t index = 0; |
| 5398 if (name->AsArrayIndex(&index)) { | 5409 if (name->AsArrayIndex(&index)) { |
| 5399 return DeleteElement(object, index, mode); | 5410 return DeleteElement(object, index, mode); |
| 5400 } | 5411 } |
| 5401 | 5412 |
| 5402 LookupResult lookup(isolate); | 5413 LookupResult lookup(isolate); |
| 5403 object->LookupOwn(name, &lookup, true); | 5414 object->LookupOwn(name, &lookup, true); |
| 5404 if (!lookup.IsFound()) return isolate->factory()->true_value(); | 5415 if (!lookup.IsFound()) return isolate->factory()->true_value(); |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5613 | 5624 |
| 5614 if (object->IsAccessCheckNeeded() && | 5625 if (object->IsAccessCheckNeeded() && |
| 5615 !isolate->MayNamedAccess( | 5626 !isolate->MayNamedAccess( |
| 5616 object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { | 5627 object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { |
| 5617 isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS); | 5628 isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS); |
| 5618 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 5629 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 5619 return isolate->factory()->false_value(); | 5630 return isolate->factory()->false_value(); |
| 5620 } | 5631 } |
| 5621 | 5632 |
| 5622 if (object->IsJSGlobalProxy()) { | 5633 if (object->IsJSGlobalProxy()) { |
| 5623 Handle<Object> proto(object->GetPrototype(), isolate); | 5634 PrototypeIterator iter(isolate, object); |
| 5624 if (proto->IsNull()) return object; | 5635 if (iter.IsAtEnd()) return object; |
| 5625 ASSERT(proto->IsJSGlobalObject()); | 5636 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
| 5626 return PreventExtensions(Handle<JSObject>::cast(proto)); | 5637 return PreventExtensions( |
| 5638 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter))); |
| 5627 } | 5639 } |
| 5628 | 5640 |
| 5629 // It's not possible to seal objects with external array elements | 5641 // It's not possible to seal objects with external array elements |
| 5630 if (object->HasExternalArrayElements() || | 5642 if (object->HasExternalArrayElements() || |
| 5631 object->HasFixedTypedArrayElements()) { | 5643 object->HasFixedTypedArrayElements()) { |
| 5632 Handle<Object> error = | 5644 Handle<Object> error = |
| 5633 isolate->factory()->NewTypeError( | 5645 isolate->factory()->NewTypeError( |
| 5634 "cant_prevent_ext_external_array_elements", | 5646 "cant_prevent_ext_external_array_elements", |
| 5635 HandleVector(&object, 1)); | 5647 HandleVector(&object, 1)); |
| 5636 return isolate->Throw<Object>(error); | 5648 return isolate->Throw<Object>(error); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5696 Isolate* isolate = object->GetIsolate(); | 5708 Isolate* isolate = object->GetIsolate(); |
| 5697 if (object->IsAccessCheckNeeded() && | 5709 if (object->IsAccessCheckNeeded() && |
| 5698 !isolate->MayNamedAccess( | 5710 !isolate->MayNamedAccess( |
| 5699 object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { | 5711 object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { |
| 5700 isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS); | 5712 isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS); |
| 5701 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 5713 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 5702 return isolate->factory()->false_value(); | 5714 return isolate->factory()->false_value(); |
| 5703 } | 5715 } |
| 5704 | 5716 |
| 5705 if (object->IsJSGlobalProxy()) { | 5717 if (object->IsJSGlobalProxy()) { |
| 5706 Handle<Object> proto(object->GetPrototype(), isolate); | 5718 PrototypeIterator iter(isolate, object); |
| 5707 if (proto->IsNull()) return object; | 5719 if (iter.IsAtEnd()) return object; |
| 5708 ASSERT(proto->IsJSGlobalObject()); | 5720 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
| 5709 return Freeze(Handle<JSObject>::cast(proto)); | 5721 return Freeze(Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter))); |
| 5710 } | 5722 } |
| 5711 | 5723 |
| 5712 // It's not possible to freeze objects with external array elements | 5724 // It's not possible to freeze objects with external array elements |
| 5713 if (object->HasExternalArrayElements() || | 5725 if (object->HasExternalArrayElements() || |
| 5714 object->HasFixedTypedArrayElements()) { | 5726 object->HasFixedTypedArrayElements()) { |
| 5715 Handle<Object> error = | 5727 Handle<Object> error = |
| 5716 isolate->factory()->NewTypeError( | 5728 isolate->factory()->NewTypeError( |
| 5717 "cant_prevent_ext_external_array_elements", | 5729 "cant_prevent_ext_external_array_elements", |
| 5718 HandleVector(&object, 1)); | 5730 HandleVector(&object, 1)); |
| 5719 return isolate->Throw<Object>(error); | 5731 return isolate->Throw<Object>(error); |
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6084 return result; | 6096 return result; |
| 6085 } | 6097 } |
| 6086 | 6098 |
| 6087 | 6099 |
| 6088 // Tests for the fast common case for property enumeration: | 6100 // Tests for the fast common case for property enumeration: |
| 6089 // - This object and all prototypes has an enum cache (which means that | 6101 // - This object and all prototypes has an enum cache (which means that |
| 6090 // it is no proxy, has no interceptors and needs no access checks). | 6102 // it is no proxy, has no interceptors and needs no access checks). |
| 6091 // - This object has no elements. | 6103 // - This object has no elements. |
| 6092 // - No prototype has enumerable properties/elements. | 6104 // - No prototype has enumerable properties/elements. |
| 6093 bool JSReceiver::IsSimpleEnum() { | 6105 bool JSReceiver::IsSimpleEnum() { |
| 6094 Heap* heap = GetHeap(); | 6106 for (PrototypeIterator iter(GetIsolate(), this, |
| 6095 for (Object* o = this; | 6107 PrototypeIterator::START_AT_RECEIVER); |
| 6096 o != heap->null_value(); | 6108 !iter.IsAtEnd(); iter.Advance()) { |
| 6097 o = JSObject::cast(o)->GetPrototype()) { | 6109 if (!iter.GetCurrent()->IsJSObject()) return false; |
| 6098 if (!o->IsJSObject()) return false; | 6110 JSObject* curr = JSObject::cast(iter.GetCurrent()); |
| 6099 JSObject* curr = JSObject::cast(o); | |
| 6100 int enum_length = curr->map()->EnumLength(); | 6111 int enum_length = curr->map()->EnumLength(); |
| 6101 if (enum_length == kInvalidEnumCacheSentinel) return false; | 6112 if (enum_length == kInvalidEnumCacheSentinel) return false; |
| 6102 if (curr->IsAccessCheckNeeded()) return false; | 6113 if (curr->IsAccessCheckNeeded()) return false; |
| 6103 ASSERT(!curr->HasNamedInterceptor()); | 6114 ASSERT(!curr->HasNamedInterceptor()); |
| 6104 ASSERT(!curr->HasIndexedInterceptor()); | 6115 ASSERT(!curr->HasIndexedInterceptor()); |
| 6105 if (curr->NumberOfEnumElements() > 0) return false; | 6116 if (curr->NumberOfEnumElements() > 0) return false; |
| 6106 if (curr != this && enum_length != 0) return false; | 6117 if (curr != this && enum_length != 0) return false; |
| 6107 } | 6118 } |
| 6108 return true; | 6119 return true; |
| 6109 } | 6120 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6157 return max_index + 1; | 6168 return max_index + 1; |
| 6158 } | 6169 } |
| 6159 | 6170 |
| 6160 | 6171 |
| 6161 void JSReceiver::LookupOwn( | 6172 void JSReceiver::LookupOwn( |
| 6162 Handle<Name> name, LookupResult* result, bool search_hidden_prototypes) { | 6173 Handle<Name> name, LookupResult* result, bool search_hidden_prototypes) { |
| 6163 DisallowHeapAllocation no_gc; | 6174 DisallowHeapAllocation no_gc; |
| 6164 ASSERT(name->IsName()); | 6175 ASSERT(name->IsName()); |
| 6165 | 6176 |
| 6166 if (IsJSGlobalProxy()) { | 6177 if (IsJSGlobalProxy()) { |
| 6167 Object* proto = GetPrototype(); | 6178 PrototypeIterator iter(GetIsolate(), this); |
| 6168 if (proto->IsNull()) return result->NotFound(); | 6179 if (iter.IsAtEnd()) return result->NotFound(); |
| 6169 ASSERT(proto->IsJSGlobalObject()); | 6180 ASSERT(iter.GetCurrent()->IsJSGlobalObject()); |
| 6170 return JSReceiver::cast(proto)->LookupOwn( | 6181 return JSReceiver::cast(iter.GetCurrent()) |
| 6171 name, result, search_hidden_prototypes); | 6182 ->LookupOwn(name, result, search_hidden_prototypes); |
| 6172 } | 6183 } |
| 6173 | 6184 |
| 6174 if (IsJSProxy()) { | 6185 if (IsJSProxy()) { |
| 6175 result->HandlerResult(JSProxy::cast(this)); | 6186 result->HandlerResult(JSProxy::cast(this)); |
| 6176 return; | 6187 return; |
| 6177 } | 6188 } |
| 6178 | 6189 |
| 6179 // Do not use inline caching if the object is a non-global object | 6190 // Do not use inline caching if the object is a non-global object |
| 6180 // that requires access checks. | 6191 // that requires access checks. |
| 6181 if (IsAccessCheckNeeded()) { | 6192 if (IsAccessCheckNeeded()) { |
| 6182 result->DisallowCaching(); | 6193 result->DisallowCaching(); |
| 6183 } | 6194 } |
| 6184 | 6195 |
| 6185 JSObject* js_object = JSObject::cast(this); | 6196 JSObject* js_object = JSObject::cast(this); |
| 6186 | 6197 |
| 6187 // Check for lookup interceptor except when bootstrapping. | 6198 // Check for lookup interceptor except when bootstrapping. |
| 6188 if (js_object->HasNamedInterceptor() && | 6199 if (js_object->HasNamedInterceptor() && |
| 6189 !GetIsolate()->bootstrapper()->IsActive()) { | 6200 !GetIsolate()->bootstrapper()->IsActive()) { |
| 6190 result->InterceptorResult(js_object); | 6201 result->InterceptorResult(js_object); |
| 6191 return; | 6202 return; |
| 6192 } | 6203 } |
| 6193 | 6204 |
| 6194 js_object->LookupOwnRealNamedProperty(name, result); | 6205 js_object->LookupOwnRealNamedProperty(name, result); |
| 6195 if (result->IsFound() || !search_hidden_prototypes) return; | 6206 if (result->IsFound() || !search_hidden_prototypes) return; |
| 6196 | 6207 |
| 6197 Object* proto = js_object->GetPrototype(); | 6208 PrototypeIterator iter(GetIsolate(), js_object); |
| 6198 if (!proto->IsJSReceiver()) return; | 6209 if (!iter.GetCurrent()->IsJSReceiver()) return; |
| 6199 JSReceiver* receiver = JSReceiver::cast(proto); | 6210 JSReceiver* receiver = JSReceiver::cast(iter.GetCurrent()); |
| 6200 if (receiver->map()->is_hidden_prototype()) { | 6211 if (receiver->map()->is_hidden_prototype()) { |
| 6201 receiver->LookupOwn(name, result, search_hidden_prototypes); | 6212 receiver->LookupOwn(name, result, search_hidden_prototypes); |
| 6202 } | 6213 } |
| 6203 } | 6214 } |
| 6204 | 6215 |
| 6205 | 6216 |
| 6206 void JSReceiver::Lookup(Handle<Name> name, LookupResult* result) { | 6217 void JSReceiver::Lookup(Handle<Name> name, LookupResult* result) { |
| 6207 DisallowHeapAllocation no_gc; | 6218 DisallowHeapAllocation no_gc; |
| 6208 // Ecma-262 3rd 8.6.2.4 | 6219 // Ecma-262 3rd 8.6.2.4 |
| 6209 Handle<Object> null_value = GetIsolate()->factory()->null_value(); | 6220 for (PrototypeIterator iter(GetIsolate(), this, |
| 6210 for (Object* current = this; | 6221 PrototypeIterator::START_AT_RECEIVER); |
| 6211 current != *null_value; | 6222 !iter.IsAtEnd(); iter.Advance()) { |
| 6212 current = JSObject::cast(current)->GetPrototype()) { | 6223 JSReceiver::cast(iter.GetCurrent())->LookupOwn(name, result, false); |
| 6213 JSReceiver::cast(current)->LookupOwn(name, result, false); | |
| 6214 if (result->IsFound()) return; | 6224 if (result->IsFound()) return; |
| 6215 } | 6225 } |
| 6216 result->NotFound(); | 6226 result->NotFound(); |
| 6217 } | 6227 } |
| 6218 | 6228 |
| 6219 | 6229 |
| 6220 static bool ContainsOnlyValidKeys(Handle<FixedArray> array) { | 6230 static bool ContainsOnlyValidKeys(Handle<FixedArray> array) { |
| 6221 int len = array->length(); | 6231 int len = array->length(); |
| 6222 for (int i = 0; i < len; i++) { | 6232 for (int i = 0; i < len; i++) { |
| 6223 Object* e = array->get(i); | 6233 Object* e = array->get(i); |
| (...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6683 Isolate* isolate = object->GetIsolate(); | 6693 Isolate* isolate = object->GetIsolate(); |
| 6684 // Check access rights if needed. | 6694 // Check access rights if needed. |
| 6685 if (object->IsAccessCheckNeeded() && | 6695 if (object->IsAccessCheckNeeded() && |
| 6686 !isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) { | 6696 !isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) { |
| 6687 isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET); | 6697 isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET); |
| 6688 // TODO(yangguo): Issue 3269, check for scheduled exception missing? | 6698 // TODO(yangguo): Issue 3269, check for scheduled exception missing? |
| 6689 return; | 6699 return; |
| 6690 } | 6700 } |
| 6691 | 6701 |
| 6692 if (object->IsJSGlobalProxy()) { | 6702 if (object->IsJSGlobalProxy()) { |
| 6693 Handle<Object> proto(object->GetPrototype(), isolate); | 6703 PrototypeIterator iter(isolate, object); |
| 6694 if (proto->IsNull()) return; | 6704 if (iter.IsAtEnd()) return; |
| 6695 ASSERT(proto->IsJSGlobalObject()); | 6705 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
| 6696 DefineAccessor(Handle<JSObject>::cast(proto), | 6706 DefineAccessor(Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), |
| 6697 name, | 6707 name, getter, setter, attributes); |
| 6698 getter, | |
| 6699 setter, | |
| 6700 attributes); | |
| 6701 return; | 6708 return; |
| 6702 } | 6709 } |
| 6703 | 6710 |
| 6704 // Make sure that the top context does not change when doing callbacks or | 6711 // Make sure that the top context does not change when doing callbacks or |
| 6705 // interceptor calls. | 6712 // interceptor calls. |
| 6706 AssertNoContextChange ncc(isolate); | 6713 AssertNoContextChange ncc(isolate); |
| 6707 | 6714 |
| 6708 // Try to flatten before operating on the string. | 6715 // Try to flatten before operating on the string. |
| 6709 if (name->IsString()) name = String::Flatten(Handle<String>::cast(name)); | 6716 if (name->IsString()) name = String::Flatten(Handle<String>::cast(name)); |
| 6710 | 6717 |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6859 | 6866 |
| 6860 // Check access rights if needed. | 6867 // Check access rights if needed. |
| 6861 if (object->IsAccessCheckNeeded() && | 6868 if (object->IsAccessCheckNeeded() && |
| 6862 !isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) { | 6869 !isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) { |
| 6863 isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET); | 6870 isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET); |
| 6864 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 6871 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 6865 return factory->undefined_value(); | 6872 return factory->undefined_value(); |
| 6866 } | 6873 } |
| 6867 | 6874 |
| 6868 if (object->IsJSGlobalProxy()) { | 6875 if (object->IsJSGlobalProxy()) { |
| 6869 Handle<Object> proto(object->GetPrototype(), isolate); | 6876 PrototypeIterator iter(isolate, object); |
| 6870 if (proto->IsNull()) return object; | 6877 if (iter.IsAtEnd()) return object; |
| 6871 ASSERT(proto->IsJSGlobalObject()); | 6878 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
| 6872 return SetAccessor(Handle<JSObject>::cast(proto), info); | 6879 return SetAccessor( |
| 6880 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), info); |
| 6873 } | 6881 } |
| 6874 | 6882 |
| 6875 // Make sure that the top context does not change when doing callbacks or | 6883 // Make sure that the top context does not change when doing callbacks or |
| 6876 // interceptor calls. | 6884 // interceptor calls. |
| 6877 AssertNoContextChange ncc(isolate); | 6885 AssertNoContextChange ncc(isolate); |
| 6878 | 6886 |
| 6879 // Try to flatten before operating on the string. | 6887 // Try to flatten before operating on the string. |
| 6880 if (name->IsString()) name = String::Flatten(Handle<String>::cast(name)); | 6888 if (name->IsString()) name = String::Flatten(Handle<String>::cast(name)); |
| 6881 | 6889 |
| 6882 uint32_t index = 0; | 6890 uint32_t index = 0; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6943 if (object->IsAccessCheckNeeded() && | 6951 if (object->IsAccessCheckNeeded() && |
| 6944 !isolate->MayNamedAccess(object, name, v8::ACCESS_HAS)) { | 6952 !isolate->MayNamedAccess(object, name, v8::ACCESS_HAS)) { |
| 6945 isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS); | 6953 isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS); |
| 6946 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 6954 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 6947 return isolate->factory()->undefined_value(); | 6955 return isolate->factory()->undefined_value(); |
| 6948 } | 6956 } |
| 6949 | 6957 |
| 6950 // Make the lookup and include prototypes. | 6958 // Make the lookup and include prototypes. |
| 6951 uint32_t index = 0; | 6959 uint32_t index = 0; |
| 6952 if (name->AsArrayIndex(&index)) { | 6960 if (name->AsArrayIndex(&index)) { |
| 6953 for (Handle<Object> obj = object; | 6961 for (PrototypeIterator iter(isolate, object, |
| 6954 !obj->IsNull(); | 6962 PrototypeIterator::START_AT_RECEIVER); |
| 6955 obj = handle(JSReceiver::cast(*obj)->GetPrototype(), isolate)) { | 6963 !iter.IsAtEnd(); iter.Advance()) { |
| 6956 if (obj->IsJSObject() && JSObject::cast(*obj)->HasDictionaryElements()) { | 6964 if (PrototypeIterator::GetCurrent(iter)->IsJSObject() && |
| 6957 JSObject* js_object = JSObject::cast(*obj); | 6965 JSObject::cast(*PrototypeIterator::GetCurrent(iter)) |
| 6966 ->HasDictionaryElements()) { |
| 6967 JSObject* js_object = |
| 6968 JSObject::cast(*PrototypeIterator::GetCurrent(iter)); |
| 6958 SeededNumberDictionary* dictionary = js_object->element_dictionary(); | 6969 SeededNumberDictionary* dictionary = js_object->element_dictionary(); |
| 6959 int entry = dictionary->FindEntry(index); | 6970 int entry = dictionary->FindEntry(index); |
| 6960 if (entry != SeededNumberDictionary::kNotFound) { | 6971 if (entry != SeededNumberDictionary::kNotFound) { |
| 6961 Object* element = dictionary->ValueAt(entry); | 6972 Object* element = dictionary->ValueAt(entry); |
| 6962 if (dictionary->DetailsAt(entry).type() == CALLBACKS && | 6973 if (dictionary->DetailsAt(entry).type() == CALLBACKS && |
| 6963 element->IsAccessorPair()) { | 6974 element->IsAccessorPair()) { |
| 6964 return handle(AccessorPair::cast(element)->GetComponent(component), | 6975 return handle(AccessorPair::cast(element)->GetComponent(component), |
| 6965 isolate); | 6976 isolate); |
| 6966 } | 6977 } |
| 6967 } | 6978 } |
| 6968 } | 6979 } |
| 6969 } | 6980 } |
| 6970 } else { | 6981 } else { |
| 6971 for (Handle<Object> obj = object; | 6982 for (PrototypeIterator iter(isolate, object, |
| 6972 !obj->IsNull(); | 6983 PrototypeIterator::START_AT_RECEIVER); |
| 6973 obj = handle(JSReceiver::cast(*obj)->GetPrototype(), isolate)) { | 6984 !iter.IsAtEnd(); iter.Advance()) { |
| 6974 LookupResult result(isolate); | 6985 LookupResult result(isolate); |
| 6975 JSReceiver::cast(*obj)->LookupOwn(name, &result); | 6986 JSReceiver::cast(*PrototypeIterator::GetCurrent(iter)) |
| 6987 ->LookupOwn(name, &result); |
| 6976 if (result.IsFound()) { | 6988 if (result.IsFound()) { |
| 6977 if (result.IsReadOnly()) return isolate->factory()->undefined_value(); | 6989 if (result.IsReadOnly()) return isolate->factory()->undefined_value(); |
| 6978 if (result.IsPropertyCallbacks()) { | 6990 if (result.IsPropertyCallbacks()) { |
| 6979 Object* obj = result.GetCallbackObject(); | 6991 Object* obj = result.GetCallbackObject(); |
| 6980 if (obj->IsAccessorPair()) { | 6992 if (obj->IsAccessorPair()) { |
| 6981 return handle(AccessorPair::cast(obj)->GetComponent(component), | 6993 return handle(AccessorPair::cast(obj)->GetComponent(component), |
| 6982 isolate); | 6994 isolate); |
| 6983 } | 6995 } |
| 6984 } | 6996 } |
| 6985 } | 6997 } |
| (...skipping 5256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12242 // direction. | 12254 // direction. |
| 12243 return EnsureCanContainElements( | 12255 return EnsureCanContainElements( |
| 12244 object, args->arguments() - first_arg - (arg_count - 1), arg_count, mode); | 12256 object, args->arguments() - first_arg - (arg_count - 1), arg_count, mode); |
| 12245 } | 12257 } |
| 12246 | 12258 |
| 12247 | 12259 |
| 12248 MaybeHandle<AccessorPair> JSObject::GetOwnElementAccessorPair( | 12260 MaybeHandle<AccessorPair> JSObject::GetOwnElementAccessorPair( |
| 12249 Handle<JSObject> object, | 12261 Handle<JSObject> object, |
| 12250 uint32_t index) { | 12262 uint32_t index) { |
| 12251 if (object->IsJSGlobalProxy()) { | 12263 if (object->IsJSGlobalProxy()) { |
| 12252 Handle<Object> proto(object->GetPrototype(), object->GetIsolate()); | 12264 PrototypeIterator iter(object->GetIsolate(), object); |
| 12253 if (proto->IsNull()) return MaybeHandle<AccessorPair>(); | 12265 if (iter.IsAtEnd()) return MaybeHandle<AccessorPair>(); |
| 12254 ASSERT(proto->IsJSGlobalObject()); | 12266 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
| 12255 return GetOwnElementAccessorPair(Handle<JSObject>::cast(proto), index); | 12267 return GetOwnElementAccessorPair( |
| 12268 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), index); |
| 12256 } | 12269 } |
| 12257 | 12270 |
| 12258 // Check for lookup interceptor. | 12271 // Check for lookup interceptor. |
| 12259 if (object->HasIndexedInterceptor()) return MaybeHandle<AccessorPair>(); | 12272 if (object->HasIndexedInterceptor()) return MaybeHandle<AccessorPair>(); |
| 12260 | 12273 |
| 12261 return object->GetElementsAccessor()->GetAccessorPair(object, object, index); | 12274 return object->GetElementsAccessor()->GetAccessorPair(object, object, index); |
| 12262 } | 12275 } |
| 12263 | 12276 |
| 12264 | 12277 |
| 12265 MaybeHandle<Object> JSObject::SetElementWithInterceptor( | 12278 MaybeHandle<Object> JSObject::SetElementWithInterceptor( |
| (...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12848 // Check access rights if needed. | 12861 // Check access rights if needed. |
| 12849 if (object->IsAccessCheckNeeded()) { | 12862 if (object->IsAccessCheckNeeded()) { |
| 12850 if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_SET)) { | 12863 if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_SET)) { |
| 12851 isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET); | 12864 isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET); |
| 12852 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 12865 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 12853 return value; | 12866 return value; |
| 12854 } | 12867 } |
| 12855 } | 12868 } |
| 12856 | 12869 |
| 12857 if (object->IsJSGlobalProxy()) { | 12870 if (object->IsJSGlobalProxy()) { |
| 12858 Handle<Object> proto(object->GetPrototype(), isolate); | 12871 PrototypeIterator iter(isolate, object); |
| 12859 if (proto->IsNull()) return value; | 12872 if (iter.IsAtEnd()) return value; |
| 12860 ASSERT(proto->IsJSGlobalObject()); | 12873 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
| 12861 return SetElement(Handle<JSObject>::cast(proto), index, value, attributes, | 12874 return SetElement( |
| 12862 strict_mode, | 12875 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), index, |
| 12863 check_prototype, | 12876 value, attributes, strict_mode, check_prototype, set_mode); |
| 12864 set_mode); | |
| 12865 } | 12877 } |
| 12866 | 12878 |
| 12867 // Don't allow element properties to be redefined for external arrays. | 12879 // Don't allow element properties to be redefined for external arrays. |
| 12868 if ((object->HasExternalArrayElements() || | 12880 if ((object->HasExternalArrayElements() || |
| 12869 object->HasFixedTypedArrayElements()) && | 12881 object->HasFixedTypedArrayElements()) && |
| 12870 set_mode == DEFINE_PROPERTY) { | 12882 set_mode == DEFINE_PROPERTY) { |
| 12871 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 12883 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
| 12872 Handle<Object> args[] = { object, number }; | 12884 Handle<Object> args[] = { object, number }; |
| 12873 Handle<Object> error = isolate->factory()->NewTypeError( | 12885 Handle<Object> error = isolate->factory()->NewTypeError( |
| 12874 "redef_external_array_element", HandleVector(args, ARRAY_SIZE(args))); | 12886 "redef_external_array_element", HandleVector(args, ARRAY_SIZE(args))); |
| (...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13352 } | 13364 } |
| 13353 } | 13365 } |
| 13354 | 13366 |
| 13355 ElementsAccessor* handler = object->GetElementsAccessor(); | 13367 ElementsAccessor* handler = object->GetElementsAccessor(); |
| 13356 Handle<Object> result; | 13368 Handle<Object> result; |
| 13357 ASSIGN_RETURN_ON_EXCEPTION( | 13369 ASSIGN_RETURN_ON_EXCEPTION( |
| 13358 isolate, result, handler->Get(receiver, object, index), | 13370 isolate, result, handler->Get(receiver, object, index), |
| 13359 Object); | 13371 Object); |
| 13360 if (!result->IsTheHole()) return result; | 13372 if (!result->IsTheHole()) return result; |
| 13361 | 13373 |
| 13362 Handle<Object> proto(object->GetPrototype(), isolate); | 13374 PrototypeIterator iter(isolate, object); |
| 13363 if (proto->IsNull()) return isolate->factory()->undefined_value(); | 13375 if (iter.IsAtEnd()) return isolate->factory()->undefined_value(); |
| 13364 return Object::GetElementWithReceiver(isolate, proto, receiver, index); | 13376 return Object::GetElementWithReceiver( |
| 13377 isolate, PrototypeIterator::GetCurrent(iter), receiver, index); |
| 13365 } | 13378 } |
| 13366 | 13379 |
| 13367 | 13380 |
| 13368 bool JSObject::HasDenseElements() { | 13381 bool JSObject::HasDenseElements() { |
| 13369 int capacity = 0; | 13382 int capacity = 0; |
| 13370 int used = 0; | 13383 int used = 0; |
| 13371 GetElementsCapacityAndUsage(&capacity, &used); | 13384 GetElementsCapacityAndUsage(&capacity, &used); |
| 13372 return (capacity == 0) || (used > (capacity / 2)); | 13385 return (capacity == 0) || (used > (capacity / 2)); |
| 13373 } | 13386 } |
| 13374 | 13387 |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13715 if (object->IsAccessCheckNeeded()) { | 13728 if (object->IsAccessCheckNeeded()) { |
| 13716 if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_HAS)) { | 13729 if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_HAS)) { |
| 13717 isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS); | 13730 isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS); |
| 13718 // TODO(yangguo): Issue 3269, check for scheduled exception missing? | 13731 // TODO(yangguo): Issue 3269, check for scheduled exception missing? |
| 13719 return false; | 13732 return false; |
| 13720 } | 13733 } |
| 13721 } | 13734 } |
| 13722 | 13735 |
| 13723 if (object->IsJSGlobalProxy()) { | 13736 if (object->IsJSGlobalProxy()) { |
| 13724 HandleScope scope(isolate); | 13737 HandleScope scope(isolate); |
| 13725 Handle<Object> proto(object->GetPrototype(), isolate); | 13738 PrototypeIterator iter(isolate, object); |
| 13726 if (proto->IsNull()) return false; | 13739 if (iter.IsAtEnd()) return false; |
| 13727 ASSERT(proto->IsJSGlobalObject()); | 13740 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
| 13728 return HasRealElementProperty(Handle<JSObject>::cast(proto), index); | 13741 return HasRealElementProperty( |
| 13742 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), index); |
| 13729 } | 13743 } |
| 13730 | 13744 |
| 13731 return GetElementAttributeWithoutInterceptor( | 13745 return GetElementAttributeWithoutInterceptor( |
| 13732 object, object, index, false) != ABSENT; | 13746 object, object, index, false) != ABSENT; |
| 13733 } | 13747 } |
| 13734 | 13748 |
| 13735 | 13749 |
| 13736 bool JSObject::HasRealNamedCallbackProperty(Handle<JSObject> object, | 13750 bool JSObject::HasRealNamedCallbackProperty(Handle<JSObject> object, |
| 13737 Handle<Name> key) { | 13751 Handle<Name> key) { |
| 13738 Isolate* isolate = object->GetIsolate(); | 13752 Isolate* isolate = object->GetIsolate(); |
| (...skipping 3209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16948 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16962 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 16949 static const char* error_messages_[] = { | 16963 static const char* error_messages_[] = { |
| 16950 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16964 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 16951 }; | 16965 }; |
| 16952 #undef ERROR_MESSAGES_TEXTS | 16966 #undef ERROR_MESSAGES_TEXTS |
| 16953 return error_messages_[reason]; | 16967 return error_messages_[reason]; |
| 16954 } | 16968 } |
| 16955 | 16969 |
| 16956 | 16970 |
| 16957 } } // namespace v8::internal | 16971 } } // namespace v8::internal |
| OLD | NEW |