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