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

Side by Side Diff: src/objects.cc

Issue 11413068: Fix and clean up treatment of hidden prototypes. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 1 month 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/runtime.cc » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1948 matching lines...) Expand 10 before | Expand all | Expand 10 after
1959 Object); 1959 Object);
1960 } 1960 }
1961 1961
1962 1962
1963 MaybeObject* JSReceiver::SetProperty(String* name, 1963 MaybeObject* JSReceiver::SetProperty(String* name,
1964 Object* value, 1964 Object* value,
1965 PropertyAttributes attributes, 1965 PropertyAttributes attributes,
1966 StrictModeFlag strict_mode, 1966 StrictModeFlag strict_mode,
1967 JSReceiver::StoreFromKeyed store_mode) { 1967 JSReceiver::StoreFromKeyed store_mode) {
1968 LookupResult result(GetIsolate()); 1968 LookupResult result(GetIsolate());
1969 LocalLookup(name, &result); 1969 LocalLookup(name, &result, true);
1970 if (!result.IsFound()) { 1970 if (!result.IsFound()) {
1971 map()->LookupTransition(JSObject::cast(this), name, &result); 1971 map()->LookupTransition(JSObject::cast(this), name, &result);
1972 } 1972 }
1973 return SetProperty(&result, name, value, attributes, strict_mode, store_mode); 1973 return SetProperty(&result, name, value, attributes, strict_mode, store_mode);
1974 } 1974 }
1975 1975
1976 1976
1977 MaybeObject* JSObject::SetPropertyWithCallback(Object* structure, 1977 MaybeObject* JSObject::SetPropertyWithCallback(Object* structure,
1978 String* name, 1978 String* name,
1979 Object* value, 1979 Object* value,
(...skipping 1033 matching lines...) Expand 10 before | Expand all | Expand 10 after
3013 } 3013 }
3014 3014
3015 Handle<Object> hresult; 3015 Handle<Object> hresult;
3016 if (!result->ToHandle(&hresult, isolate)) return result; 3016 if (!result->ToHandle(&hresult, isolate)) return result;
3017 3017
3018 if (FLAG_harmony_observation && map()->is_observed()) { 3018 if (FLAG_harmony_observation && map()->is_observed()) {
3019 if (lookup->IsTransition()) { 3019 if (lookup->IsTransition()) {
3020 EnqueueChangeRecord(self, "new", name, old_value); 3020 EnqueueChangeRecord(self, "new", name, old_value);
3021 } else { 3021 } else {
3022 LookupResult new_lookup(isolate); 3022 LookupResult new_lookup(isolate);
3023 self->LocalLookup(*name, &new_lookup); 3023 self->LocalLookup(*name, &new_lookup, true);
3024 ASSERT(!new_lookup.GetLazyValue()->IsTheHole()); 3024 ASSERT(!new_lookup.GetLazyValue()->IsTheHole());
3025 if (!new_lookup.GetLazyValue()->SameValue(*old_value)) { 3025 if (!new_lookup.GetLazyValue()->SameValue(*old_value)) {
3026 EnqueueChangeRecord(self, "updated", name, old_value); 3026 EnqueueChangeRecord(self, "updated", name, old_value);
3027 } 3027 }
3028 } 3028 }
3029 } 3029 }
3030 3030
3031 return *hresult; 3031 return *hresult;
3032 } 3032 }
3033 3033
(...skipping 21 matching lines...) Expand all
3055 3055
3056 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( 3056 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes(
3057 String* name_raw, 3057 String* name_raw,
3058 Object* value_raw, 3058 Object* value_raw,
3059 PropertyAttributes attributes) { 3059 PropertyAttributes attributes) {
3060 // Make sure that the top context does not change when doing callbacks or 3060 // Make sure that the top context does not change when doing callbacks or
3061 // interceptor calls. 3061 // interceptor calls.
3062 AssertNoContextChange ncc; 3062 AssertNoContextChange ncc;
3063 Isolate* isolate = GetIsolate(); 3063 Isolate* isolate = GetIsolate();
3064 LookupResult lookup(isolate); 3064 LookupResult lookup(isolate);
3065 LocalLookup(name_raw, &lookup); 3065 LocalLookup(name_raw, &lookup, true);
3066 if (!lookup.IsFound()) map()->LookupTransition(this, name_raw, &lookup); 3066 if (!lookup.IsFound()) map()->LookupTransition(this, name_raw, &lookup);
3067 // Check access rights if needed. 3067 // Check access rights if needed.
3068 if (IsAccessCheckNeeded()) { 3068 if (IsAccessCheckNeeded()) {
3069 if (!isolate->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) { 3069 if (!isolate->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) {
3070 return SetPropertyWithFailedAccessCheck(&lookup, 3070 return SetPropertyWithFailedAccessCheck(&lookup,
3071 name_raw, 3071 name_raw,
3072 value_raw, 3072 value_raw,
3073 false, 3073 false,
3074 kNonStrictMode); 3074 kNonStrictMode);
3075 } 3075 }
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
3162 } 3162 }
3163 3163
3164 Handle<Object> hresult; 3164 Handle<Object> hresult;
3165 if (!result->ToHandle(&hresult, isolate)) return result; 3165 if (!result->ToHandle(&hresult, isolate)) return result;
3166 3166
3167 if (FLAG_harmony_observation && map()->is_observed()) { 3167 if (FLAG_harmony_observation && map()->is_observed()) {
3168 if (lookup.IsTransition()) { 3168 if (lookup.IsTransition()) {
3169 EnqueueChangeRecord(self, "new", name, old_value); 3169 EnqueueChangeRecord(self, "new", name, old_value);
3170 } else { 3170 } else {
3171 LookupResult new_lookup(isolate); 3171 LookupResult new_lookup(isolate);
3172 self->LocalLookup(*name, &new_lookup); 3172 self->LocalLookup(*name, &new_lookup, true);
3173 ASSERT(!new_lookup.GetLazyValue()->IsTheHole()); 3173 ASSERT(!new_lookup.GetLazyValue()->IsTheHole());
3174 if (old_value->IsTheHole() || 3174 if (old_value->IsTheHole() ||
3175 new_lookup.GetAttributes() != old_attributes) { 3175 new_lookup.GetAttributes() != old_attributes) {
3176 EnqueueChangeRecord(self, "reconfigured", name, old_value); 3176 EnqueueChangeRecord(self, "reconfigured", name, old_value);
3177 } else if (!new_lookup.GetLazyValue()->SameValue(*old_value)) { 3177 } else if (!new_lookup.GetLazyValue()->SameValue(*old_value)) {
3178 EnqueueChangeRecord(self, "updated", name, old_value); 3178 EnqueueChangeRecord(self, "updated", name, old_value);
3179 } 3179 }
3180 } 3180 }
3181 } 3181 }
3182 3182
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
3309 3309
3310 3310
3311 PropertyAttributes JSReceiver::GetLocalPropertyAttribute(String* name) { 3311 PropertyAttributes JSReceiver::GetLocalPropertyAttribute(String* name) {
3312 // Check whether the name is an array index. 3312 // Check whether the name is an array index.
3313 uint32_t index = 0; 3313 uint32_t index = 0;
3314 if (IsJSObject() && name->AsArrayIndex(&index)) { 3314 if (IsJSObject() && name->AsArrayIndex(&index)) {
3315 return GetLocalElementAttribute(index); 3315 return GetLocalElementAttribute(index);
3316 } 3316 }
3317 // Named property. 3317 // Named property.
3318 LookupResult lookup(GetIsolate()); 3318 LookupResult lookup(GetIsolate());
3319 LocalLookup(name, &lookup); 3319 LocalLookup(name, &lookup, true);
3320 return GetPropertyAttributeForResult(this, &lookup, name, false); 3320 return GetPropertyAttributeForResult(this, &lookup, name, false);
3321 } 3321 }
3322 3322
3323 3323
3324 PropertyAttributes JSObject::GetElementAttributeWithReceiver( 3324 PropertyAttributes JSObject::GetElementAttributeWithReceiver(
3325 JSReceiver* receiver, uint32_t index, bool continue_search) { 3325 JSReceiver* receiver, uint32_t index, bool continue_search) {
3326 Isolate* isolate = GetIsolate(); 3326 Isolate* isolate = GetIsolate();
3327 3327
3328 // Check access rights if needed. 3328 // Check access rights if needed.
3329 if (IsAccessCheckNeeded()) { 3329 if (IsAccessCheckNeeded()) {
(...skipping 881 matching lines...) Expand 10 before | Expand all | Expand 10 after
4211 ASSERT(proto->IsJSGlobalObject()); 4211 ASSERT(proto->IsJSGlobalObject());
4212 return JSGlobalObject::cast(proto)->DeleteProperty(name, mode); 4212 return JSGlobalObject::cast(proto)->DeleteProperty(name, mode);
4213 } 4213 }
4214 4214
4215 uint32_t index = 0; 4215 uint32_t index = 0;
4216 if (name->AsArrayIndex(&index)) { 4216 if (name->AsArrayIndex(&index)) {
4217 return DeleteElement(index, mode); 4217 return DeleteElement(index, mode);
4218 } 4218 }
4219 4219
4220 LookupResult lookup(isolate); 4220 LookupResult lookup(isolate);
4221 LocalLookup(name, &lookup); 4221 LocalLookup(name, &lookup, true);
4222 if (!lookup.IsFound()) return isolate->heap()->true_value(); 4222 if (!lookup.IsFound()) return isolate->heap()->true_value();
4223 // Ignore attributes if forcing a deletion. 4223 // Ignore attributes if forcing a deletion.
4224 if (lookup.IsDontDelete() && mode != FORCE_DELETION) { 4224 if (lookup.IsDontDelete() && mode != FORCE_DELETION) {
4225 if (mode == STRICT_DELETION) { 4225 if (mode == STRICT_DELETION) {
4226 // Deleting a non-configurable property in strict mode. 4226 // Deleting a non-configurable property in strict mode.
4227 HandleScope scope(isolate); 4227 HandleScope scope(isolate);
4228 Handle<Object> args[2] = { Handle<Object>(name), Handle<Object>(this) }; 4228 Handle<Object> args[2] = { Handle<Object>(name), Handle<Object>(this) };
4229 return isolate->Throw(*isolate->factory()->NewTypeError( 4229 return isolate->Throw(*isolate->factory()->NewTypeError(
4230 "strict_delete_property", HandleVector(args, 2))); 4230 "strict_delete_property", HandleVector(args, 2)));
4231 } 4231 }
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
4541 int number_of_own_descriptors = NumberOfOwnDescriptors(); 4541 int number_of_own_descriptors = NumberOfOwnDescriptors();
4542 for (int i = 0; i < number_of_own_descriptors; i++) { 4542 for (int i = 0; i < number_of_own_descriptors; i++) {
4543 if (descs->GetType(i) == CALLBACKS && name->Equals(descs->GetKey(i))) { 4543 if (descs->GetType(i) == CALLBACKS && name->Equals(descs->GetKey(i))) {
4544 return descs->GetCallbacks(i); 4544 return descs->GetCallbacks(i);
4545 } 4545 }
4546 } 4546 }
4547 return NULL; 4547 return NULL;
4548 } 4548 }
4549 4549
4550 4550
4551 void JSReceiver::LocalLookup(String* name, LookupResult* result) { 4551 void JSReceiver::LocalLookup(
4552 String* name, LookupResult* result, bool search_hidden_prototypes) {
4552 ASSERT(name->IsString()); 4553 ASSERT(name->IsString());
4553 4554
4554 Heap* heap = GetHeap(); 4555 Heap* heap = GetHeap();
4555 4556
4556 if (IsJSGlobalProxy()) { 4557 if (IsJSGlobalProxy()) {
4557 Object* proto = GetPrototype(); 4558 Object* proto = GetPrototype();
4558 if (proto->IsNull()) return result->NotFound(); 4559 if (proto->IsNull()) return result->NotFound();
4559 ASSERT(proto->IsJSGlobalObject()); 4560 ASSERT(proto->IsJSGlobalObject());
4560 return JSReceiver::cast(proto)->LocalLookup(name, result); 4561 return JSReceiver::cast(proto)->LocalLookup(
4562 name, result, search_hidden_prototypes);
4561 } 4563 }
4562 4564
4563 if (IsJSProxy()) { 4565 if (IsJSProxy()) {
4564 result->HandlerResult(JSProxy::cast(this)); 4566 result->HandlerResult(JSProxy::cast(this));
4565 return; 4567 return;
4566 } 4568 }
4567 4569
4568 // Do not use inline caching if the object is a non-global object 4570 // Do not use inline caching if the object is a non-global object
4569 // that requires access checks. 4571 // that requires access checks.
4570 if (IsAccessCheckNeeded()) { 4572 if (IsAccessCheckNeeded()) {
4571 result->DisallowCaching(); 4573 result->DisallowCaching();
4572 } 4574 }
4573 4575
4574 JSObject* js_object = JSObject::cast(this); 4576 JSObject* js_object = JSObject::cast(this);
4575 4577
4576 // Check __proto__ before interceptor. 4578 // Check __proto__ before interceptor.
4577 if (name->Equals(heap->Proto_symbol()) && !IsJSContextExtensionObject()) { 4579 if (name->Equals(heap->Proto_symbol()) && !IsJSContextExtensionObject()) {
4578 result->ConstantResult(js_object); 4580 result->ConstantResult(js_object);
4579 return; 4581 return;
4580 } 4582 }
4581 4583
4582 // Check for lookup interceptor except when bootstrapping. 4584 // Check for lookup interceptor except when bootstrapping.
4583 if (js_object->HasNamedInterceptor() && 4585 if (js_object->HasNamedInterceptor() &&
4584 !heap->isolate()->bootstrapper()->IsActive()) { 4586 !heap->isolate()->bootstrapper()->IsActive()) {
4585 result->InterceptorResult(js_object); 4587 result->InterceptorResult(js_object);
4586 return; 4588 return;
4587 } 4589 }
4588 4590
4589 js_object->LocalLookupRealNamedProperty(name, result); 4591 js_object->LocalLookupRealNamedProperty(name, result);
4592 if (result->IsFound() || !search_hidden_prototypes) return;
4593
4594 Object* proto = js_object->GetPrototype();
4595 if (!proto->IsJSReceiver()) return;
4596 JSReceiver* receiver = JSReceiver::cast(proto);
4597 if (receiver->map()->is_hidden_prototype()) {
4598 receiver->LocalLookup(name, result, search_hidden_prototypes);
4599 }
4590 } 4600 }
4591 4601
4592 4602
4593 void JSReceiver::Lookup(String* name, LookupResult* result) { 4603 void JSReceiver::Lookup(String* name, LookupResult* result) {
4594 // Ecma-262 3rd 8.6.2.4 4604 // Ecma-262 3rd 8.6.2.4
4595 Heap* heap = GetHeap(); 4605 Heap* heap = GetHeap();
4596 for (Object* current = this; 4606 for (Object* current = this;
4597 current != heap->null_value(); 4607 current != heap->null_value();
4598 current = JSObject::cast(current)->GetPrototype()) { 4608 current = JSObject::cast(current)->GetPrototype()) {
4599 JSReceiver::cast(current)->LocalLookup(name, result); 4609 JSReceiver::cast(current)->LocalLookup(name, result, false);
4600 if (result->IsFound()) return; 4610 if (result->IsFound()) return;
4601 } 4611 }
4602 result->NotFound(); 4612 result->NotFound();
4603 } 4613 }
4604 4614
4605 4615
4606 // Search object and its prototype chain for callback properties. 4616 // Search object and its prototype chain for callback properties.
4607 void JSObject::LookupCallbackProperty(String* name, LookupResult* result) { 4617 void JSObject::LookupCallbackProperty(String* name, LookupResult* result) {
4608 Heap* heap = GetHeap(); 4618 Heap* heap = GetHeap();
4609 for (Object* current = this; 4619 for (Object* current = this;
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
4911 Handle<Object> old_value = isolate->factory()->the_hole_value(); 4921 Handle<Object> old_value = isolate->factory()->the_hole_value();
4912 bool preexists = false; 4922 bool preexists = false;
4913 if (FLAG_harmony_observation && map()->is_observed()) { 4923 if (FLAG_harmony_observation && map()->is_observed()) {
4914 if (is_element) { 4924 if (is_element) {
4915 preexists = HasLocalElement(index); 4925 preexists = HasLocalElement(index);
4916 if (preexists && GetLocalElementAccessorPair(index) == NULL) { 4926 if (preexists && GetLocalElementAccessorPair(index) == NULL) {
4917 old_value = Object::GetElement(self, index); 4927 old_value = Object::GetElement(self, index);
4918 } 4928 }
4919 } else { 4929 } else {
4920 LookupResult lookup(isolate); 4930 LookupResult lookup(isolate);
4921 LocalLookup(*name, &lookup); 4931 LocalLookup(*name, &lookup, true);
4922 preexists = lookup.IsProperty(); 4932 preexists = lookup.IsProperty();
4923 if (preexists) old_value = handle(lookup.GetLazyValue(), isolate); 4933 if (preexists) old_value = handle(lookup.GetLazyValue(), isolate);
4924 } 4934 }
4925 } 4935 }
4926 4936
4927 MaybeObject* result = is_element ? 4937 MaybeObject* result = is_element ?
4928 self->DefineElementAccessor(index, *getter, *setter, attributes) : 4938 self->DefineElementAccessor(index, *getter, *setter, attributes) :
4929 self->DefinePropertyAccessor(*name, *getter, *setter, attributes); 4939 self->DefinePropertyAccessor(*name, *getter, *setter, attributes);
4930 4940
4931 Handle<Object> hresult; 4941 Handle<Object> hresult;
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
5109 UNIMPLEMENTED(); 5119 UNIMPLEMENTED();
5110 break; 5120 break;
5111 } 5121 }
5112 5122
5113 MaybeObject* maybe_ok = 5123 MaybeObject* maybe_ok =
5114 SetElementCallback(index, info, info->property_attributes()); 5124 SetElementCallback(index, info, info->property_attributes());
5115 if (maybe_ok->IsFailure()) return maybe_ok; 5125 if (maybe_ok->IsFailure()) return maybe_ok;
5116 } else { 5126 } else {
5117 // Lookup the name. 5127 // Lookup the name.
5118 LookupResult result(isolate); 5128 LookupResult result(isolate);
5119 LocalLookup(name, &result); 5129 LocalLookup(name, &result, true);
5120 // ES5 forbids turning a property into an accessor if it's not 5130 // ES5 forbids turning a property into an accessor if it's not
5121 // configurable (that is IsDontDelete in ES3 and v8), see 8.6.1 (Table 5). 5131 // configurable (that is IsDontDelete in ES3 and v8), see 8.6.1 (Table 5).
5122 if (result.IsFound() && (result.IsReadOnly() || result.IsDontDelete())) { 5132 if (result.IsFound() && (result.IsReadOnly() || result.IsDontDelete())) {
5123 return isolate->heap()->undefined_value(); 5133 return isolate->heap()->undefined_value();
5124 } 5134 }
5125 5135
5126 MaybeObject* maybe_ok = 5136 MaybeObject* maybe_ok =
5127 SetPropertyCallback(name, info, info->property_attributes()); 5137 SetPropertyCallback(name, info, info->property_attributes());
5128 if (maybe_ok->IsFailure()) return maybe_ok; 5138 if (maybe_ok->IsFailure()) return maybe_ok;
5129 } 5139 }
(...skipping 4493 matching lines...) Expand 10 before | Expand all | Expand 10 after
9623 arg_count, mode); 9633 arg_count, mode);
9624 } 9634 }
9625 9635
9626 9636
9627 PropertyType JSObject::GetLocalPropertyType(String* name) { 9637 PropertyType JSObject::GetLocalPropertyType(String* name) {
9628 uint32_t index = 0; 9638 uint32_t index = 0;
9629 if (name->AsArrayIndex(&index)) { 9639 if (name->AsArrayIndex(&index)) {
9630 return GetLocalElementType(index); 9640 return GetLocalElementType(index);
9631 } 9641 }
9632 LookupResult lookup(GetIsolate()); 9642 LookupResult lookup(GetIsolate());
9633 LocalLookup(name, &lookup); 9643 LocalLookup(name, &lookup, true);
9634 return lookup.type(); 9644 return lookup.type();
9635 } 9645 }
9636 9646
9637 9647
9638 PropertyType JSObject::GetLocalElementType(uint32_t index) { 9648 PropertyType JSObject::GetLocalElementType(uint32_t index) {
9639 return GetElementsAccessor()->GetType(this, this, index); 9649 return GetElementsAccessor()->GetType(this, this, index);
9640 } 9650 }
9641 9651
9642 9652
9643 AccessorPair* JSObject::GetLocalPropertyAccessorPair(String* name) { 9653 AccessorPair* JSObject::GetLocalPropertyAccessorPair(String* name) {
(...skipping 4224 matching lines...) Expand 10 before | Expand all | Expand 10 after
13868 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); 13878 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER);
13869 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); 13879 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER);
13870 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); 13880 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER);
13871 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); 13881 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER);
13872 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); 13882 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER);
13873 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); 13883 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER);
13874 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); 13884 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER);
13875 } 13885 }
13876 13886
13877 } } // namespace v8::internal 13887 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/runtime.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698