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 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
465 MaybeHandle<Object> Object::SetPropertyWithCallback(Handle<Object> receiver, | 465 MaybeHandle<Object> Object::SetPropertyWithCallback(Handle<Object> receiver, |
466 Handle<Name> name, | 466 Handle<Name> name, |
467 Handle<Object> value, | 467 Handle<Object> value, |
468 Handle<JSObject> holder, | 468 Handle<JSObject> holder, |
469 Handle<Object> structure, | 469 Handle<Object> structure, |
470 StrictMode strict_mode) { | 470 StrictMode strict_mode) { |
471 Isolate* isolate = name->GetIsolate(); | 471 Isolate* isolate = name->GetIsolate(); |
472 | 472 |
473 // We should never get here to initialize a const with the hole | 473 // We should never get here to initialize a const with the hole |
474 // value since a const declaration would conflict with the setter. | 474 // value since a const declaration would conflict with the setter. |
475 ASSERT(!value->IsTheHole()); | |
476 ASSERT(!structure->IsForeign()); | 475 ASSERT(!structure->IsForeign()); |
477 if (structure->IsExecutableAccessorInfo()) { | 476 if (structure->IsExecutableAccessorInfo()) { |
478 // api style callbacks | 477 // api style callbacks |
479 ExecutableAccessorInfo* data = ExecutableAccessorInfo::cast(*structure); | 478 ExecutableAccessorInfo* data = ExecutableAccessorInfo::cast(*structure); |
480 if (!data->IsCompatibleReceiver(*receiver)) { | 479 if (!data->IsCompatibleReceiver(*receiver)) { |
481 Handle<Object> args[2] = { name, receiver }; | 480 Handle<Object> args[2] = { name, receiver }; |
482 Handle<Object> error = | 481 Handle<Object> error = |
483 isolate->factory()->NewTypeError("incompatible_method_receiver", | 482 isolate->factory()->NewTypeError("incompatible_method_receiver", |
484 HandleVector(args, | 483 HandleVector(args, |
485 ARRAY_SIZE(args))); | 484 ARRAY_SIZE(args))); |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
663 } | 662 } |
664 | 663 |
665 | 664 |
666 Handle<Object> JSObject::GetNormalizedProperty(Handle<JSObject> object, | 665 Handle<Object> JSObject::GetNormalizedProperty(Handle<JSObject> object, |
667 const LookupResult* result) { | 666 const LookupResult* result) { |
668 ASSERT(!object->HasFastProperties()); | 667 ASSERT(!object->HasFastProperties()); |
669 Isolate* isolate = object->GetIsolate(); | 668 Isolate* isolate = object->GetIsolate(); |
670 Handle<Object> value(object->property_dictionary()->ValueAt( | 669 Handle<Object> value(object->property_dictionary()->ValueAt( |
671 result->GetDictionaryEntry()), isolate); | 670 result->GetDictionaryEntry()), isolate); |
672 if (object->IsGlobalObject()) { | 671 if (object->IsGlobalObject()) { |
673 value = Handle<Object>(Handle<PropertyCell>::cast(value)->value(), isolate); | 672 value = handle(Handle<PropertyCell>::cast(value)->value(), isolate); |
| 673 ASSERT(!value->IsTheHole()); |
674 } | 674 } |
675 ASSERT(!value->IsPropertyCell() && !value->IsCell()); | 675 ASSERT(!value->IsPropertyCell() && !value->IsCell()); |
676 return value; | 676 return value; |
677 } | 677 } |
678 | 678 |
679 | 679 |
680 void JSObject::SetNormalizedProperty(Handle<JSObject> object, | 680 void JSObject::SetNormalizedProperty(Handle<JSObject> object, |
681 const LookupResult* result, | 681 const LookupResult* result, |
682 Handle<Object> value) { | 682 Handle<Object> value) { |
683 ASSERT(!object->HasFastProperties()); | 683 ASSERT(!object->HasFastProperties()); |
(...skipping 2298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2982 Isolate* isolate = object->GetIsolate(); | 2982 Isolate* isolate = object->GetIsolate(); |
2983 Handle<String> name_string = Handle<String>::cast(name); | 2983 Handle<String> name_string = Handle<String>::cast(name); |
2984 Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor()); | 2984 Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor()); |
2985 if (!interceptor->setter()->IsUndefined()) { | 2985 if (!interceptor->setter()->IsUndefined()) { |
2986 LOG(isolate, | 2986 LOG(isolate, |
2987 ApiNamedPropertyAccess("interceptor-named-set", *object, *name)); | 2987 ApiNamedPropertyAccess("interceptor-named-set", *object, *name)); |
2988 PropertyCallbackArguments args( | 2988 PropertyCallbackArguments args( |
2989 isolate, interceptor->data(), *object, *object); | 2989 isolate, interceptor->data(), *object, *object); |
2990 v8::NamedPropertySetterCallback setter = | 2990 v8::NamedPropertySetterCallback setter = |
2991 v8::ToCData<v8::NamedPropertySetterCallback>(interceptor->setter()); | 2991 v8::ToCData<v8::NamedPropertySetterCallback>(interceptor->setter()); |
2992 Handle<Object> value_unhole = value->IsTheHole() | 2992 v8::Handle<v8::Value> result = args.Call( |
2993 ? Handle<Object>(isolate->factory()->undefined_value()) : value; | 2993 setter, v8::Utils::ToLocal(name_string), v8::Utils::ToLocal(value)); |
2994 v8::Handle<v8::Value> result = args.Call(setter, | |
2995 v8::Utils::ToLocal(name_string), | |
2996 v8::Utils::ToLocal(value_unhole)); | |
2997 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 2994 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
2998 if (!result.IsEmpty()) return value; | 2995 if (!result.IsEmpty()) return value; |
2999 } | 2996 } |
3000 return SetPropertyPostInterceptor(object, name, value, strict_mode); | 2997 return SetPropertyPostInterceptor(object, name, value, strict_mode); |
3001 } | 2998 } |
3002 | 2999 |
3003 | 3000 |
3004 MaybeHandle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object, | 3001 MaybeHandle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object, |
3005 Handle<Name> name, | 3002 Handle<Name> name, |
3006 Handle<Object> value, | 3003 Handle<Object> value, |
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3455 return JSObject::cast(proto)->LookupOwnRealNamedProperty(name, result); | 3452 return JSObject::cast(proto)->LookupOwnRealNamedProperty(name, result); |
3456 } | 3453 } |
3457 | 3454 |
3458 if (HasFastProperties()) { | 3455 if (HasFastProperties()) { |
3459 map()->LookupDescriptor(this, *name, result); | 3456 map()->LookupDescriptor(this, *name, result); |
3460 // A property or a map transition was found. We return all of these result | 3457 // A property or a map transition was found. We return all of these result |
3461 // types because LookupOwnRealNamedProperty is used when setting | 3458 // types because LookupOwnRealNamedProperty is used when setting |
3462 // properties where map transitions are handled. | 3459 // properties where map transitions are handled. |
3463 ASSERT(!result->IsFound() || | 3460 ASSERT(!result->IsFound() || |
3464 (result->holder() == this && result->IsFastPropertyType())); | 3461 (result->holder() == this && result->IsFastPropertyType())); |
3465 // Disallow caching for uninitialized constants. These can only | |
3466 // occur as fields. | |
3467 if (result->IsField() && | |
3468 result->IsReadOnly() && | |
3469 RawFastPropertyAt(result->GetFieldIndex())->IsTheHole()) { | |
3470 result->DisallowCaching(); | |
3471 } | |
3472 return; | 3462 return; |
3473 } | 3463 } |
3474 | 3464 |
3475 int entry = property_dictionary()->FindEntry(name); | 3465 int entry = property_dictionary()->FindEntry(name); |
3476 if (entry != NameDictionary::kNotFound) { | 3466 if (entry != NameDictionary::kNotFound) { |
3477 Object* value = property_dictionary()->ValueAt(entry); | 3467 Object* value = property_dictionary()->ValueAt(entry); |
3478 if (IsGlobalObject()) { | 3468 if (IsGlobalObject()) { |
3479 PropertyDetails d = property_dictionary()->DetailsAt(entry); | 3469 PropertyDetails d = property_dictionary()->DetailsAt(entry); |
3480 if (d.IsDeleted()) { | 3470 if (d.IsDeleted() || PropertyCell::cast(value)->value()->IsTheHole()) { |
3481 result->NotFound(); | 3471 result->NotFound(); |
3482 return; | 3472 return; |
3483 } | 3473 } |
3484 value = PropertyCell::cast(value)->value(); | 3474 value = PropertyCell::cast(value)->value(); |
3485 } | 3475 } |
3486 // Make sure to disallow caching for uninitialized constants | |
3487 // found in the dictionary-mode objects. | |
3488 if (value->IsTheHole()) result->DisallowCaching(); | |
3489 result->DictionaryResult(this, entry); | 3476 result->DictionaryResult(this, entry); |
3490 return; | 3477 return; |
3491 } | 3478 } |
3492 | 3479 |
3493 result->NotFound(); | 3480 result->NotFound(); |
3494 } | 3481 } |
3495 | 3482 |
3496 | 3483 |
3497 void JSObject::LookupRealNamedProperty(Handle<Name> name, | 3484 void JSObject::LookupRealNamedProperty(Handle<Name> name, |
3498 LookupResult* result) { | 3485 LookupResult* result) { |
(...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4046 } | 4033 } |
4047 | 4034 |
4048 | 4035 |
4049 MaybeHandle<Object> JSObject::SetPropertyForResult( | 4036 MaybeHandle<Object> JSObject::SetPropertyForResult( |
4050 Handle<JSObject> object, | 4037 Handle<JSObject> object, |
4051 LookupResult* lookup, | 4038 LookupResult* lookup, |
4052 Handle<Name> name, | 4039 Handle<Name> name, |
4053 Handle<Object> value, | 4040 Handle<Object> value, |
4054 StrictMode strict_mode, | 4041 StrictMode strict_mode, |
4055 StoreFromKeyed store_mode) { | 4042 StoreFromKeyed store_mode) { |
| 4043 ASSERT(!value->IsTheHole()); |
4056 Isolate* isolate = object->GetIsolate(); | 4044 Isolate* isolate = object->GetIsolate(); |
4057 | 4045 |
4058 // Make sure that the top context does not change when doing callbacks or | 4046 // Make sure that the top context does not change when doing callbacks or |
4059 // interceptor calls. | 4047 // interceptor calls. |
4060 AssertNoContextChange ncc(isolate); | 4048 AssertNoContextChange ncc(isolate); |
4061 | 4049 |
4062 // Optimization for 2-byte strings often used as keys in a decompression | 4050 // Optimization for 2-byte strings often used as keys in a decompression |
4063 // dictionary. We internalize these short keys to avoid constantly | 4051 // dictionary. We internalize these short keys to avoid constantly |
4064 // reallocating them. | 4052 // reallocating them. |
4065 if (name->IsString() && !name->IsInternalizedString() && | 4053 if (name->IsString() && !name->IsInternalizedString() && |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4202 // reconfigurable. | 4190 // reconfigurable. |
4203 MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes( | 4191 MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes( |
4204 Handle<JSObject> object, | 4192 Handle<JSObject> object, |
4205 Handle<Name> name, | 4193 Handle<Name> name, |
4206 Handle<Object> value, | 4194 Handle<Object> value, |
4207 PropertyAttributes attributes, | 4195 PropertyAttributes attributes, |
4208 StoreMode mode, | 4196 StoreMode mode, |
4209 ExtensibilityCheck extensibility_check, | 4197 ExtensibilityCheck extensibility_check, |
4210 StoreFromKeyed store_from_keyed, | 4198 StoreFromKeyed store_from_keyed, |
4211 ExecutableAccessorInfoHandling handling) { | 4199 ExecutableAccessorInfoHandling handling) { |
| 4200 ASSERT(!value->IsTheHole()); |
4212 Isolate* isolate = object->GetIsolate(); | 4201 Isolate* isolate = object->GetIsolate(); |
4213 | 4202 |
4214 // Make sure that the top context does not change when doing callbacks or | 4203 // Make sure that the top context does not change when doing callbacks or |
4215 // interceptor calls. | 4204 // interceptor calls. |
4216 AssertNoContextChange ncc(isolate); | 4205 AssertNoContextChange ncc(isolate); |
4217 | 4206 |
4218 LookupResult lookup(isolate); | 4207 LookupResult lookup(isolate); |
4219 object->LookupOwn(name, &lookup, true); | 4208 object->LookupOwn(name, &lookup, true); |
4220 if (!lookup.IsFound()) { | 4209 if (!lookup.IsFound()) { |
4221 object->map()->LookupTransition(*object, *name, &lookup); | 4210 object->map()->LookupTransition(*object, *name, &lookup); |
(...skipping 925 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5147 } else { | 5136 } else { |
5148 return GetHeap()->undefined_value(); | 5137 return GetHeap()->undefined_value(); |
5149 } | 5138 } |
5150 } else { | 5139 } else { |
5151 Isolate* isolate = GetIsolate(); | 5140 Isolate* isolate = GetIsolate(); |
5152 LookupResult result(isolate); | 5141 LookupResult result(isolate); |
5153 LookupOwnRealNamedProperty(isolate->factory()->hidden_string(), &result); | 5142 LookupOwnRealNamedProperty(isolate->factory()->hidden_string(), &result); |
5154 if (result.IsFound()) { | 5143 if (result.IsFound()) { |
5155 ASSERT(result.IsNormal()); | 5144 ASSERT(result.IsNormal()); |
5156 ASSERT(result.holder() == this); | 5145 ASSERT(result.holder() == this); |
5157 Object* value = GetNormalizedProperty(&result); | 5146 return GetNormalizedProperty(&result); |
5158 if (!value->IsTheHole()) return value; | |
5159 } | 5147 } |
5160 return GetHeap()->undefined_value(); | 5148 return GetHeap()->undefined_value(); |
5161 } | 5149 } |
5162 } | 5150 } |
5163 | 5151 |
5164 Handle<ObjectHashTable> JSObject::GetOrCreateHiddenPropertiesHashtable( | 5152 Handle<ObjectHashTable> JSObject::GetOrCreateHiddenPropertiesHashtable( |
5165 Handle<JSObject> object) { | 5153 Handle<JSObject> object) { |
5166 Isolate* isolate = object->GetIsolate(); | 5154 Isolate* isolate = object->GetIsolate(); |
5167 | 5155 |
5168 static const int kInitialCapacity = 4; | 5156 static const int kInitialCapacity = 4; |
(...skipping 11753 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16922 set_type_raw(type, ignored); | 16910 set_type_raw(type, ignored); |
16923 } | 16911 } |
16924 | 16912 |
16925 | 16913 |
16926 Handle<HeapType> PropertyCell::UpdatedType(Handle<PropertyCell> cell, | 16914 Handle<HeapType> PropertyCell::UpdatedType(Handle<PropertyCell> cell, |
16927 Handle<Object> value) { | 16915 Handle<Object> value) { |
16928 Isolate* isolate = cell->GetIsolate(); | 16916 Isolate* isolate = cell->GetIsolate(); |
16929 Handle<HeapType> old_type(cell->type(), isolate); | 16917 Handle<HeapType> old_type(cell->type(), isolate); |
16930 // TODO(2803): Do not track ConsString as constant because they cannot be | 16918 // TODO(2803): Do not track ConsString as constant because they cannot be |
16931 // embedded into code. | 16919 // embedded into code. |
16932 Handle<HeapType> new_type = value->IsConsString() || value->IsTheHole() | 16920 Handle<HeapType> new_type = value->IsConsString() |
16933 ? HeapType::Any(isolate) : HeapType::Constant(value, isolate); | 16921 ? HeapType::Any(isolate) |
| 16922 : HeapType::Constant(value, isolate); |
16934 | 16923 |
16935 if (new_type->Is(old_type)) { | 16924 if (new_type->Is(old_type)) return old_type; |
16936 return old_type; | |
16937 } | |
16938 | 16925 |
16939 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 16926 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
16940 isolate, DependentCode::kPropertyCellChangedGroup); | 16927 isolate, DependentCode::kPropertyCellChangedGroup); |
16941 | 16928 |
16942 if (old_type->Is(HeapType::None()) || old_type->Is(HeapType::Undefined())) { | 16929 if (old_type->Is(HeapType::None()) || old_type->Is(HeapType::Undefined())) { |
16943 return new_type; | 16930 return new_type; |
16944 } | 16931 } |
16945 | 16932 |
16946 return HeapType::Any(isolate); | 16933 return HeapType::Any(isolate); |
16947 } | 16934 } |
(...skipping 27 matching lines...) Expand all Loading... |
16975 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16962 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16976 static const char* error_messages_[] = { | 16963 static const char* error_messages_[] = { |
16977 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16964 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16978 }; | 16965 }; |
16979 #undef ERROR_MESSAGES_TEXTS | 16966 #undef ERROR_MESSAGES_TEXTS |
16980 return error_messages_[reason]; | 16967 return error_messages_[reason]; |
16981 } | 16968 } |
16982 | 16969 |
16983 | 16970 |
16984 } } // namespace v8::internal | 16971 } } // namespace v8::internal |
OLD | NEW |