| 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 |