| 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 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 544 break; | 544 break; |
| 545 } | 545 } |
| 546 default: | 546 default: |
| 547 UNREACHABLE(); | 547 UNREACHABLE(); |
| 548 } | 548 } |
| 549 } | 549 } |
| 550 | 550 |
| 551 // No accessible property found. | 551 // No accessible property found. |
| 552 *attributes = ABSENT; | 552 *attributes = ABSENT; |
| 553 Heap* heap = name->GetHeap(); | 553 Heap* heap = name->GetHeap(); |
| 554 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_GET); | 554 Isolate* isolate = heap->isolate(); |
| 555 isolate->ReportFailedAccessCheck(this, v8::ACCESS_GET); |
| 556 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 555 return heap->undefined_value(); | 557 return heap->undefined_value(); |
| 556 } | 558 } |
| 557 | 559 |
| 558 | 560 |
| 559 PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck( | 561 PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck( |
| 560 Object* receiver, | 562 Object* receiver, |
| 561 LookupResult* result, | 563 LookupResult* result, |
| 562 Name* name, | 564 Name* name, |
| 563 bool continue_search) { | 565 bool continue_search) { |
| 564 if (result->IsProperty()) { | 566 if (result->IsProperty()) { |
| (...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 918 // Inline the case for JSObjects. Doing so significantly improves the | 920 // Inline the case for JSObjects. Doing so significantly improves the |
| 919 // performance of fetching elements where checking the prototype chain is | 921 // performance of fetching elements where checking the prototype chain is |
| 920 // necessary. | 922 // necessary. |
| 921 JSObject* js_object = JSObject::cast(holder); | 923 JSObject* js_object = JSObject::cast(holder); |
| 922 | 924 |
| 923 // Check access rights if needed. | 925 // Check access rights if needed. |
| 924 if (js_object->IsAccessCheckNeeded()) { | 926 if (js_object->IsAccessCheckNeeded()) { |
| 925 Isolate* isolate = heap->isolate(); | 927 Isolate* isolate = heap->isolate(); |
| 926 if (!isolate->MayIndexedAccess(js_object, index, v8::ACCESS_GET)) { | 928 if (!isolate->MayIndexedAccess(js_object, index, v8::ACCESS_GET)) { |
| 927 isolate->ReportFailedAccessCheck(js_object, v8::ACCESS_GET); | 929 isolate->ReportFailedAccessCheck(js_object, v8::ACCESS_GET); |
| 930 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 928 return heap->undefined_value(); | 931 return heap->undefined_value(); |
| 929 } | 932 } |
| 930 } | 933 } |
| 931 | 934 |
| 932 if (js_object->HasIndexedInterceptor()) { | 935 if (js_object->HasIndexedInterceptor()) { |
| 933 return js_object->GetElementWithInterceptor(receiver, index); | 936 return js_object->GetElementWithInterceptor(receiver, index); |
| 934 } | 937 } |
| 935 | 938 |
| 936 if (js_object->elements() != heap->empty_fixed_array()) { | 939 if (js_object->elements() != heap->empty_fixed_array()) { |
| 937 MaybeObject* result = js_object->GetElementsAccessor()->Get( | 940 MaybeObject* result = js_object->GetElementsAccessor()->Get( |
| (...skipping 2298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3236 | 3239 |
| 3237 return AddMissingElementsTransitions(closest_map, kind); | 3240 return AddMissingElementsTransitions(closest_map, kind); |
| 3238 } | 3241 } |
| 3239 | 3242 |
| 3240 | 3243 |
| 3241 void JSObject::LocalLookupRealNamedProperty(Name* name, LookupResult* result) { | 3244 void JSObject::LocalLookupRealNamedProperty(Name* name, LookupResult* result) { |
| 3242 if (IsJSGlobalProxy()) { | 3245 if (IsJSGlobalProxy()) { |
| 3243 Object* proto = GetPrototype(); | 3246 Object* proto = GetPrototype(); |
| 3244 if (proto->IsNull()) return result->NotFound(); | 3247 if (proto->IsNull()) return result->NotFound(); |
| 3245 ASSERT(proto->IsJSGlobalObject()); | 3248 ASSERT(proto->IsJSGlobalObject()); |
| 3246 // A GlobalProxy's prototype should always be a proper JSObject. | |
| 3247 return JSObject::cast(proto)->LocalLookupRealNamedProperty(name, result); | 3249 return JSObject::cast(proto)->LocalLookupRealNamedProperty(name, result); |
| 3248 } | 3250 } |
| 3249 | 3251 |
| 3250 if (HasFastProperties()) { | 3252 if (HasFastProperties()) { |
| 3251 map()->LookupDescriptor(this, name, result); | 3253 map()->LookupDescriptor(this, name, result); |
| 3252 // A property or a map transition was found. We return all of these result | 3254 // A property or a map transition was found. We return all of these result |
| 3253 // types because LocalLookupRealNamedProperty is used when setting | 3255 // types because LocalLookupRealNamedProperty is used when setting |
| 3254 // properties where map transitions are handled. | 3256 // properties where map transitions are handled. |
| 3255 ASSERT(!result->IsFound() || | 3257 ASSERT(!result->IsFound() || |
| 3256 (result->holder() == this && result->IsFastPropertyType())); | 3258 (result->holder() == this && result->IsFastPropertyType())); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3358 break; | 3360 break; |
| 3359 } | 3361 } |
| 3360 } | 3362 } |
| 3361 } | 3363 } |
| 3362 } | 3364 } |
| 3363 | 3365 |
| 3364 Isolate* isolate = GetIsolate(); | 3366 Isolate* isolate = GetIsolate(); |
| 3365 HandleScope scope(isolate); | 3367 HandleScope scope(isolate); |
| 3366 Handle<Object> value_handle(value, isolate); | 3368 Handle<Object> value_handle(value, isolate); |
| 3367 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); | 3369 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); |
| 3370 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 3368 return *value_handle; | 3371 return *value_handle; |
| 3369 } | 3372 } |
| 3370 | 3373 |
| 3371 | 3374 |
| 3372 MaybeObject* JSReceiver::SetProperty(LookupResult* result, | 3375 MaybeObject* JSReceiver::SetProperty(LookupResult* result, |
| 3373 Name* key, | 3376 Name* key, |
| 3374 Object* value, | 3377 Object* value, |
| 3375 PropertyAttributes attributes, | 3378 PropertyAttributes attributes, |
| 3376 StrictModeFlag strict_mode, | 3379 StrictModeFlag strict_mode, |
| 3377 JSReceiver::StoreFromKeyed store_mode) { | 3380 JSReceiver::StoreFromKeyed store_mode) { |
| (...skipping 630 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4008 | 4011 |
| 4009 // From this point on everything needs to be handlified. | 4012 // From this point on everything needs to be handlified. |
| 4010 HandleScope scope(isolate); | 4013 HandleScope scope(isolate); |
| 4011 Handle<JSObject> self(this); | 4014 Handle<JSObject> self(this); |
| 4012 Handle<Name> name(name_raw); | 4015 Handle<Name> name(name_raw); |
| 4013 Handle<Object> value(value_raw, isolate); | 4016 Handle<Object> value(value_raw, isolate); |
| 4014 | 4017 |
| 4015 Handle<Object> old_value(isolate->heap()->the_hole_value(), isolate); | 4018 Handle<Object> old_value(isolate->heap()->the_hole_value(), isolate); |
| 4016 PropertyAttributes old_attributes = ABSENT; | 4019 PropertyAttributes old_attributes = ABSENT; |
| 4017 bool is_observed = FLAG_harmony_observation && self->map()->is_observed(); | 4020 bool is_observed = FLAG_harmony_observation && self->map()->is_observed(); |
| 4018 if (is_observed) { | 4021 if (is_observed && lookup.IsProperty()) { |
| 4019 if (lookup.IsDataProperty()) old_value = Object::GetProperty(self, name); | 4022 if (lookup.IsDataProperty()) old_value = Object::GetProperty(self, name); |
| 4020 old_attributes = lookup.GetAttributes(); | 4023 old_attributes = lookup.GetAttributes(); |
| 4021 } | 4024 } |
| 4022 | 4025 |
| 4023 // Check of IsReadOnly removed from here in clone. | 4026 // Check of IsReadOnly removed from here in clone. |
| 4024 MaybeObject* result = *value; | 4027 MaybeObject* result = *value; |
| 4025 switch (lookup.type()) { | 4028 switch (lookup.type()) { |
| 4026 case NORMAL: { | 4029 case NORMAL: { |
| 4027 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0); | 4030 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0); |
| 4028 result = self->SetNormalizedProperty(*name, *value, details); | 4031 result = self->SetNormalizedProperty(*name, *value, details); |
| (...skipping 1024 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5053 Object); | 5056 Object); |
| 5054 } | 5057 } |
| 5055 | 5058 |
| 5056 | 5059 |
| 5057 MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) { | 5060 MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) { |
| 5058 Isolate* isolate = GetIsolate(); | 5061 Isolate* isolate = GetIsolate(); |
| 5059 // Check access rights if needed. | 5062 // Check access rights if needed. |
| 5060 if (IsAccessCheckNeeded() && | 5063 if (IsAccessCheckNeeded() && |
| 5061 !isolate->MayIndexedAccess(this, index, v8::ACCESS_DELETE)) { | 5064 !isolate->MayIndexedAccess(this, index, v8::ACCESS_DELETE)) { |
| 5062 isolate->ReportFailedAccessCheck(this, v8::ACCESS_DELETE); | 5065 isolate->ReportFailedAccessCheck(this, v8::ACCESS_DELETE); |
| 5066 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 5063 return isolate->heap()->false_value(); | 5067 return isolate->heap()->false_value(); |
| 5064 } | 5068 } |
| 5065 | 5069 |
| 5066 if (IsStringObjectWithCharacterAt(index)) { | 5070 if (IsStringObjectWithCharacterAt(index)) { |
| 5067 if (mode == STRICT_DELETION) { | 5071 if (mode == STRICT_DELETION) { |
| 5068 // Deleting a non-configurable property in strict mode. | 5072 // Deleting a non-configurable property in strict mode. |
| 5069 HandleScope scope(isolate); | 5073 HandleScope scope(isolate); |
| 5070 Handle<Object> holder(this, isolate); | 5074 Handle<Object> holder(this, isolate); |
| 5071 Handle<Object> name = isolate->factory()->NewNumberFromUint(index); | 5075 Handle<Object> name = isolate->factory()->NewNumberFromUint(index); |
| 5072 Handle<Object> args[2] = { name, holder }; | 5076 Handle<Object> args[2] = { name, holder }; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5130 | 5134 |
| 5131 MaybeObject* JSObject::DeleteProperty(Name* name, DeleteMode mode) { | 5135 MaybeObject* JSObject::DeleteProperty(Name* name, DeleteMode mode) { |
| 5132 Isolate* isolate = GetIsolate(); | 5136 Isolate* isolate = GetIsolate(); |
| 5133 // ECMA-262, 3rd, 8.6.2.5 | 5137 // ECMA-262, 3rd, 8.6.2.5 |
| 5134 ASSERT(name->IsName()); | 5138 ASSERT(name->IsName()); |
| 5135 | 5139 |
| 5136 // Check access rights if needed. | 5140 // Check access rights if needed. |
| 5137 if (IsAccessCheckNeeded() && | 5141 if (IsAccessCheckNeeded() && |
| 5138 !isolate->MayNamedAccess(this, name, v8::ACCESS_DELETE)) { | 5142 !isolate->MayNamedAccess(this, name, v8::ACCESS_DELETE)) { |
| 5139 isolate->ReportFailedAccessCheck(this, v8::ACCESS_DELETE); | 5143 isolate->ReportFailedAccessCheck(this, v8::ACCESS_DELETE); |
| 5144 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 5140 return isolate->heap()->false_value(); | 5145 return isolate->heap()->false_value(); |
| 5141 } | 5146 } |
| 5142 | 5147 |
| 5143 if (IsJSGlobalProxy()) { | 5148 if (IsJSGlobalProxy()) { |
| 5144 Object* proto = GetPrototype(); | 5149 Object* proto = GetPrototype(); |
| 5145 if (proto->IsNull()) return isolate->heap()->false_value(); | 5150 if (proto->IsNull()) return isolate->heap()->false_value(); |
| 5146 ASSERT(proto->IsJSGlobalObject()); | 5151 ASSERT(proto->IsJSGlobalObject()); |
| 5147 return JSGlobalObject::cast(proto)->DeleteProperty(name, mode); | 5152 return JSGlobalObject::cast(proto)->DeleteProperty(name, mode); |
| 5148 } | 5153 } |
| 5149 | 5154 |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5360 } | 5365 } |
| 5361 | 5366 |
| 5362 | 5367 |
| 5363 MaybeObject* JSObject::PreventExtensions() { | 5368 MaybeObject* JSObject::PreventExtensions() { |
| 5364 Isolate* isolate = GetIsolate(); | 5369 Isolate* isolate = GetIsolate(); |
| 5365 if (IsAccessCheckNeeded() && | 5370 if (IsAccessCheckNeeded() && |
| 5366 !isolate->MayNamedAccess(this, | 5371 !isolate->MayNamedAccess(this, |
| 5367 isolate->heap()->undefined_value(), | 5372 isolate->heap()->undefined_value(), |
| 5368 v8::ACCESS_KEYS)) { | 5373 v8::ACCESS_KEYS)) { |
| 5369 isolate->ReportFailedAccessCheck(this, v8::ACCESS_KEYS); | 5374 isolate->ReportFailedAccessCheck(this, v8::ACCESS_KEYS); |
| 5375 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 5370 return isolate->heap()->false_value(); | 5376 return isolate->heap()->false_value(); |
| 5371 } | 5377 } |
| 5372 | 5378 |
| 5373 if (IsJSGlobalProxy()) { | 5379 if (IsJSGlobalProxy()) { |
| 5374 Object* proto = GetPrototype(); | 5380 Object* proto = GetPrototype(); |
| 5375 if (proto->IsNull()) return this; | 5381 if (proto->IsNull()) return this; |
| 5376 ASSERT(proto->IsJSGlobalObject()); | 5382 ASSERT(proto->IsJSGlobalObject()); |
| 5377 return JSObject::cast(proto)->PreventExtensions(); | 5383 return JSObject::cast(proto)->PreventExtensions(); |
| 5378 } | 5384 } |
| 5379 | 5385 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5438 | 5444 |
| 5439 Heap* heap = isolate->heap(); | 5445 Heap* heap = isolate->heap(); |
| 5440 | 5446 |
| 5441 if (map()->is_frozen()) return this; | 5447 if (map()->is_frozen()) return this; |
| 5442 | 5448 |
| 5443 if (IsAccessCheckNeeded() && | 5449 if (IsAccessCheckNeeded() && |
| 5444 !isolate->MayNamedAccess(this, | 5450 !isolate->MayNamedAccess(this, |
| 5445 heap->undefined_value(), | 5451 heap->undefined_value(), |
| 5446 v8::ACCESS_KEYS)) { | 5452 v8::ACCESS_KEYS)) { |
| 5447 isolate->ReportFailedAccessCheck(this, v8::ACCESS_KEYS); | 5453 isolate->ReportFailedAccessCheck(this, v8::ACCESS_KEYS); |
| 5454 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 5448 return heap->false_value(); | 5455 return heap->false_value(); |
| 5449 } | 5456 } |
| 5450 | 5457 |
| 5451 if (IsJSGlobalProxy()) { | 5458 if (IsJSGlobalProxy()) { |
| 5452 Object* proto = GetPrototype(); | 5459 Object* proto = GetPrototype(); |
| 5453 if (proto->IsNull()) return this; | 5460 if (proto->IsNull()) return this; |
| 5454 ASSERT(proto->IsJSGlobalObject()); | 5461 ASSERT(proto->IsJSGlobalObject()); |
| 5455 return JSObject::cast(proto)->Freeze(isolate); | 5462 return JSObject::cast(proto)->Freeze(isolate); |
| 5456 } | 5463 } |
| 5457 | 5464 |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5543 // Make sure we never go back to the fast case | 5550 // Make sure we never go back to the fast case |
| 5544 dictionary->set_requires_slow_elements(); | 5551 dictionary->set_requires_slow_elements(); |
| 5545 // Freeze all elements in the dictionary | 5552 // Freeze all elements in the dictionary |
| 5546 FreezeDictionary(dictionary); | 5553 FreezeDictionary(dictionary); |
| 5547 } | 5554 } |
| 5548 | 5555 |
| 5549 return this; | 5556 return this; |
| 5550 } | 5557 } |
| 5551 | 5558 |
| 5552 | 5559 |
| 5560 MUST_USE_RESULT MaybeObject* JSObject::SetObserved(Isolate* isolate) { |
| 5561 if (map()->is_observed()) |
| 5562 return isolate->heap()->undefined_value(); |
| 5563 |
| 5564 Heap* heap = isolate->heap(); |
| 5565 |
| 5566 if (!HasExternalArrayElements()) { |
| 5567 // Go to dictionary mode, so that we don't skip map checks. |
| 5568 MaybeObject* maybe = NormalizeElements(); |
| 5569 if (maybe->IsFailure()) return maybe; |
| 5570 ASSERT(!HasFastElements()); |
| 5571 } |
| 5572 |
| 5573 LookupResult result(isolate); |
| 5574 map()->LookupTransition(this, heap->observed_symbol(), &result); |
| 5575 |
| 5576 Map* new_map; |
| 5577 if (result.IsTransition()) { |
| 5578 new_map = result.GetTransitionTarget(); |
| 5579 ASSERT(new_map->is_observed()); |
| 5580 } else if (map()->CanHaveMoreTransitions()) { |
| 5581 MaybeObject* maybe_new_map = map()->CopyForObserved(); |
| 5582 if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
| 5583 } else { |
| 5584 MaybeObject* maybe_copy = map()->Copy(); |
| 5585 if (!maybe_copy->To(&new_map)) return maybe_copy; |
| 5586 new_map->set_is_observed(true); |
| 5587 } |
| 5588 set_map(new_map); |
| 5589 |
| 5590 return heap->undefined_value(); |
| 5591 } |
| 5592 |
| 5593 |
| 5553 MUST_USE_RESULT MaybeObject* JSObject::DeepCopy(Isolate* isolate) { | 5594 MUST_USE_RESULT MaybeObject* JSObject::DeepCopy(Isolate* isolate) { |
| 5554 StackLimitCheck check(isolate); | 5595 StackLimitCheck check(isolate); |
| 5555 if (check.HasOverflowed()) return isolate->StackOverflow(); | 5596 if (check.HasOverflowed()) return isolate->StackOverflow(); |
| 5556 | 5597 |
| 5557 if (map()->is_deprecated()) { | 5598 if (map()->is_deprecated()) { |
| 5558 MaybeObject* maybe_failure = MigrateInstance(); | 5599 MaybeObject* maybe_failure = MigrateInstance(); |
| 5559 if (maybe_failure->IsFailure()) return maybe_failure; | 5600 if (maybe_failure->IsFailure()) return maybe_failure; |
| 5560 } | 5601 } |
| 5561 | 5602 |
| 5562 Heap* heap = isolate->heap(); | 5603 Heap* heap = isolate->heap(); |
| (...skipping 688 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6251 } | 6292 } |
| 6252 | 6293 |
| 6253 | 6294 |
| 6254 MaybeObject* JSObject::DefineAccessor(AccessorInfo* info) { | 6295 MaybeObject* JSObject::DefineAccessor(AccessorInfo* info) { |
| 6255 Isolate* isolate = GetIsolate(); | 6296 Isolate* isolate = GetIsolate(); |
| 6256 Name* name = Name::cast(info->name()); | 6297 Name* name = Name::cast(info->name()); |
| 6257 // Check access rights if needed. | 6298 // Check access rights if needed. |
| 6258 if (IsAccessCheckNeeded() && | 6299 if (IsAccessCheckNeeded() && |
| 6259 !isolate->MayNamedAccess(this, name, v8::ACCESS_SET)) { | 6300 !isolate->MayNamedAccess(this, name, v8::ACCESS_SET)) { |
| 6260 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); | 6301 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); |
| 6302 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 6261 return isolate->heap()->undefined_value(); | 6303 return isolate->heap()->undefined_value(); |
| 6262 } | 6304 } |
| 6263 | 6305 |
| 6264 if (IsJSGlobalProxy()) { | 6306 if (IsJSGlobalProxy()) { |
| 6265 Object* proto = GetPrototype(); | 6307 Object* proto = GetPrototype(); |
| 6266 if (proto->IsNull()) return this; | 6308 if (proto->IsNull()) return this; |
| 6267 ASSERT(proto->IsJSGlobalObject()); | 6309 ASSERT(proto->IsJSGlobalObject()); |
| 6268 return JSObject::cast(proto)->DefineAccessor(info); | 6310 return JSObject::cast(proto)->DefineAccessor(info); |
| 6269 } | 6311 } |
| 6270 | 6312 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6326 | 6368 |
| 6327 MaybeObject* maybe_ok = | 6369 MaybeObject* maybe_ok = |
| 6328 SetPropertyCallback(name, info, info->property_attributes()); | 6370 SetPropertyCallback(name, info, info->property_attributes()); |
| 6329 if (maybe_ok->IsFailure()) return maybe_ok; | 6371 if (maybe_ok->IsFailure()) return maybe_ok; |
| 6330 } | 6372 } |
| 6331 | 6373 |
| 6332 return this; | 6374 return this; |
| 6333 } | 6375 } |
| 6334 | 6376 |
| 6335 | 6377 |
| 6336 Object* JSObject::LookupAccessor(Name* name, AccessorComponent component) { | 6378 MaybeObject* JSObject::LookupAccessor(Name* name, AccessorComponent component) { |
| 6337 Heap* heap = GetHeap(); | 6379 Heap* heap = GetHeap(); |
| 6338 | 6380 |
| 6339 // Make sure that the top context does not change when doing callbacks or | 6381 // Make sure that the top context does not change when doing callbacks or |
| 6340 // interceptor calls. | 6382 // interceptor calls. |
| 6341 AssertNoContextChange ncc; | 6383 AssertNoContextChange ncc; |
| 6342 | 6384 |
| 6343 // Check access rights if needed. | 6385 // Check access rights if needed. |
| 6344 if (IsAccessCheckNeeded() && | 6386 if (IsAccessCheckNeeded() && |
| 6345 !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_HAS)) { | 6387 !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_HAS)) { |
| 6346 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 6388 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 6389 RETURN_IF_SCHEDULED_EXCEPTION(heap->isolate()); |
| 6347 return heap->undefined_value(); | 6390 return heap->undefined_value(); |
| 6348 } | 6391 } |
| 6349 | 6392 |
| 6350 // Make the lookup and include prototypes. | 6393 // Make the lookup and include prototypes. |
| 6351 uint32_t index = 0; | 6394 uint32_t index = 0; |
| 6352 if (name->AsArrayIndex(&index)) { | 6395 if (name->AsArrayIndex(&index)) { |
| 6353 for (Object* obj = this; | 6396 for (Object* obj = this; |
| 6354 obj != heap->null_value(); | 6397 obj != heap->null_value(); |
| 6355 obj = JSReceiver::cast(obj)->GetPrototype()) { | 6398 obj = JSReceiver::cast(obj)->GetPrototype()) { |
| 6356 if (obj->IsJSObject() && JSObject::cast(obj)->HasDictionaryElements()) { | 6399 if (obj->IsJSObject() && JSObject::cast(obj)->HasDictionaryElements()) { |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6664 if (insert_transition) { | 6707 if (insert_transition) { |
| 6665 MaybeObject* added_elements = set_elements_transition_map(new_map); | 6708 MaybeObject* added_elements = set_elements_transition_map(new_map); |
| 6666 if (added_elements->IsFailure()) return added_elements; | 6709 if (added_elements->IsFailure()) return added_elements; |
| 6667 new_map->SetBackPointer(this); | 6710 new_map->SetBackPointer(this); |
| 6668 } | 6711 } |
| 6669 | 6712 |
| 6670 return new_map; | 6713 return new_map; |
| 6671 } | 6714 } |
| 6672 | 6715 |
| 6673 | 6716 |
| 6717 MaybeObject* Map::CopyForObserved() { |
| 6718 ASSERT(!is_observed()); |
| 6719 |
| 6720 // In case the map owned its own descriptors, share the descriptors and |
| 6721 // transfer ownership to the new map. |
| 6722 Map* new_map; |
| 6723 MaybeObject* maybe_new_map; |
| 6724 if (owns_descriptors()) { |
| 6725 maybe_new_map = CopyDropDescriptors(); |
| 6726 } else { |
| 6727 maybe_new_map = Copy(); |
| 6728 } |
| 6729 if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
| 6730 |
| 6731 TransitionArray* transitions; |
| 6732 MaybeObject* maybe_transitions = AddTransition(GetHeap()->observed_symbol(), |
| 6733 new_map, |
| 6734 FULL_TRANSITION); |
| 6735 if (!maybe_transitions->To(&transitions)) return maybe_transitions; |
| 6736 set_transitions(transitions); |
| 6737 |
| 6738 new_map->set_is_observed(true); |
| 6739 |
| 6740 if (owns_descriptors()) { |
| 6741 new_map->InitializeDescriptors(instance_descriptors()); |
| 6742 set_owns_descriptors(false); |
| 6743 } |
| 6744 |
| 6745 new_map->SetBackPointer(this); |
| 6746 return new_map; |
| 6747 } |
| 6748 |
| 6749 |
| 6674 MaybeObject* Map::CopyWithPreallocatedFieldDescriptors() { | 6750 MaybeObject* Map::CopyWithPreallocatedFieldDescriptors() { |
| 6675 if (pre_allocated_property_fields() == 0) return CopyDropDescriptors(); | 6751 if (pre_allocated_property_fields() == 0) return CopyDropDescriptors(); |
| 6676 | 6752 |
| 6677 // If the map has pre-allocated properties always start out with a descriptor | 6753 // If the map has pre-allocated properties always start out with a descriptor |
| 6678 // array describing these properties. | 6754 // array describing these properties. |
| 6679 ASSERT(constructor()->IsJSFunction()); | 6755 ASSERT(constructor()->IsJSFunction()); |
| 6680 JSFunction* ctor = JSFunction::cast(constructor()); | 6756 JSFunction* ctor = JSFunction::cast(constructor()); |
| 6681 Map* map = ctor->initial_map(); | 6757 Map* map = ctor->initial_map(); |
| 6682 DescriptorArray* descriptors = map->instance_descriptors(); | 6758 DescriptorArray* descriptors = map->instance_descriptors(); |
| 6683 | 6759 |
| (...skipping 3285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9969 VisitPointer(rinfo->target_object_address()); | 10045 VisitPointer(rinfo->target_object_address()); |
| 9970 } | 10046 } |
| 9971 | 10047 |
| 9972 | 10048 |
| 9973 void ObjectVisitor::VisitExternalReference(RelocInfo* rinfo) { | 10049 void ObjectVisitor::VisitExternalReference(RelocInfo* rinfo) { |
| 9974 Address* p = rinfo->target_reference_address(); | 10050 Address* p = rinfo->target_reference_address(); |
| 9975 VisitExternalReferences(p, p + 1); | 10051 VisitExternalReferences(p, p + 1); |
| 9976 } | 10052 } |
| 9977 | 10053 |
| 9978 | 10054 |
| 9979 byte Code::compare_nil_state() { | |
| 9980 ASSERT(is_compare_nil_ic_stub()); | |
| 9981 return CompareNilICStub::ExtractTypesFromExtraICState( | |
| 9982 extended_extra_ic_state()); | |
| 9983 } | |
| 9984 | |
| 9985 | |
| 9986 byte Code::compare_nil_value() { | |
| 9987 ASSERT(is_compare_nil_ic_stub()); | |
| 9988 return CompareNilICStub::ExtractNilValueFromExtraICState( | |
| 9989 extended_extra_ic_state()); | |
| 9990 } | |
| 9991 | |
| 9992 | |
| 9993 void Code::InvalidateRelocation() { | 10055 void Code::InvalidateRelocation() { |
| 9994 set_relocation_info(GetHeap()->empty_byte_array()); | 10056 set_relocation_info(GetHeap()->empty_byte_array()); |
| 9995 } | 10057 } |
| 9996 | 10058 |
| 9997 | 10059 |
| 9998 void Code::Relocate(intptr_t delta) { | 10060 void Code::Relocate(intptr_t delta) { |
| 9999 for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) { | 10061 for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) { |
| 10000 it.rinfo()->apply(delta); | 10062 it.rinfo()->apply(delta); |
| 10001 } | 10063 } |
| 10002 CPU::FlushICache(instruction_start(), instruction_size()); | 10064 CPU::FlushICache(instruction_start(), instruction_size()); |
| (...skipping 2070 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12073 PropertyAttributes attributes, | 12135 PropertyAttributes attributes, |
| 12074 StrictModeFlag strict_mode, | 12136 StrictModeFlag strict_mode, |
| 12075 bool check_prototype, | 12137 bool check_prototype, |
| 12076 SetPropertyMode set_mode) { | 12138 SetPropertyMode set_mode) { |
| 12077 Isolate* isolate = GetIsolate(); | 12139 Isolate* isolate = GetIsolate(); |
| 12078 | 12140 |
| 12079 // Check access rights if needed. | 12141 // Check access rights if needed. |
| 12080 if (IsAccessCheckNeeded()) { | 12142 if (IsAccessCheckNeeded()) { |
| 12081 if (!isolate->MayIndexedAccess(this, index, v8::ACCESS_SET)) { | 12143 if (!isolate->MayIndexedAccess(this, index, v8::ACCESS_SET)) { |
| 12082 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); | 12144 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); |
| 12145 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 12083 return value_raw; | 12146 return value_raw; |
| 12084 } | 12147 } |
| 12085 } | 12148 } |
| 12086 | 12149 |
| 12087 if (IsJSGlobalProxy()) { | 12150 if (IsJSGlobalProxy()) { |
| 12088 Object* proto = GetPrototype(); | 12151 Object* proto = GetPrototype(); |
| 12089 if (proto->IsNull()) return value_raw; | 12152 if (proto->IsNull()) return value_raw; |
| 12090 ASSERT(proto->IsJSGlobalObject()); | 12153 ASSERT(proto->IsJSGlobalObject()); |
| 12091 return JSObject::cast(proto)->SetElement(index, | 12154 return JSObject::cast(proto)->SetElement(index, |
| 12092 value_raw, | 12155 value_raw, |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12311 AllocationSiteInfo* info = AllocationSiteInfo::FindForJSObject(this); | 12374 AllocationSiteInfo* info = AllocationSiteInfo::FindForJSObject(this); |
| 12312 if (info == NULL || !info->IsValid()) { | 12375 if (info == NULL || !info->IsValid()) { |
| 12313 return this; | 12376 return this; |
| 12314 } | 12377 } |
| 12315 | 12378 |
| 12316 // Walk through to the Allocation Site | 12379 // Walk through to the Allocation Site |
| 12317 AllocationSite* site = info->GetAllocationSite(); | 12380 AllocationSite* site = info->GetAllocationSite(); |
| 12318 if (site->IsLiteralSite()) { | 12381 if (site->IsLiteralSite()) { |
| 12319 JSArray* transition_info = JSArray::cast(site->transition_info()); | 12382 JSArray* transition_info = JSArray::cast(site->transition_info()); |
| 12320 ElementsKind kind = transition_info->GetElementsKind(); | 12383 ElementsKind kind = transition_info->GetElementsKind(); |
| 12384 // if kind is holey ensure that to_kind is as well. |
| 12385 if (IsHoleyElementsKind(kind)) { |
| 12386 to_kind = GetHoleyElementsKind(to_kind); |
| 12387 } |
| 12321 if (AllocationSite::GetMode(kind, to_kind) == TRACK_ALLOCATION_SITE) { | 12388 if (AllocationSite::GetMode(kind, to_kind) == TRACK_ALLOCATION_SITE) { |
| 12322 // If the array is huge, it's not likely to be defined in a local | 12389 // If the array is huge, it's not likely to be defined in a local |
| 12323 // function, so we shouldn't make new instances of it very often. | 12390 // function, so we shouldn't make new instances of it very often. |
| 12324 uint32_t length = 0; | 12391 uint32_t length = 0; |
| 12325 CHECK(transition_info->length()->ToArrayIndex(&length)); | 12392 CHECK(transition_info->length()->ToArrayIndex(&length)); |
| 12326 if (length <= AllocationSite::kMaximumArrayBytesToPretransition) { | 12393 if (length <= AllocationSite::kMaximumArrayBytesToPretransition) { |
| 12327 if (FLAG_trace_track_allocation_sites) { | 12394 if (FLAG_trace_track_allocation_sites) { |
| 12328 PrintF( | 12395 PrintF( |
| 12329 "AllocationSite: JSArray %p boilerplate updated %s->%s\n", | 12396 "AllocationSite: JSArray %p boilerplate updated %s->%s\n", |
| 12330 reinterpret_cast<void*>(this), | 12397 reinterpret_cast<void*>(this), |
| 12331 ElementsKindToString(kind), | 12398 ElementsKindToString(kind), |
| 12332 ElementsKindToString(to_kind)); | 12399 ElementsKindToString(to_kind)); |
| 12333 } | 12400 } |
| 12334 return transition_info->TransitionElementsKind(to_kind); | 12401 return transition_info->TransitionElementsKind(to_kind); |
| 12335 } | 12402 } |
| 12336 } | 12403 } |
| 12337 } else { | 12404 } else { |
| 12338 ElementsKind kind = site->GetElementsKind(); | 12405 ElementsKind kind = site->GetElementsKind(); |
| 12406 // if kind is holey ensure that to_kind is as well. |
| 12407 if (IsHoleyElementsKind(kind)) { |
| 12408 to_kind = GetHoleyElementsKind(to_kind); |
| 12409 } |
| 12339 if (AllocationSite::GetMode(kind, to_kind) == TRACK_ALLOCATION_SITE) { | 12410 if (AllocationSite::GetMode(kind, to_kind) == TRACK_ALLOCATION_SITE) { |
| 12340 if (FLAG_trace_track_allocation_sites) { | 12411 if (FLAG_trace_track_allocation_sites) { |
| 12341 PrintF("AllocationSite: JSArray %p site updated %s->%s\n", | 12412 PrintF("AllocationSite: JSArray %p site updated %s->%s\n", |
| 12342 reinterpret_cast<void*>(this), | 12413 reinterpret_cast<void*>(this), |
| 12343 ElementsKindToString(kind), | 12414 ElementsKindToString(kind), |
| 12344 ElementsKindToString(to_kind)); | 12415 ElementsKindToString(to_kind)); |
| 12345 } | 12416 } |
| 12346 site->set_transition_info(Smi::FromInt(to_kind)); | 12417 site->set_transition_info(Smi::FromInt(to_kind)); |
| 12347 } | 12418 } |
| 12348 } | 12419 } |
| (...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12814 | 12885 |
| 12815 bool JSObject::HasRealElementProperty(Isolate* isolate, uint32_t index) { | 12886 bool JSObject::HasRealElementProperty(Isolate* isolate, uint32_t index) { |
| 12816 // Check access rights if needed. | 12887 // Check access rights if needed. |
| 12817 if (IsAccessCheckNeeded()) { | 12888 if (IsAccessCheckNeeded()) { |
| 12818 if (!isolate->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { | 12889 if (!isolate->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { |
| 12819 isolate->ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 12890 isolate->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 12820 return false; | 12891 return false; |
| 12821 } | 12892 } |
| 12822 } | 12893 } |
| 12823 | 12894 |
| 12895 if (IsJSGlobalProxy()) { |
| 12896 Object* proto = GetPrototype(); |
| 12897 if (proto->IsNull()) return false; |
| 12898 ASSERT(proto->IsJSGlobalObject()); |
| 12899 return JSObject::cast(proto)->HasRealElementProperty(isolate, index); |
| 12900 } |
| 12901 |
| 12824 return GetElementAttributeWithoutInterceptor(this, index, false) != ABSENT; | 12902 return GetElementAttributeWithoutInterceptor(this, index, false) != ABSENT; |
| 12825 } | 12903 } |
| 12826 | 12904 |
| 12827 | 12905 |
| 12828 bool JSObject::HasRealNamedCallbackProperty(Isolate* isolate, Name* key) { | 12906 bool JSObject::HasRealNamedCallbackProperty(Isolate* isolate, Name* key) { |
| 12829 // Check access rights if needed. | 12907 // Check access rights if needed. |
| 12830 if (IsAccessCheckNeeded()) { | 12908 if (IsAccessCheckNeeded()) { |
| 12831 if (!isolate->MayNamedAccess(this, key, v8::ACCESS_HAS)) { | 12909 if (!isolate->MayNamedAccess(this, key, v8::ACCESS_HAS)) { |
| 12832 isolate->ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 12910 isolate->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 12833 return false; | 12911 return false; |
| (...skipping 3036 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15870 | 15948 |
| 15871 void PropertyCell::AddDependentCode(Handle<Code> code) { | 15949 void PropertyCell::AddDependentCode(Handle<Code> code) { |
| 15872 Handle<DependentCode> codes = DependentCode::Insert( | 15950 Handle<DependentCode> codes = DependentCode::Insert( |
| 15873 Handle<DependentCode>(dependent_code()), | 15951 Handle<DependentCode>(dependent_code()), |
| 15874 DependentCode::kPropertyCellChangedGroup, code); | 15952 DependentCode::kPropertyCellChangedGroup, code); |
| 15875 if (*codes != dependent_code()) set_dependent_code(*codes); | 15953 if (*codes != dependent_code()) set_dependent_code(*codes); |
| 15876 } | 15954 } |
| 15877 | 15955 |
| 15878 | 15956 |
| 15879 } } // namespace v8::internal | 15957 } } // namespace v8::internal |
| OLD | NEW |