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 2157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2168 const char* type_str, | 2168 const char* type_str, |
2169 Handle<Name> name, | 2169 Handle<Name> name, |
2170 Handle<Object> old_value) { | 2170 Handle<Object> old_value) { |
2171 Isolate* isolate = object->GetIsolate(); | 2171 Isolate* isolate = object->GetIsolate(); |
2172 HandleScope scope(isolate); | 2172 HandleScope scope(isolate); |
2173 Handle<String> type = isolate->factory()->InternalizeUtf8String(type_str); | 2173 Handle<String> type = isolate->factory()->InternalizeUtf8String(type_str); |
2174 if (object->IsJSGlobalObject()) { | 2174 if (object->IsJSGlobalObject()) { |
2175 object = handle(JSGlobalObject::cast(*object)->global_receiver(), isolate); | 2175 object = handle(JSGlobalObject::cast(*object)->global_receiver(), isolate); |
2176 } | 2176 } |
2177 Handle<Object> args[] = { type, object, name, old_value }; | 2177 Handle<Object> args[] = { type, object, name, old_value }; |
| 2178 int argc = name.is_null() ? 2 : old_value->IsTheHole() ? 3 : 4; |
2178 bool threw; | 2179 bool threw; |
| 2180 |
2179 Execution::Call(isolate, | 2181 Execution::Call(isolate, |
2180 Handle<JSFunction>(isolate->observers_notify_change()), | 2182 Handle<JSFunction>(isolate->observers_notify_change()), |
2181 isolate->factory()->undefined_value(), | 2183 isolate->factory()->undefined_value(), |
2182 old_value->IsTheHole() ? 3 : 4, args, | 2184 argc, args, |
2183 &threw); | 2185 &threw); |
2184 ASSERT(!threw); | 2186 ASSERT(!threw); |
2185 } | 2187 } |
2186 | 2188 |
2187 | 2189 |
2188 void JSObject::DeliverChangeRecords(Isolate* isolate) { | 2190 void JSObject::DeliverChangeRecords(Isolate* isolate) { |
2189 ASSERT(isolate->observer_delivery_pending()); | 2191 ASSERT(isolate->observer_delivery_pending()); |
2190 bool threw = false; | 2192 bool threw = false; |
2191 Execution::Call( | 2193 Execution::Call( |
2192 isolate, | 2194 isolate, |
(...skipping 3242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5435 } | 5437 } |
5436 } | 5438 } |
5437 | 5439 |
5438 // No references to object. | 5440 // No references to object. |
5439 return false; | 5441 return false; |
5440 } | 5442 } |
5441 | 5443 |
5442 | 5444 |
5443 Handle<Object> JSObject::PreventExtensions(Handle<JSObject> object) { | 5445 Handle<Object> JSObject::PreventExtensions(Handle<JSObject> object) { |
5444 Isolate* isolate = object->GetIsolate(); | 5446 Isolate* isolate = object->GetIsolate(); |
| 5447 |
| 5448 if (!object->map()->is_extensible()) return object; |
| 5449 |
5445 if (object->IsAccessCheckNeeded() && | 5450 if (object->IsAccessCheckNeeded() && |
5446 !isolate->MayNamedAccess(*object, | 5451 !isolate->MayNamedAccess(*object, |
5447 isolate->heap()->undefined_value(), | 5452 isolate->heap()->undefined_value(), |
5448 v8::ACCESS_KEYS)) { | 5453 v8::ACCESS_KEYS)) { |
5449 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_KEYS); | 5454 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_KEYS); |
5450 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); | 5455 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); |
5451 return isolate->factory()->false_value(); | 5456 return isolate->factory()->false_value(); |
5452 } | 5457 } |
5453 | 5458 |
5454 if (object->IsJSGlobalProxy()) { | 5459 if (object->IsJSGlobalProxy()) { |
(...skipping 22 matching lines...) Expand all Loading... |
5477 dictionary->set_requires_slow_elements(); | 5482 dictionary->set_requires_slow_elements(); |
5478 | 5483 |
5479 // Do a map transition, other objects with this map may still | 5484 // Do a map transition, other objects with this map may still |
5480 // be extensible. | 5485 // be extensible. |
5481 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps. | 5486 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps. |
5482 Handle<Map> new_map = Map::Copy(handle(object->map())); | 5487 Handle<Map> new_map = Map::Copy(handle(object->map())); |
5483 | 5488 |
5484 new_map->set_is_extensible(false); | 5489 new_map->set_is_extensible(false); |
5485 object->set_map(*new_map); | 5490 object->set_map(*new_map); |
5486 ASSERT(!object->map()->is_extensible()); | 5491 ASSERT(!object->map()->is_extensible()); |
| 5492 |
| 5493 if (FLAG_harmony_observation && object->map()->is_observed()) { |
| 5494 EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(), |
| 5495 isolate->factory()->the_hole_value()); |
| 5496 } |
5487 return object; | 5497 return object; |
5488 } | 5498 } |
5489 | 5499 |
5490 | 5500 |
5491 template<typename Dictionary> | 5501 template<typename Dictionary> |
5492 static void FreezeDictionary(Dictionary* dictionary) { | 5502 static void FreezeDictionary(Dictionary* dictionary) { |
5493 int capacity = dictionary->Capacity(); | 5503 int capacity = dictionary->Capacity(); |
5494 for (int i = 0; i < capacity; i++) { | 5504 for (int i = 0; i < capacity; i++) { |
5495 Object* k = dictionary->KeyAt(i); | 5505 Object* k = dictionary->KeyAt(i); |
5496 if (dictionary->IsKey(k)) { | 5506 if (dictionary->IsKey(k)) { |
5497 PropertyDetails details = dictionary->DetailsAt(i); | 5507 PropertyDetails details = dictionary->DetailsAt(i); |
5498 int attrs = DONT_DELETE; | 5508 int attrs = DONT_DELETE; |
5499 // READ_ONLY is an invalid attribute for JS setters/getters. | 5509 // READ_ONLY is an invalid attribute for JS setters/getters. |
5500 if (details.type() != CALLBACKS || | 5510 if (details.type() != CALLBACKS || |
5501 !dictionary->ValueAt(i)->IsAccessorPair()) { | 5511 !dictionary->ValueAt(i)->IsAccessorPair()) { |
5502 attrs |= READ_ONLY; | 5512 attrs |= READ_ONLY; |
5503 } | 5513 } |
5504 details = details.CopyAddAttributes( | 5514 details = details.CopyAddAttributes( |
5505 static_cast<PropertyAttributes>(attrs)); | 5515 static_cast<PropertyAttributes>(attrs)); |
5506 dictionary->DetailsAtPut(i, details); | 5516 dictionary->DetailsAtPut(i, details); |
5507 } | 5517 } |
5508 } | 5518 } |
5509 } | 5519 } |
5510 | 5520 |
5511 | 5521 |
5512 Handle<Object> JSObject::Freeze(Handle<JSObject> object) { | 5522 Handle<Object> JSObject::Freeze(Handle<JSObject> object) { |
5513 // Freezing non-strict arguments should be handled elsewhere. | 5523 // Freezing non-strict arguments should be handled elsewhere. |
5514 ASSERT(!object->HasNonStrictArgumentsElements()); | 5524 ASSERT(!object->HasNonStrictArgumentsElements()); |
| 5525 ASSERT(!object->map()->is_observed()); |
5515 | 5526 |
5516 if (object->map()->is_frozen()) return object; | 5527 if (object->map()->is_frozen()) return object; |
5517 | 5528 |
5518 Isolate* isolate = object->GetIsolate(); | 5529 Isolate* isolate = object->GetIsolate(); |
5519 if (object->IsAccessCheckNeeded() && | 5530 if (object->IsAccessCheckNeeded() && |
5520 !isolate->MayNamedAccess(*object, | 5531 !isolate->MayNamedAccess(*object, |
5521 isolate->heap()->undefined_value(), | 5532 isolate->heap()->undefined_value(), |
5522 v8::ACCESS_KEYS)) { | 5533 v8::ACCESS_KEYS)) { |
5523 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_KEYS); | 5534 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_KEYS); |
5524 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); | 5535 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); |
(...skipping 10908 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16433 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16444 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16434 static const char* error_messages_[] = { | 16445 static const char* error_messages_[] = { |
16435 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16446 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16436 }; | 16447 }; |
16437 #undef ERROR_MESSAGES_TEXTS | 16448 #undef ERROR_MESSAGES_TEXTS |
16438 return error_messages_[reason]; | 16449 return error_messages_[reason]; |
16439 } | 16450 } |
16440 | 16451 |
16441 | 16452 |
16442 } } // namespace v8::internal | 16453 } } // namespace v8::internal |
OLD | NEW |