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 |