| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 506 case CALLBACKS: { | 506 case CALLBACKS: { |
| 507 // Only allow API accessors. | 507 // Only allow API accessors. |
| 508 Object* obj = result->GetCallbackObject(); | 508 Object* obj = result->GetCallbackObject(); |
| 509 if (obj->IsAccessorInfo()) { | 509 if (obj->IsAccessorInfo()) { |
| 510 AccessorInfo* info = AccessorInfo::cast(obj); | 510 AccessorInfo* info = AccessorInfo::cast(obj); |
| 511 if (info->all_can_read()) { | 511 if (info->all_can_read()) { |
| 512 *attributes = result->GetAttributes(); | 512 *attributes = result->GetAttributes(); |
| 513 return result->holder()->GetPropertyWithCallback( | 513 return result->holder()->GetPropertyWithCallback( |
| 514 receiver, result->GetCallbackObject(), name); | 514 receiver, result->GetCallbackObject(), name); |
| 515 } | 515 } |
| 516 } else if (obj->IsAccessorPair()) { |
| 517 AccessorPair* pair = AccessorPair::cast(obj); |
| 518 if (pair->all_can_read()) { |
| 519 return result->holder()->GetPropertyWithCallback( |
| 520 receiver, result->GetCallbackObject(), name); |
| 521 } |
| 516 } | 522 } |
| 517 break; | 523 break; |
| 518 } | 524 } |
| 519 case NORMAL: | 525 case NORMAL: |
| 520 case FIELD: | 526 case FIELD: |
| 521 case CONSTANT: { | 527 case CONSTANT: { |
| 522 // Search ALL_CAN_READ accessors in prototype chain. | 528 // Search ALL_CAN_READ accessors in prototype chain. |
| 523 LookupResult r(GetIsolate()); | 529 LookupResult r(GetIsolate()); |
| 524 result->holder()->LookupRealNamedPropertyInPrototypes(name, &r); | 530 result->holder()->LookupRealNamedPropertyInPrototypes(name, &r); |
| 525 if (r.IsProperty()) { | 531 if (r.IsProperty()) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 566 if (result->IsProperty()) { | 572 if (result->IsProperty()) { |
| 567 switch (result->type()) { | 573 switch (result->type()) { |
| 568 case CALLBACKS: { | 574 case CALLBACKS: { |
| 569 // Only allow API accessors. | 575 // Only allow API accessors. |
| 570 Object* obj = result->GetCallbackObject(); | 576 Object* obj = result->GetCallbackObject(); |
| 571 if (obj->IsAccessorInfo()) { | 577 if (obj->IsAccessorInfo()) { |
| 572 AccessorInfo* info = AccessorInfo::cast(obj); | 578 AccessorInfo* info = AccessorInfo::cast(obj); |
| 573 if (info->all_can_read()) { | 579 if (info->all_can_read()) { |
| 574 return result->GetAttributes(); | 580 return result->GetAttributes(); |
| 575 } | 581 } |
| 582 } else if (obj->IsAccessorPair()) { |
| 583 AccessorPair* pair = AccessorPair::cast(obj); |
| 584 if (pair->all_can_read()) { |
| 585 return result->GetAttributes(); |
| 586 } |
| 576 } | 587 } |
| 577 break; | 588 break; |
| 578 } | 589 } |
| 579 | 590 |
| 580 case NORMAL: | 591 case NORMAL: |
| 581 case FIELD: | 592 case FIELD: |
| 582 case CONSTANT: { | 593 case CONSTANT: { |
| 583 if (!continue_search) break; | 594 if (!continue_search) break; |
| 584 // Search ALL_CAN_READ accessors in prototype chain. | 595 // Search ALL_CAN_READ accessors in prototype chain. |
| 585 LookupResult r(GetIsolate()); | 596 LookupResult r(GetIsolate()); |
| (...skipping 2802 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3388 Object* obj = result->GetCallbackObject(); | 3399 Object* obj = result->GetCallbackObject(); |
| 3389 if (obj->IsAccessorInfo()) { | 3400 if (obj->IsAccessorInfo()) { |
| 3390 AccessorInfo* info = AccessorInfo::cast(obj); | 3401 AccessorInfo* info = AccessorInfo::cast(obj); |
| 3391 if (info->all_can_write()) { | 3402 if (info->all_can_write()) { |
| 3392 return SetPropertyWithCallback(result->GetCallbackObject(), | 3403 return SetPropertyWithCallback(result->GetCallbackObject(), |
| 3393 name, | 3404 name, |
| 3394 value, | 3405 value, |
| 3395 result->holder(), | 3406 result->holder(), |
| 3396 strict_mode); | 3407 strict_mode); |
| 3397 } | 3408 } |
| 3409 } else if (obj->IsAccessorPair()) { |
| 3410 AccessorPair* pair = AccessorPair::cast(obj); |
| 3411 if (pair->all_can_read()) { |
| 3412 return SetPropertyWithCallback(result->GetCallbackObject(), |
| 3413 name, |
| 3414 value, |
| 3415 result->holder(), |
| 3416 strict_mode); |
| 3417 } |
| 3398 } | 3418 } |
| 3399 break; | 3419 break; |
| 3400 } | 3420 } |
| 3401 case INTERCEPTOR: { | 3421 case INTERCEPTOR: { |
| 3402 // Try lookup real named properties. Note that only property can be | 3422 // Try lookup real named properties. Note that only property can be |
| 3403 // set is callbacks marked as ALL_CAN_WRITE on the prototype chain. | 3423 // set is callbacks marked as ALL_CAN_WRITE on the prototype chain. |
| 3404 LookupResult r(GetIsolate()); | 3424 LookupResult r(GetIsolate()); |
| 3405 LookupRealNamedProperty(name, &r); | 3425 LookupRealNamedProperty(name, &r); |
| 3406 if (r.IsProperty()) { | 3426 if (r.IsProperty()) { |
| 3407 return SetPropertyWithFailedAccessCheck(&r, | 3427 return SetPropertyWithFailedAccessCheck(&r, |
| (...skipping 2477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5885 } | 5905 } |
| 5886 } | 5906 } |
| 5887 return false; | 5907 return false; |
| 5888 } | 5908 } |
| 5889 | 5909 |
| 5890 | 5910 |
| 5891 void JSObject::DefineElementAccessor(Handle<JSObject> object, | 5911 void JSObject::DefineElementAccessor(Handle<JSObject> object, |
| 5892 uint32_t index, | 5912 uint32_t index, |
| 5893 Handle<Object> getter, | 5913 Handle<Object> getter, |
| 5894 Handle<Object> setter, | 5914 Handle<Object> setter, |
| 5895 PropertyAttributes attributes) { | 5915 PropertyAttributes attributes, |
| 5916 v8::AccessControl access_control) { |
| 5896 switch (object->GetElementsKind()) { | 5917 switch (object->GetElementsKind()) { |
| 5897 case FAST_SMI_ELEMENTS: | 5918 case FAST_SMI_ELEMENTS: |
| 5898 case FAST_ELEMENTS: | 5919 case FAST_ELEMENTS: |
| 5899 case FAST_DOUBLE_ELEMENTS: | 5920 case FAST_DOUBLE_ELEMENTS: |
| 5900 case FAST_HOLEY_SMI_ELEMENTS: | 5921 case FAST_HOLEY_SMI_ELEMENTS: |
| 5901 case FAST_HOLEY_ELEMENTS: | 5922 case FAST_HOLEY_ELEMENTS: |
| 5902 case FAST_HOLEY_DOUBLE_ELEMENTS: | 5923 case FAST_HOLEY_DOUBLE_ELEMENTS: |
| 5903 break; | 5924 break; |
| 5904 case EXTERNAL_PIXEL_ELEMENTS: | 5925 case EXTERNAL_PIXEL_ELEMENTS: |
| 5905 case EXTERNAL_BYTE_ELEMENTS: | 5926 case EXTERNAL_BYTE_ELEMENTS: |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5943 } | 5964 } |
| 5944 } | 5965 } |
| 5945 } | 5966 } |
| 5946 break; | 5967 break; |
| 5947 } | 5968 } |
| 5948 } | 5969 } |
| 5949 | 5970 |
| 5950 Isolate* isolate = object->GetIsolate(); | 5971 Isolate* isolate = object->GetIsolate(); |
| 5951 Handle<AccessorPair> accessors = isolate->factory()->NewAccessorPair(); | 5972 Handle<AccessorPair> accessors = isolate->factory()->NewAccessorPair(); |
| 5952 accessors->SetComponents(*getter, *setter); | 5973 accessors->SetComponents(*getter, *setter); |
| 5974 accessors->set_access_flags(access_control); |
| 5953 | 5975 |
| 5954 CALL_HEAP_FUNCTION_VOID( | 5976 CALL_HEAP_FUNCTION_VOID( |
| 5955 isolate, object->SetElementCallback(index, *accessors, attributes)); | 5977 isolate, object->SetElementCallback(index, *accessors, attributes)); |
| 5956 } | 5978 } |
| 5957 | 5979 |
| 5958 | 5980 |
| 5959 Handle<AccessorPair> JSObject::CreateAccessorPairFor(Handle<JSObject> object, | 5981 Handle<AccessorPair> JSObject::CreateAccessorPairFor(Handle<JSObject> object, |
| 5960 Handle<Name> name) { | 5982 Handle<Name> name) { |
| 5961 Isolate* isolate = object->GetIsolate(); | 5983 Isolate* isolate = object->GetIsolate(); |
| 5962 LookupResult result(isolate); | 5984 LookupResult result(isolate); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 5974 } | 5996 } |
| 5975 } | 5997 } |
| 5976 return isolate->factory()->NewAccessorPair(); | 5998 return isolate->factory()->NewAccessorPair(); |
| 5977 } | 5999 } |
| 5978 | 6000 |
| 5979 | 6001 |
| 5980 void JSObject::DefinePropertyAccessor(Handle<JSObject> object, | 6002 void JSObject::DefinePropertyAccessor(Handle<JSObject> object, |
| 5981 Handle<Name> name, | 6003 Handle<Name> name, |
| 5982 Handle<Object> getter, | 6004 Handle<Object> getter, |
| 5983 Handle<Object> setter, | 6005 Handle<Object> setter, |
| 5984 PropertyAttributes attributes) { | 6006 PropertyAttributes attributes, |
| 6007 v8::AccessControl access_control) { |
| 5985 // We could assert that the property is configurable here, but we would need | 6008 // We could assert that the property is configurable here, but we would need |
| 5986 // to do a lookup, which seems to be a bit of overkill. | 6009 // to do a lookup, which seems to be a bit of overkill. |
| 5987 bool only_attribute_changes = getter->IsNull() && setter->IsNull(); | 6010 bool only_attribute_changes = getter->IsNull() && setter->IsNull(); |
| 5988 if (object->HasFastProperties() && !only_attribute_changes && | 6011 if (object->HasFastProperties() && !only_attribute_changes && |
| 6012 access_control == v8::DEFAULT && |
| 5989 (object->map()->NumberOfOwnDescriptors() < | 6013 (object->map()->NumberOfOwnDescriptors() < |
| 5990 DescriptorArray::kMaxNumberOfDescriptors)) { | 6014 DescriptorArray::kMaxNumberOfDescriptors)) { |
| 5991 bool getterOk = getter->IsNull() || | 6015 bool getterOk = getter->IsNull() || |
| 5992 DefineFastAccessor(object, name, ACCESSOR_GETTER, getter, attributes); | 6016 DefineFastAccessor(object, name, ACCESSOR_GETTER, getter, attributes); |
| 5993 bool setterOk = !getterOk || setter->IsNull() || | 6017 bool setterOk = !getterOk || setter->IsNull() || |
| 5994 DefineFastAccessor(object, name, ACCESSOR_SETTER, setter, attributes); | 6018 DefineFastAccessor(object, name, ACCESSOR_SETTER, setter, attributes); |
| 5995 if (getterOk && setterOk) return; | 6019 if (getterOk && setterOk) return; |
| 5996 } | 6020 } |
| 5997 | 6021 |
| 5998 Handle<AccessorPair> accessors = CreateAccessorPairFor(object, name); | 6022 Handle<AccessorPair> accessors = CreateAccessorPairFor(object, name); |
| 5999 accessors->SetComponents(*getter, *setter); | 6023 accessors->SetComponents(*getter, *setter); |
| 6024 accessors->set_access_flags(access_control); |
| 6000 | 6025 |
| 6001 CALL_HEAP_FUNCTION_VOID( | 6026 CALL_HEAP_FUNCTION_VOID( |
| 6002 object->GetIsolate(), | 6027 object->GetIsolate(), |
| 6003 object->SetPropertyCallback(*name, *accessors, attributes)); | 6028 object->SetPropertyCallback(*name, *accessors, attributes)); |
| 6004 } | 6029 } |
| 6005 | 6030 |
| 6006 | 6031 |
| 6007 bool JSObject::CanSetCallback(Name* name) { | 6032 bool JSObject::CanSetCallback(Name* name) { |
| 6008 ASSERT(!IsAccessCheckNeeded() || | 6033 ASSERT(!IsAccessCheckNeeded() || |
| 6009 GetIsolate()->MayNamedAccess(this, name, v8::ACCESS_SET)); | 6034 GetIsolate()->MayNamedAccess(this, name, v8::ACCESS_SET)); |
| 6010 | 6035 |
| 6011 // Check if there is an API defined callback object which prohibits | 6036 // Check if there is an API defined callback object which prohibits |
| 6012 // callback overwriting in this object or its prototype chain. | 6037 // callback overwriting in this object or its prototype chain. |
| 6013 // This mechanism is needed for instance in a browser setting, where | 6038 // This mechanism is needed for instance in a browser setting, where |
| 6014 // certain accessors such as window.location should not be allowed | 6039 // certain accessors such as window.location should not be allowed |
| 6015 // to be overwritten because allowing overwriting could potentially | 6040 // to be overwritten because allowing overwriting could potentially |
| 6016 // cause security problems. | 6041 // cause security problems. |
| 6017 LookupResult callback_result(GetIsolate()); | 6042 LookupResult callback_result(GetIsolate()); |
| 6018 LookupCallbackProperty(name, &callback_result); | 6043 LookupCallbackProperty(name, &callback_result); |
| 6019 if (callback_result.IsFound()) { | 6044 if (callback_result.IsFound()) { |
| 6020 Object* obj = callback_result.GetCallbackObject(); | 6045 Object* obj = callback_result.GetCallbackObject(); |
| 6021 if (obj->IsAccessorInfo() && | 6046 if (obj->IsAccessorInfo()) { |
| 6022 AccessorInfo::cast(obj)->prohibits_overwriting()) { | 6047 return !AccessorInfo::cast(obj)->prohibits_overwriting(); |
| 6023 return false; | 6048 } |
| 6049 if (obj->IsAccessorPair()) { |
| 6050 return !AccessorPair::cast(obj)->prohibits_overwriting(); |
| 6024 } | 6051 } |
| 6025 } | 6052 } |
| 6026 | |
| 6027 return true; | 6053 return true; |
| 6028 } | 6054 } |
| 6029 | 6055 |
| 6030 | 6056 |
| 6031 MaybeObject* JSObject::SetElementCallback(uint32_t index, | 6057 MaybeObject* JSObject::SetElementCallback(uint32_t index, |
| 6032 Object* structure, | 6058 Object* structure, |
| 6033 PropertyAttributes attributes) { | 6059 PropertyAttributes attributes) { |
| 6034 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); | 6060 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); |
| 6035 | 6061 |
| 6036 // Normalize elements to make this operation simple. | 6062 // Normalize elements to make this operation simple. |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6094 if (maybe_ok->IsFailure()) return maybe_ok; | 6120 if (maybe_ok->IsFailure()) return maybe_ok; |
| 6095 | 6121 |
| 6096 return GetHeap()->undefined_value(); | 6122 return GetHeap()->undefined_value(); |
| 6097 } | 6123 } |
| 6098 | 6124 |
| 6099 | 6125 |
| 6100 void JSObject::DefineAccessor(Handle<JSObject> object, | 6126 void JSObject::DefineAccessor(Handle<JSObject> object, |
| 6101 Handle<Name> name, | 6127 Handle<Name> name, |
| 6102 Handle<Object> getter, | 6128 Handle<Object> getter, |
| 6103 Handle<Object> setter, | 6129 Handle<Object> setter, |
| 6104 PropertyAttributes attributes) { | 6130 PropertyAttributes attributes, |
| 6131 v8::AccessControl access_control) { |
| 6105 Isolate* isolate = object->GetIsolate(); | 6132 Isolate* isolate = object->GetIsolate(); |
| 6106 // Check access rights if needed. | 6133 // Check access rights if needed. |
| 6107 if (object->IsAccessCheckNeeded() && | 6134 if (object->IsAccessCheckNeeded() && |
| 6108 !isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) { | 6135 !isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) { |
| 6109 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_SET); | 6136 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_SET); |
| 6110 return; | 6137 return; |
| 6111 } | 6138 } |
| 6112 | 6139 |
| 6113 if (object->IsJSGlobalProxy()) { | 6140 if (object->IsJSGlobalProxy()) { |
| 6114 Handle<Object> proto(object->GetPrototype(), isolate); | 6141 Handle<Object> proto(object->GetPrototype(), isolate); |
| 6115 if (proto->IsNull()) return; | 6142 if (proto->IsNull()) return; |
| 6116 ASSERT(proto->IsJSGlobalObject()); | 6143 ASSERT(proto->IsJSGlobalObject()); |
| 6117 DefineAccessor( | 6144 DefineAccessor(Handle<JSObject>::cast(proto), |
| 6118 Handle<JSObject>::cast(proto), name, getter, setter, attributes); | 6145 name, |
| 6146 getter, |
| 6147 setter, |
| 6148 attributes, |
| 6149 access_control); |
| 6119 return; | 6150 return; |
| 6120 } | 6151 } |
| 6121 | 6152 |
| 6122 // Make sure that the top context does not change when doing callbacks or | 6153 // Make sure that the top context does not change when doing callbacks or |
| 6123 // interceptor calls. | 6154 // interceptor calls. |
| 6124 AssertNoContextChange ncc; | 6155 AssertNoContextChange ncc; |
| 6125 | 6156 |
| 6126 // Try to flatten before operating on the string. | 6157 // Try to flatten before operating on the string. |
| 6127 if (name->IsString()) String::cast(*name)->TryFlatten(); | 6158 if (name->IsString()) String::cast(*name)->TryFlatten(); |
| 6128 | 6159 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 6144 LookupResult lookup(isolate); | 6175 LookupResult lookup(isolate); |
| 6145 object->LocalLookup(*name, &lookup, true); | 6176 object->LocalLookup(*name, &lookup, true); |
| 6146 preexists = lookup.IsProperty(); | 6177 preexists = lookup.IsProperty(); |
| 6147 if (preexists && lookup.IsDataProperty()) { | 6178 if (preexists && lookup.IsDataProperty()) { |
| 6148 old_value = Object::GetProperty(object, name); | 6179 old_value = Object::GetProperty(object, name); |
| 6149 } | 6180 } |
| 6150 } | 6181 } |
| 6151 } | 6182 } |
| 6152 | 6183 |
| 6153 if (is_element) { | 6184 if (is_element) { |
| 6154 DefineElementAccessor(object, index, getter, setter, attributes); | 6185 DefineElementAccessor( |
| 6186 object, index, getter, setter, attributes, access_control); |
| 6155 } else { | 6187 } else { |
| 6156 DefinePropertyAccessor(object, name, getter, setter, attributes); | 6188 DefinePropertyAccessor( |
| 6189 object, name, getter, setter, attributes, access_control); |
| 6157 } | 6190 } |
| 6158 | 6191 |
| 6159 if (is_observed) { | 6192 if (is_observed) { |
| 6160 const char* type = preexists ? "reconfigured" : "new"; | 6193 const char* type = preexists ? "reconfigured" : "new"; |
| 6161 EnqueueChangeRecord(object, type, name, old_value); | 6194 EnqueueChangeRecord(object, type, name, old_value); |
| 6162 } | 6195 } |
| 6163 } | 6196 } |
| 6164 | 6197 |
| 6165 | 6198 |
| 6166 static bool TryAccessorTransition(JSObject* self, | 6199 static bool TryAccessorTransition(JSObject* self, |
| (...skipping 9782 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15949 #define ERROR_MESSAGES_TEXTS(C, T) T, | 15982 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 15950 static const char* error_messages_[] = { | 15983 static const char* error_messages_[] = { |
| 15951 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 15984 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 15952 }; | 15985 }; |
| 15953 #undef ERROR_MESSAGES_TEXTS | 15986 #undef ERROR_MESSAGES_TEXTS |
| 15954 return error_messages_[reason]; | 15987 return error_messages_[reason]; |
| 15955 } | 15988 } |
| 15956 | 15989 |
| 15957 | 15990 |
| 15958 } } // namespace v8::internal | 15991 } } // namespace v8::internal |
| OLD | NEW |