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 2808 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3394 Object* obj = result->GetCallbackObject(); | 3405 Object* obj = result->GetCallbackObject(); |
3395 if (obj->IsAccessorInfo()) { | 3406 if (obj->IsAccessorInfo()) { |
3396 AccessorInfo* info = AccessorInfo::cast(obj); | 3407 AccessorInfo* info = AccessorInfo::cast(obj); |
3397 if (info->all_can_write()) { | 3408 if (info->all_can_write()) { |
3398 return SetPropertyWithCallback(result->GetCallbackObject(), | 3409 return SetPropertyWithCallback(result->GetCallbackObject(), |
3399 name, | 3410 name, |
3400 value, | 3411 value, |
3401 result->holder(), | 3412 result->holder(), |
3402 strict_mode); | 3413 strict_mode); |
3403 } | 3414 } |
| 3415 } else if (obj->IsAccessorPair()) { |
| 3416 AccessorPair* pair = AccessorPair::cast(obj); |
| 3417 if (pair->all_can_read()) { |
| 3418 return SetPropertyWithCallback(result->GetCallbackObject(), |
| 3419 name, |
| 3420 value, |
| 3421 result->holder(), |
| 3422 strict_mode); |
| 3423 } |
3404 } | 3424 } |
3405 break; | 3425 break; |
3406 } | 3426 } |
3407 case INTERCEPTOR: { | 3427 case INTERCEPTOR: { |
3408 // Try lookup real named properties. Note that only property can be | 3428 // Try lookup real named properties. Note that only property can be |
3409 // set is callbacks marked as ALL_CAN_WRITE on the prototype chain. | 3429 // set is callbacks marked as ALL_CAN_WRITE on the prototype chain. |
3410 LookupResult r(GetIsolate()); | 3430 LookupResult r(GetIsolate()); |
3411 LookupRealNamedProperty(name, &r); | 3431 LookupRealNamedProperty(name, &r); |
3412 if (r.IsProperty()) { | 3432 if (r.IsProperty()) { |
3413 return SetPropertyWithFailedAccessCheck(&r, | 3433 return SetPropertyWithFailedAccessCheck(&r, |
(...skipping 2532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5946 } | 5966 } |
5947 } | 5967 } |
5948 return false; | 5968 return false; |
5949 } | 5969 } |
5950 | 5970 |
5951 | 5971 |
5952 void JSObject::DefineElementAccessor(Handle<JSObject> object, | 5972 void JSObject::DefineElementAccessor(Handle<JSObject> object, |
5953 uint32_t index, | 5973 uint32_t index, |
5954 Handle<Object> getter, | 5974 Handle<Object> getter, |
5955 Handle<Object> setter, | 5975 Handle<Object> setter, |
5956 PropertyAttributes attributes) { | 5976 PropertyAttributes attributes, |
| 5977 v8::AccessControl access_control) { |
5957 switch (object->GetElementsKind()) { | 5978 switch (object->GetElementsKind()) { |
5958 case FAST_SMI_ELEMENTS: | 5979 case FAST_SMI_ELEMENTS: |
5959 case FAST_ELEMENTS: | 5980 case FAST_ELEMENTS: |
5960 case FAST_DOUBLE_ELEMENTS: | 5981 case FAST_DOUBLE_ELEMENTS: |
5961 case FAST_HOLEY_SMI_ELEMENTS: | 5982 case FAST_HOLEY_SMI_ELEMENTS: |
5962 case FAST_HOLEY_ELEMENTS: | 5983 case FAST_HOLEY_ELEMENTS: |
5963 case FAST_HOLEY_DOUBLE_ELEMENTS: | 5984 case FAST_HOLEY_DOUBLE_ELEMENTS: |
5964 break; | 5985 break; |
5965 case EXTERNAL_PIXEL_ELEMENTS: | 5986 case EXTERNAL_PIXEL_ELEMENTS: |
5966 case EXTERNAL_BYTE_ELEMENTS: | 5987 case EXTERNAL_BYTE_ELEMENTS: |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6004 } | 6025 } |
6005 } | 6026 } |
6006 } | 6027 } |
6007 break; | 6028 break; |
6008 } | 6029 } |
6009 } | 6030 } |
6010 | 6031 |
6011 Isolate* isolate = object->GetIsolate(); | 6032 Isolate* isolate = object->GetIsolate(); |
6012 Handle<AccessorPair> accessors = isolate->factory()->NewAccessorPair(); | 6033 Handle<AccessorPair> accessors = isolate->factory()->NewAccessorPair(); |
6013 accessors->SetComponents(*getter, *setter); | 6034 accessors->SetComponents(*getter, *setter); |
| 6035 accessors->set_access_flags(access_control); |
6014 | 6036 |
6015 CALL_HEAP_FUNCTION_VOID( | 6037 CALL_HEAP_FUNCTION_VOID( |
6016 isolate, object->SetElementCallback(index, *accessors, attributes)); | 6038 isolate, object->SetElementCallback(index, *accessors, attributes)); |
6017 } | 6039 } |
6018 | 6040 |
6019 | 6041 |
6020 Handle<AccessorPair> JSObject::CreateAccessorPairFor(Handle<JSObject> object, | 6042 Handle<AccessorPair> JSObject::CreateAccessorPairFor(Handle<JSObject> object, |
6021 Handle<Name> name) { | 6043 Handle<Name> name) { |
6022 Isolate* isolate = object->GetIsolate(); | 6044 Isolate* isolate = object->GetIsolate(); |
6023 LookupResult result(isolate); | 6045 LookupResult result(isolate); |
(...skipping 11 matching lines...) Expand all Loading... |
6035 } | 6057 } |
6036 } | 6058 } |
6037 return isolate->factory()->NewAccessorPair(); | 6059 return isolate->factory()->NewAccessorPair(); |
6038 } | 6060 } |
6039 | 6061 |
6040 | 6062 |
6041 void JSObject::DefinePropertyAccessor(Handle<JSObject> object, | 6063 void JSObject::DefinePropertyAccessor(Handle<JSObject> object, |
6042 Handle<Name> name, | 6064 Handle<Name> name, |
6043 Handle<Object> getter, | 6065 Handle<Object> getter, |
6044 Handle<Object> setter, | 6066 Handle<Object> setter, |
6045 PropertyAttributes attributes) { | 6067 PropertyAttributes attributes, |
| 6068 v8::AccessControl access_control) { |
6046 // We could assert that the property is configurable here, but we would need | 6069 // We could assert that the property is configurable here, but we would need |
6047 // to do a lookup, which seems to be a bit of overkill. | 6070 // to do a lookup, which seems to be a bit of overkill. |
6048 bool only_attribute_changes = getter->IsNull() && setter->IsNull(); | 6071 bool only_attribute_changes = getter->IsNull() && setter->IsNull(); |
6049 if (object->HasFastProperties() && !only_attribute_changes && | 6072 if (object->HasFastProperties() && !only_attribute_changes && |
| 6073 access_control == v8::DEFAULT && |
6050 (object->map()->NumberOfOwnDescriptors() < | 6074 (object->map()->NumberOfOwnDescriptors() < |
6051 DescriptorArray::kMaxNumberOfDescriptors)) { | 6075 DescriptorArray::kMaxNumberOfDescriptors)) { |
6052 bool getterOk = getter->IsNull() || | 6076 bool getterOk = getter->IsNull() || |
6053 DefineFastAccessor(object, name, ACCESSOR_GETTER, getter, attributes); | 6077 DefineFastAccessor(object, name, ACCESSOR_GETTER, getter, attributes); |
6054 bool setterOk = !getterOk || setter->IsNull() || | 6078 bool setterOk = !getterOk || setter->IsNull() || |
6055 DefineFastAccessor(object, name, ACCESSOR_SETTER, setter, attributes); | 6079 DefineFastAccessor(object, name, ACCESSOR_SETTER, setter, attributes); |
6056 if (getterOk && setterOk) return; | 6080 if (getterOk && setterOk) return; |
6057 } | 6081 } |
6058 | 6082 |
6059 Handle<AccessorPair> accessors = CreateAccessorPairFor(object, name); | 6083 Handle<AccessorPair> accessors = CreateAccessorPairFor(object, name); |
6060 accessors->SetComponents(*getter, *setter); | 6084 accessors->SetComponents(*getter, *setter); |
| 6085 accessors->set_access_flags(access_control); |
6061 | 6086 |
6062 CALL_HEAP_FUNCTION_VOID( | 6087 CALL_HEAP_FUNCTION_VOID( |
6063 object->GetIsolate(), | 6088 object->GetIsolate(), |
6064 object->SetPropertyCallback(*name, *accessors, attributes)); | 6089 object->SetPropertyCallback(*name, *accessors, attributes)); |
6065 } | 6090 } |
6066 | 6091 |
6067 | 6092 |
6068 bool JSObject::CanSetCallback(Name* name) { | 6093 bool JSObject::CanSetCallback(Name* name) { |
6069 ASSERT(!IsAccessCheckNeeded() || | 6094 ASSERT(!IsAccessCheckNeeded() || |
6070 GetIsolate()->MayNamedAccess(this, name, v8::ACCESS_SET)); | 6095 GetIsolate()->MayNamedAccess(this, name, v8::ACCESS_SET)); |
6071 | 6096 |
6072 // Check if there is an API defined callback object which prohibits | 6097 // Check if there is an API defined callback object which prohibits |
6073 // callback overwriting in this object or its prototype chain. | 6098 // callback overwriting in this object or its prototype chain. |
6074 // This mechanism is needed for instance in a browser setting, where | 6099 // This mechanism is needed for instance in a browser setting, where |
6075 // certain accessors such as window.location should not be allowed | 6100 // certain accessors such as window.location should not be allowed |
6076 // to be overwritten because allowing overwriting could potentially | 6101 // to be overwritten because allowing overwriting could potentially |
6077 // cause security problems. | 6102 // cause security problems. |
6078 LookupResult callback_result(GetIsolate()); | 6103 LookupResult callback_result(GetIsolate()); |
6079 LookupCallbackProperty(name, &callback_result); | 6104 LookupCallbackProperty(name, &callback_result); |
6080 if (callback_result.IsFound()) { | 6105 if (callback_result.IsFound()) { |
6081 Object* obj = callback_result.GetCallbackObject(); | 6106 Object* obj = callback_result.GetCallbackObject(); |
6082 if (obj->IsAccessorInfo() && | 6107 if (obj->IsAccessorInfo()) { |
6083 AccessorInfo::cast(obj)->prohibits_overwriting()) { | 6108 return !AccessorInfo::cast(obj)->prohibits_overwriting(); |
6084 return false; | 6109 } |
| 6110 if (obj->IsAccessorPair()) { |
| 6111 return !AccessorPair::cast(obj)->prohibits_overwriting(); |
6085 } | 6112 } |
6086 } | 6113 } |
6087 | |
6088 return true; | 6114 return true; |
6089 } | 6115 } |
6090 | 6116 |
6091 | 6117 |
6092 MaybeObject* JSObject::SetElementCallback(uint32_t index, | 6118 MaybeObject* JSObject::SetElementCallback(uint32_t index, |
6093 Object* structure, | 6119 Object* structure, |
6094 PropertyAttributes attributes) { | 6120 PropertyAttributes attributes) { |
6095 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); | 6121 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); |
6096 | 6122 |
6097 // Normalize elements to make this operation simple. | 6123 // Normalize elements to make this operation simple. |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6155 if (maybe_ok->IsFailure()) return maybe_ok; | 6181 if (maybe_ok->IsFailure()) return maybe_ok; |
6156 | 6182 |
6157 return GetHeap()->undefined_value(); | 6183 return GetHeap()->undefined_value(); |
6158 } | 6184 } |
6159 | 6185 |
6160 | 6186 |
6161 void JSObject::DefineAccessor(Handle<JSObject> object, | 6187 void JSObject::DefineAccessor(Handle<JSObject> object, |
6162 Handle<Name> name, | 6188 Handle<Name> name, |
6163 Handle<Object> getter, | 6189 Handle<Object> getter, |
6164 Handle<Object> setter, | 6190 Handle<Object> setter, |
6165 PropertyAttributes attributes) { | 6191 PropertyAttributes attributes, |
| 6192 v8::AccessControl access_control) { |
6166 Isolate* isolate = object->GetIsolate(); | 6193 Isolate* isolate = object->GetIsolate(); |
6167 // Check access rights if needed. | 6194 // Check access rights if needed. |
6168 if (object->IsAccessCheckNeeded() && | 6195 if (object->IsAccessCheckNeeded() && |
6169 !isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) { | 6196 !isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) { |
6170 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_SET); | 6197 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_SET); |
6171 return; | 6198 return; |
6172 } | 6199 } |
6173 | 6200 |
6174 if (object->IsJSGlobalProxy()) { | 6201 if (object->IsJSGlobalProxy()) { |
6175 Handle<Object> proto(object->GetPrototype(), isolate); | 6202 Handle<Object> proto(object->GetPrototype(), isolate); |
6176 if (proto->IsNull()) return; | 6203 if (proto->IsNull()) return; |
6177 ASSERT(proto->IsJSGlobalObject()); | 6204 ASSERT(proto->IsJSGlobalObject()); |
6178 DefineAccessor( | 6205 DefineAccessor(Handle<JSObject>::cast(proto), |
6179 Handle<JSObject>::cast(proto), name, getter, setter, attributes); | 6206 name, |
| 6207 getter, |
| 6208 setter, |
| 6209 attributes, |
| 6210 access_control); |
6180 return; | 6211 return; |
6181 } | 6212 } |
6182 | 6213 |
6183 // Make sure that the top context does not change when doing callbacks or | 6214 // Make sure that the top context does not change when doing callbacks or |
6184 // interceptor calls. | 6215 // interceptor calls. |
6185 AssertNoContextChange ncc; | 6216 AssertNoContextChange ncc; |
6186 | 6217 |
6187 // Try to flatten before operating on the string. | 6218 // Try to flatten before operating on the string. |
6188 if (name->IsString()) String::cast(*name)->TryFlatten(); | 6219 if (name->IsString()) String::cast(*name)->TryFlatten(); |
6189 | 6220 |
(...skipping 15 matching lines...) Expand all Loading... |
6205 LookupResult lookup(isolate); | 6236 LookupResult lookup(isolate); |
6206 object->LocalLookup(*name, &lookup, true); | 6237 object->LocalLookup(*name, &lookup, true); |
6207 preexists = lookup.IsProperty(); | 6238 preexists = lookup.IsProperty(); |
6208 if (preexists && lookup.IsDataProperty()) { | 6239 if (preexists && lookup.IsDataProperty()) { |
6209 old_value = Object::GetProperty(object, name); | 6240 old_value = Object::GetProperty(object, name); |
6210 } | 6241 } |
6211 } | 6242 } |
6212 } | 6243 } |
6213 | 6244 |
6214 if (is_element) { | 6245 if (is_element) { |
6215 DefineElementAccessor(object, index, getter, setter, attributes); | 6246 DefineElementAccessor( |
| 6247 object, index, getter, setter, attributes, access_control); |
6216 } else { | 6248 } else { |
6217 DefinePropertyAccessor(object, name, getter, setter, attributes); | 6249 DefinePropertyAccessor( |
| 6250 object, name, getter, setter, attributes, access_control); |
6218 } | 6251 } |
6219 | 6252 |
6220 if (is_observed) { | 6253 if (is_observed) { |
6221 const char* type = preexists ? "reconfigured" : "new"; | 6254 const char* type = preexists ? "reconfigured" : "new"; |
6222 EnqueueChangeRecord(object, type, name, old_value); | 6255 EnqueueChangeRecord(object, type, name, old_value); |
6223 } | 6256 } |
6224 } | 6257 } |
6225 | 6258 |
6226 | 6259 |
6227 static bool TryAccessorTransition(JSObject* self, | 6260 static bool TryAccessorTransition(JSObject* self, |
(...skipping 9779 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16007 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16040 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16008 static const char* error_messages_[] = { | 16041 static const char* error_messages_[] = { |
16009 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16042 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16010 }; | 16043 }; |
16011 #undef ERROR_MESSAGES_TEXTS | 16044 #undef ERROR_MESSAGES_TEXTS |
16012 return error_messages_[reason]; | 16045 return error_messages_[reason]; |
16013 } | 16046 } |
16014 | 16047 |
16015 | 16048 |
16016 } } // namespace v8::internal | 16049 } } // namespace v8::internal |
OLD | NEW |