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 "v8.h" | 5 #include "v8.h" |
6 | 6 |
7 #include "accessors.h" | 7 #include "accessors.h" |
8 #include "allocation-site-scopes.h" | 8 #include "allocation-site-scopes.h" |
9 #include "api.h" | 9 #include "api.h" |
10 #include "arguments.h" | 10 #include "arguments.h" |
(...skipping 6398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6409 for (Object* current = this; | 6409 for (Object* current = this; |
6410 current != *null_value; | 6410 current != *null_value; |
6411 current = JSObject::cast(current)->GetPrototype()) { | 6411 current = JSObject::cast(current)->GetPrototype()) { |
6412 JSReceiver::cast(current)->LookupOwn(name, result, false); | 6412 JSReceiver::cast(current)->LookupOwn(name, result, false); |
6413 if (result->IsFound()) return; | 6413 if (result->IsFound()) return; |
6414 } | 6414 } |
6415 result->NotFound(); | 6415 result->NotFound(); |
6416 } | 6416 } |
6417 | 6417 |
6418 | 6418 |
6419 // Search object and its prototype chain for callback properties. | |
6420 void JSObject::LookupCallbackProperty(Handle<Name> name, LookupResult* result) { | |
6421 DisallowHeapAllocation no_gc; | |
6422 Handle<Object> null_value = GetIsolate()->factory()->null_value(); | |
6423 for (Object* current = this; | |
6424 current != *null_value && current->IsJSObject(); | |
6425 current = JSObject::cast(current)->GetPrototype()) { | |
6426 JSObject::cast(current)->LookupOwnRealNamedProperty(name, result); | |
6427 if (result->IsPropertyCallbacks()) return; | |
6428 } | |
6429 result->NotFound(); | |
6430 } | |
6431 | |
6432 | |
6433 static bool ContainsOnlyValidKeys(Handle<FixedArray> array) { | 6419 static bool ContainsOnlyValidKeys(Handle<FixedArray> array) { |
6434 int len = array->length(); | 6420 int len = array->length(); |
6435 for (int i = 0; i < len; i++) { | 6421 for (int i = 0; i < len; i++) { |
6436 Object* e = array->get(i); | 6422 Object* e = array->get(i); |
6437 if (!(e->IsString() || e->IsNumber())) return false; | 6423 if (!(e->IsString() || e->IsNumber())) return false; |
6438 } | 6424 } |
6439 return true; | 6425 return true; |
6440 } | 6426 } |
6441 | 6427 |
6442 | 6428 |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6807 } | 6793 } |
6808 | 6794 |
6809 Handle<AccessorPair> accessors = CreateAccessorPairFor(object, name); | 6795 Handle<AccessorPair> accessors = CreateAccessorPairFor(object, name); |
6810 accessors->SetComponents(*getter, *setter); | 6796 accessors->SetComponents(*getter, *setter); |
6811 accessors->set_access_flags(access_control); | 6797 accessors->set_access_flags(access_control); |
6812 | 6798 |
6813 SetPropertyCallback(object, name, accessors, attributes); | 6799 SetPropertyCallback(object, name, accessors, attributes); |
6814 } | 6800 } |
6815 | 6801 |
6816 | 6802 |
6817 bool JSObject::CanSetCallback(Handle<JSObject> object, Handle<Name> name) { | |
6818 Isolate* isolate = object->GetIsolate(); | |
6819 ASSERT(!object->IsAccessCheckNeeded() || | |
6820 isolate->MayNamedAccess(object, name, v8::ACCESS_SET)); | |
6821 | |
6822 // Check if there is an API defined callback object which prohibits | |
6823 // callback overwriting in this object or its prototype chain. | |
6824 // This mechanism is needed for instance in a browser setting, where | |
6825 // certain accessors such as window.location should not be allowed | |
6826 // to be overwritten because allowing overwriting could potentially | |
6827 // cause security problems. | |
6828 LookupResult callback_result(isolate); | |
6829 object->LookupCallbackProperty(name, &callback_result); | |
6830 if (callback_result.IsFound()) { | |
6831 Object* callback_obj = callback_result.GetCallbackObject(); | |
6832 if (callback_obj->IsAccessorInfo()) { | |
6833 return !AccessorInfo::cast(callback_obj)->prohibits_overwriting(); | |
6834 } | |
6835 if (callback_obj->IsAccessorPair()) { | |
6836 return !AccessorPair::cast(callback_obj)->prohibits_overwriting(); | |
6837 } | |
6838 } | |
6839 return true; | |
6840 } | |
6841 | |
6842 | |
6843 bool Map::DictionaryElementsInPrototypeChainOnly() { | 6803 bool Map::DictionaryElementsInPrototypeChainOnly() { |
6844 Heap* heap = GetHeap(); | 6804 Heap* heap = GetHeap(); |
6845 | 6805 |
6846 if (IsDictionaryElementsKind(elements_kind())) { | 6806 if (IsDictionaryElementsKind(elements_kind())) { |
6847 return false; | 6807 return false; |
6848 } | 6808 } |
6849 | 6809 |
6850 for (Object* prototype = this->prototype(); | 6810 for (Object* prototype = this->prototype(); |
6851 prototype != heap->null_value(); | 6811 prototype != heap->null_value(); |
6852 prototype = prototype->GetPrototype(GetIsolate())) { | 6812 prototype = prototype->GetPrototype(GetIsolate())) { |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6959 return; | 6919 return; |
6960 } | 6920 } |
6961 | 6921 |
6962 // Make sure that the top context does not change when doing callbacks or | 6922 // Make sure that the top context does not change when doing callbacks or |
6963 // interceptor calls. | 6923 // interceptor calls. |
6964 AssertNoContextChange ncc(isolate); | 6924 AssertNoContextChange ncc(isolate); |
6965 | 6925 |
6966 // Try to flatten before operating on the string. | 6926 // Try to flatten before operating on the string. |
6967 if (name->IsString()) name = String::Flatten(Handle<String>::cast(name)); | 6927 if (name->IsString()) name = String::Flatten(Handle<String>::cast(name)); |
6968 | 6928 |
6969 if (!JSObject::CanSetCallback(object, name)) return; | |
6970 | |
6971 uint32_t index = 0; | 6929 uint32_t index = 0; |
6972 bool is_element = name->AsArrayIndex(&index); | 6930 bool is_element = name->AsArrayIndex(&index); |
6973 | 6931 |
6974 Handle<Object> old_value = isolate->factory()->the_hole_value(); | 6932 Handle<Object> old_value = isolate->factory()->the_hole_value(); |
6975 bool is_observed = object->map()->is_observed() && | 6933 bool is_observed = object->map()->is_observed() && |
6976 *name != isolate->heap()->hidden_string(); | 6934 *name != isolate->heap()->hidden_string(); |
6977 bool preexists = false; | 6935 bool preexists = false; |
6978 if (is_observed) { | 6936 if (is_observed) { |
6979 if (is_element) { | 6937 if (is_element) { |
6980 preexists = HasOwnElement(object, index); | 6938 preexists = HasOwnElement(object, index); |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7132 return SetAccessor(Handle<JSObject>::cast(proto), info); | 7090 return SetAccessor(Handle<JSObject>::cast(proto), info); |
7133 } | 7091 } |
7134 | 7092 |
7135 // Make sure that the top context does not change when doing callbacks or | 7093 // Make sure that the top context does not change when doing callbacks or |
7136 // interceptor calls. | 7094 // interceptor calls. |
7137 AssertNoContextChange ncc(isolate); | 7095 AssertNoContextChange ncc(isolate); |
7138 | 7096 |
7139 // Try to flatten before operating on the string. | 7097 // Try to flatten before operating on the string. |
7140 if (name->IsString()) name = String::Flatten(Handle<String>::cast(name)); | 7098 if (name->IsString()) name = String::Flatten(Handle<String>::cast(name)); |
7141 | 7099 |
7142 if (!JSObject::CanSetCallback(object, name)) { | |
7143 return factory->undefined_value(); | |
7144 } | |
7145 | |
7146 uint32_t index = 0; | 7100 uint32_t index = 0; |
7147 bool is_element = name->AsArrayIndex(&index); | 7101 bool is_element = name->AsArrayIndex(&index); |
7148 | 7102 |
7149 if (is_element) { | 7103 if (is_element) { |
7150 if (object->IsJSArray()) return factory->undefined_value(); | 7104 if (object->IsJSArray()) return factory->undefined_value(); |
7151 | 7105 |
7152 // Accessors overwrite previous callbacks (cf. with getters/setters). | 7106 // Accessors overwrite previous callbacks (cf. with getters/setters). |
7153 switch (object->GetElementsKind()) { | 7107 switch (object->GetElementsKind()) { |
7154 case FAST_SMI_ELEMENTS: | 7108 case FAST_SMI_ELEMENTS: |
7155 case FAST_ELEMENTS: | 7109 case FAST_ELEMENTS: |
(...skipping 10140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17296 #define ERROR_MESSAGES_TEXTS(C, T) T, | 17250 #define ERROR_MESSAGES_TEXTS(C, T) T, |
17297 static const char* error_messages_[] = { | 17251 static const char* error_messages_[] = { |
17298 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 17252 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
17299 }; | 17253 }; |
17300 #undef ERROR_MESSAGES_TEXTS | 17254 #undef ERROR_MESSAGES_TEXTS |
17301 return error_messages_[reason]; | 17255 return error_messages_[reason]; |
17302 } | 17256 } |
17303 | 17257 |
17304 | 17258 |
17305 } } // namespace v8::internal | 17259 } } // namespace v8::internal |
OLD | NEW |