Chromium Code Reviews| 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()) { | |
|
Sven Panne
2013/08/21 10:46:25
Just curious: Can we reach this code path with For
dcarney
2013/08/21 10:59:33
there's no access overrides for foreign callbacks,
| |
| 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()) { | |
|
Sven Panne
2013/08/21 10:46:25
Same here.
| |
| 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 2768 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3354 Object* obj = result->GetCallbackObject(); | 3365 Object* obj = result->GetCallbackObject(); |
| 3355 if (obj->IsAccessorInfo()) { | 3366 if (obj->IsAccessorInfo()) { |
| 3356 AccessorInfo* info = AccessorInfo::cast(obj); | 3367 AccessorInfo* info = AccessorInfo::cast(obj); |
| 3357 if (info->all_can_write()) { | 3368 if (info->all_can_write()) { |
| 3358 return SetPropertyWithCallback(result->GetCallbackObject(), | 3369 return SetPropertyWithCallback(result->GetCallbackObject(), |
| 3359 name, | 3370 name, |
| 3360 value, | 3371 value, |
| 3361 result->holder(), | 3372 result->holder(), |
| 3362 strict_mode); | 3373 strict_mode); |
| 3363 } | 3374 } |
| 3375 } else if (obj->IsAccessorPair()) { | |
|
Sven Panne
2013/08/21 10:46:25
... and here.
| |
| 3376 AccessorPair* pair = AccessorPair::cast(obj); | |
| 3377 if (pair->all_can_read()) { | |
| 3378 return SetPropertyWithCallback(result->GetCallbackObject(), | |
| 3379 name, | |
| 3380 value, | |
| 3381 result->holder(), | |
| 3382 strict_mode); | |
| 3383 } | |
| 3364 } | 3384 } |
| 3365 break; | 3385 break; |
| 3366 } | 3386 } |
| 3367 case INTERCEPTOR: { | 3387 case INTERCEPTOR: { |
| 3368 // Try lookup real named properties. Note that only property can be | 3388 // Try lookup real named properties. Note that only property can be |
| 3369 // set is callbacks marked as ALL_CAN_WRITE on the prototype chain. | 3389 // set is callbacks marked as ALL_CAN_WRITE on the prototype chain. |
| 3370 LookupResult r(GetIsolate()); | 3390 LookupResult r(GetIsolate()); |
| 3371 LookupRealNamedProperty(name, &r); | 3391 LookupRealNamedProperty(name, &r); |
| 3372 if (r.IsProperty()) { | 3392 if (r.IsProperty()) { |
| 3373 return SetPropertyWithFailedAccessCheck(&r, | 3393 return SetPropertyWithFailedAccessCheck(&r, |
| (...skipping 2631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6005 } | 6025 } |
| 6006 } | 6026 } |
| 6007 return isolate->factory()->NewAccessorPair(); | 6027 return isolate->factory()->NewAccessorPair(); |
| 6008 } | 6028 } |
| 6009 | 6029 |
| 6010 | 6030 |
| 6011 void JSObject::DefinePropertyAccessor(Handle<JSObject> object, | 6031 void JSObject::DefinePropertyAccessor(Handle<JSObject> object, |
| 6012 Handle<Name> name, | 6032 Handle<Name> name, |
| 6013 Handle<Object> getter, | 6033 Handle<Object> getter, |
| 6014 Handle<Object> setter, | 6034 Handle<Object> setter, |
| 6015 PropertyAttributes attributes) { | 6035 PropertyAttributes attributes, |
| 6036 v8::AccessControl access_control) { | |
| 6016 // We could assert that the property is configurable here, but we would need | 6037 // We could assert that the property is configurable here, but we would need |
| 6017 // to do a lookup, which seems to be a bit of overkill. | 6038 // to do a lookup, which seems to be a bit of overkill. |
| 6018 bool only_attribute_changes = getter->IsNull() && setter->IsNull(); | 6039 bool only_attribute_changes = getter->IsNull() && setter->IsNull(); |
| 6019 if (object->HasFastProperties() && !only_attribute_changes && | 6040 if (object->HasFastProperties() && !only_attribute_changes && |
| 6041 access_control == v8::DEFAULT && | |
| 6020 (object->map()->NumberOfOwnDescriptors() < | 6042 (object->map()->NumberOfOwnDescriptors() < |
| 6021 DescriptorArray::kMaxNumberOfDescriptors)) { | 6043 DescriptorArray::kMaxNumberOfDescriptors)) { |
| 6022 bool getterOk = getter->IsNull() || | 6044 bool getterOk = getter->IsNull() || |
| 6023 DefineFastAccessor(object, name, ACCESSOR_GETTER, getter, attributes); | 6045 DefineFastAccessor(object, name, ACCESSOR_GETTER, getter, attributes); |
| 6024 bool setterOk = !getterOk || setter->IsNull() || | 6046 bool setterOk = !getterOk || setter->IsNull() || |
| 6025 DefineFastAccessor(object, name, ACCESSOR_SETTER, setter, attributes); | 6047 DefineFastAccessor(object, name, ACCESSOR_SETTER, setter, attributes); |
| 6026 if (getterOk && setterOk) return; | 6048 if (getterOk && setterOk) return; |
| 6027 } | 6049 } |
| 6028 | 6050 |
| 6029 Handle<AccessorPair> accessors = CreateAccessorPairFor(object, name); | 6051 Handle<AccessorPair> accessors = CreateAccessorPairFor(object, name); |
| 6030 accessors->SetComponents(*getter, *setter); | 6052 accessors->SetComponents(*getter, *setter); |
| 6053 accessors->set_access_flags(access_control); | |
| 6031 | 6054 |
| 6032 CALL_HEAP_FUNCTION_VOID( | 6055 CALL_HEAP_FUNCTION_VOID( |
| 6033 object->GetIsolate(), | 6056 object->GetIsolate(), |
| 6034 object->SetPropertyCallback(*name, *accessors, attributes)); | 6057 object->SetPropertyCallback(*name, *accessors, attributes)); |
| 6035 } | 6058 } |
| 6036 | 6059 |
| 6037 | 6060 |
| 6038 bool JSObject::CanSetCallback(Name* name) { | 6061 bool JSObject::CanSetCallback(Name* name) { |
| 6039 ASSERT(!IsAccessCheckNeeded() || | 6062 ASSERT(!IsAccessCheckNeeded() || |
| 6040 GetIsolate()->MayNamedAccess(this, name, v8::ACCESS_SET)); | 6063 GetIsolate()->MayNamedAccess(this, name, v8::ACCESS_SET)); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6125 if (maybe_ok->IsFailure()) return maybe_ok; | 6148 if (maybe_ok->IsFailure()) return maybe_ok; |
| 6126 | 6149 |
| 6127 return GetHeap()->undefined_value(); | 6150 return GetHeap()->undefined_value(); |
| 6128 } | 6151 } |
| 6129 | 6152 |
| 6130 | 6153 |
| 6131 void JSObject::DefineAccessor(Handle<JSObject> object, | 6154 void JSObject::DefineAccessor(Handle<JSObject> object, |
| 6132 Handle<Name> name, | 6155 Handle<Name> name, |
| 6133 Handle<Object> getter, | 6156 Handle<Object> getter, |
| 6134 Handle<Object> setter, | 6157 Handle<Object> setter, |
| 6135 PropertyAttributes attributes) { | 6158 PropertyAttributes attributes, |
| 6159 v8::AccessControl access_control) { | |
| 6136 Isolate* isolate = object->GetIsolate(); | 6160 Isolate* isolate = object->GetIsolate(); |
| 6137 // Check access rights if needed. | 6161 // Check access rights if needed. |
| 6138 if (object->IsAccessCheckNeeded() && | 6162 if (object->IsAccessCheckNeeded() && |
| 6139 !isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) { | 6163 !isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) { |
| 6140 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_SET); | 6164 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_SET); |
| 6141 return; | 6165 return; |
| 6142 } | 6166 } |
| 6143 | 6167 |
| 6144 if (object->IsJSGlobalProxy()) { | 6168 if (object->IsJSGlobalProxy()) { |
| 6145 Handle<Object> proto(object->GetPrototype(), isolate); | 6169 Handle<Object> proto(object->GetPrototype(), isolate); |
| 6146 if (proto->IsNull()) return; | 6170 if (proto->IsNull()) return; |
| 6147 ASSERT(proto->IsJSGlobalObject()); | 6171 ASSERT(proto->IsJSGlobalObject()); |
| 6148 DefineAccessor( | 6172 DefineAccessor(Handle<JSObject>::cast(proto), |
| 6149 Handle<JSObject>::cast(proto), name, getter, setter, attributes); | 6173 name, |
| 6174 getter, | |
| 6175 setter, | |
| 6176 attributes, | |
| 6177 access_control); | |
| 6150 return; | 6178 return; |
| 6151 } | 6179 } |
| 6152 | 6180 |
| 6153 // Make sure that the top context does not change when doing callbacks or | 6181 // Make sure that the top context does not change when doing callbacks or |
| 6154 // interceptor calls. | 6182 // interceptor calls. |
| 6155 AssertNoContextChange ncc; | 6183 AssertNoContextChange ncc; |
| 6156 | 6184 |
| 6157 // Try to flatten before operating on the string. | 6185 // Try to flatten before operating on the string. |
| 6158 if (name->IsString()) String::cast(*name)->TryFlatten(); | 6186 if (name->IsString()) String::cast(*name)->TryFlatten(); |
| 6159 | 6187 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 6175 LookupResult lookup(isolate); | 6203 LookupResult lookup(isolate); |
| 6176 object->LocalLookup(*name, &lookup, true); | 6204 object->LocalLookup(*name, &lookup, true); |
| 6177 preexists = lookup.IsProperty(); | 6205 preexists = lookup.IsProperty(); |
| 6178 if (preexists && lookup.IsDataProperty()) { | 6206 if (preexists && lookup.IsDataProperty()) { |
| 6179 old_value = Object::GetProperty(object, name); | 6207 old_value = Object::GetProperty(object, name); |
| 6180 } | 6208 } |
| 6181 } | 6209 } |
| 6182 } | 6210 } |
| 6183 | 6211 |
| 6184 if (is_element) { | 6212 if (is_element) { |
| 6213 ASSERT_EQ(v8::DEFAULT, access_control); | |
|
Sven Panne
2013/08/21 10:46:25
Perhaps we should document this restriction in v8.
dcarney
2013/08/21 10:59:33
it's not a restriction, i just want to get this wo
| |
| 6185 DefineElementAccessor(object, index, getter, setter, attributes); | 6214 DefineElementAccessor(object, index, getter, setter, attributes); |
| 6186 } else { | 6215 } else { |
| 6187 DefinePropertyAccessor(object, name, getter, setter, attributes); | 6216 DefinePropertyAccessor( |
| 6217 object, name, getter, setter, attributes, access_control); | |
| 6188 } | 6218 } |
| 6189 | 6219 |
| 6190 if (is_observed) { | 6220 if (is_observed) { |
| 6191 const char* type = preexists ? "reconfigured" : "new"; | 6221 const char* type = preexists ? "reconfigured" : "new"; |
| 6192 EnqueueChangeRecord(object, type, name, old_value); | 6222 EnqueueChangeRecord(object, type, name, old_value); |
| 6193 } | 6223 } |
| 6194 } | 6224 } |
| 6195 | 6225 |
| 6196 | 6226 |
| 6197 static bool TryAccessorTransition(JSObject* self, | 6227 static bool TryAccessorTransition(JSObject* self, |
| (...skipping 9779 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 15977 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16007 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 15978 static const char* error_messages_[] = { | 16008 static const char* error_messages_[] = { |
| 15979 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16009 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 15980 }; | 16010 }; |
| 15981 #undef ERROR_MESSAGES_TEXTS | 16011 #undef ERROR_MESSAGES_TEXTS |
| 15982 return error_messages_[reason]; | 16012 return error_messages_[reason]; |
| 15983 } | 16013 } |
| 15984 | 16014 |
| 15985 | 16015 |
| 15986 } } // namespace v8::internal | 16016 } } // namespace v8::internal |
| OLD | NEW |