Chromium Code Reviews| OLD | NEW | 
|---|---|
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "src/objects.h" | 5 #include "src/objects.h" | 
| 6 | 6 | 
| 7 #include <cmath> | 7 #include <cmath> | 
| 8 #include <iomanip> | 8 #include <iomanip> | 
| 9 #include <memory> | 9 #include <memory> | 
| 10 #include <sstream> | 10 #include <sstream> | 
| (...skipping 7404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7415 } | 7415 } | 
| 7416 | 7416 | 
| 7417 | 7417 | 
| 7418 Maybe<bool> JSReceiver::SetIntegrityLevel(Handle<JSReceiver> receiver, | 7418 Maybe<bool> JSReceiver::SetIntegrityLevel(Handle<JSReceiver> receiver, | 
| 7419 IntegrityLevel level, | 7419 IntegrityLevel level, | 
| 7420 ShouldThrow should_throw) { | 7420 ShouldThrow should_throw) { | 
| 7421 DCHECK(level == SEALED || level == FROZEN); | 7421 DCHECK(level == SEALED || level == FROZEN); | 
| 7422 | 7422 | 
| 7423 if (receiver->IsJSObject()) { | 7423 if (receiver->IsJSObject()) { | 
| 7424 Handle<JSObject> object = Handle<JSObject>::cast(receiver); | 7424 Handle<JSObject> object = Handle<JSObject>::cast(receiver); | 
| 7425 | |
| 7426 // prevent memory leaks by adding unnecessary transitions | |
| 
 
Toon Verwaest
2017/06/13 09:57:05
Prevent ... *not* adding ... transitions. :)
 
kris.selden
2017/06/16 22:32:12
Done.
 
 | |
| 7427 Maybe<bool> test = JSObject::TestIntegrityLevel(object, level); | |
| 7428 MAYBE_RETURN(test, Nothing<bool>()); | |
| 7429 if (test.FromJust()) return Just(true); | |
| 7430 | |
| 7425 if (!object->HasSloppyArgumentsElements()) { // Fast path. | 7431 if (!object->HasSloppyArgumentsElements()) { // Fast path. | 
| 7426 if (level == SEALED) { | 7432 if (level == SEALED) { | 
| 7427 return JSObject::PreventExtensionsWithTransition<SEALED>(object, | 7433 return JSObject::PreventExtensionsWithTransition<SEALED>(object, | 
| 7428 should_throw); | 7434 should_throw); | 
| 7429 } else { | 7435 } else { | 
| 7430 return JSObject::PreventExtensionsWithTransition<FROZEN>(object, | 7436 return JSObject::PreventExtensionsWithTransition<FROZEN>(object, | 
| 7431 should_throw); | 7437 should_throw); | 
| 7432 } | 7438 } | 
| 7433 } | 7439 } | 
| 7434 } | 7440 } | 
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7471 ? no_conf | 7477 ? no_conf | 
| 7472 : no_conf_no_write; | 7478 : no_conf_no_write; | 
| 7473 MAYBE_RETURN( | 7479 MAYBE_RETURN( | 
| 7474 DefineOwnProperty(isolate, receiver, key, &desc, THROW_ON_ERROR), | 7480 DefineOwnProperty(isolate, receiver, key, &desc, THROW_ON_ERROR), | 
| 7475 Nothing<bool>()); | 7481 Nothing<bool>()); | 
| 7476 } | 7482 } | 
| 7477 } | 7483 } | 
| 7478 return Just(true); | 7484 return Just(true); | 
| 7479 } | 7485 } | 
| 7480 | 7486 | 
| 7481 | |
| 7482 Maybe<bool> JSReceiver::TestIntegrityLevel(Handle<JSReceiver> object, | 7487 Maybe<bool> JSReceiver::TestIntegrityLevel(Handle<JSReceiver> object, | 
| 7483 IntegrityLevel level) { | 7488 IntegrityLevel level) { | 
| 7489 if (object->IsJSObject()) { | |
| 7490 return JSObject::TestIntegrityLevel(Handle<JSObject>::cast(object), level); | |
| 7491 } | |
| 7492 | |
| 7484 DCHECK(level == SEALED || level == FROZEN); | 7493 DCHECK(level == SEALED || level == FROZEN); | 
| 7485 Isolate* isolate = object->GetIsolate(); | 7494 Isolate* isolate = object->GetIsolate(); | 
| 7486 | 7495 | 
| 7487 Maybe<bool> extensible = JSReceiver::IsExtensible(object); | 7496 Maybe<bool> extensible = JSReceiver::IsExtensible(object); | 
| 7488 MAYBE_RETURN(extensible, Nothing<bool>()); | 7497 MAYBE_RETURN(extensible, Nothing<bool>()); | 
| 7489 if (extensible.FromJust()) return Just(false); | 7498 if (extensible.FromJust()) return Just(false); | 
| 7490 | 7499 | 
| 7491 Handle<FixedArray> keys; | 7500 Handle<FixedArray> keys; | 
| 7492 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 7501 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 
| 7493 isolate, keys, JSReceiver::OwnPropertyKeys(object), Nothing<bool>()); | 7502 isolate, keys, JSReceiver::OwnPropertyKeys(object), Nothing<bool>()); | 
| 7494 | 7503 | 
| 7495 for (int i = 0; i < keys->length(); ++i) { | 7504 for (int i = 0; i < keys->length(); ++i) { | 
| 7496 Handle<Object> key(keys->get(i), isolate); | 7505 Handle<Object> key(keys->get(i), isolate); | 
| 7497 PropertyDescriptor current_desc; | 7506 PropertyDescriptor current_desc; | 
| 7498 Maybe<bool> owned = JSReceiver::GetOwnPropertyDescriptor( | 7507 Maybe<bool> owned = JSReceiver::GetOwnPropertyDescriptor( | 
| 7499 isolate, object, key, ¤t_desc); | 7508 isolate, object, key, ¤t_desc); | 
| 7500 MAYBE_RETURN(owned, Nothing<bool>()); | 7509 MAYBE_RETURN(owned, Nothing<bool>()); | 
| 7501 if (owned.FromJust()) { | 7510 if (owned.FromJust()) { | 
| 7502 if (current_desc.configurable()) return Just(false); | 7511 if (current_desc.configurable()) return Just(false); | 
| 7503 if (level == FROZEN && | 7512 if (level == FROZEN && | 
| 7504 PropertyDescriptor::IsDataDescriptor(¤t_desc) && | 7513 PropertyDescriptor::IsDataDescriptor(¤t_desc) && | 
| 7505 current_desc.writable()) { | 7514 current_desc.writable()) { | 
| 7506 return Just(false); | 7515 return Just(false); | 
| 7507 } | 7516 } | 
| 7508 } | 7517 } | 
| 7509 } | 7518 } | 
| 7510 return Just(true); | 7519 return Just(true); | 
| 7511 } | 7520 } | 
| 7512 | 7521 | 
| 7522 Maybe<bool> JSObject::TestIntegrityLevel(Handle<JSObject> object, | |
| 7523 IntegrityLevel level) { | |
| 7524 DCHECK(level == SEALED || level == FROZEN); | |
| 7525 | |
| 7526 if (JSObject::IsExtensible(object)) return Just(false); | |
| 7527 | |
| 7528 if (object->HasFastProperties() && | |
| 7529 IsFastObjectElementsKind(object->GetElementsKind())) { | |
| 7530 ElementsAccessor* accessor = object->GetElementsAccessor(); | |
| 
 
Toon Verwaest
2017/06/13 09:57:06
If we only support fast elements, finding any elem
 
Toon Verwaest
2017/06/16 10:03:02
Come to think of it; if we ever followed the fast
 
kris.selden
2017/06/16 22:32:12
I think what I did addresses this but I need your
 
 | |
| 7531 JSObject* rawobj = *object; | |
| 7532 uint32_t number_of_elements = accessor->NumberOfElements(rawobj); | |
| 7533 for (uint32_t i = 0; i < number_of_elements; i++) { | |
| 7534 PropertyDetails details = accessor->GetDetails(rawobj, i); | |
| 7535 if (details.IsConfigurable()) return Just(false); | |
| 7536 if (level == FROZEN && details.kind() == kData && !details.IsReadOnly()) { | |
| 7537 return Just(false); | |
| 7538 } | |
| 7539 } | |
| 7540 Map* map = object->map(); | |
| 7541 DescriptorArray* descriptors = map->instance_descriptors(); | |
| 7542 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); | |
| 7543 for (int i = 0; i < number_of_own_descriptors; i++) { | |
| 7544 PropertyDetails details = descriptors->GetDetails(i); | |
| 7545 if (details.IsConfigurable()) return Just(false); | |
| 7546 if (level == FROZEN && details.kind() == kData && !details.IsReadOnly()) { | |
| 7547 return Just(false); | |
| 7548 } | |
| 7549 } | |
| 7550 return Just(true); | |
| 7551 } | |
| 7552 | |
| 7553 Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object); | |
| 
 
Toon Verwaest
2017/06/13 09:57:05
We definitely want to share this slow path with th
 
kris.selden
2017/06/16 22:32:12
Done.
 
 | |
| 7554 Isolate* isolate = object->GetIsolate(); | |
| 7555 Handle<FixedArray> keys; | |
| 7556 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | |
| 7557 isolate, keys, JSObject::OwnPropertyKeys(receiver), Nothing<bool>()); | |
| 7558 | |
| 7559 for (int i = 0; i < keys->length(); ++i) { | |
| 7560 Handle<Object> key(keys->get(i), isolate); | |
| 7561 PropertyDescriptor current_desc; | |
| 7562 Maybe<bool> owned = JSReceiver::GetOwnPropertyDescriptor( | |
| 7563 isolate, receiver, key, ¤t_desc); | |
| 7564 MAYBE_RETURN(owned, Nothing<bool>()); | |
| 7565 if (owned.FromJust()) { | |
| 7566 if (current_desc.configurable()) return Just(false); | |
| 7567 if (level == FROZEN && | |
| 7568 PropertyDescriptor::IsDataDescriptor(¤t_desc) && | |
| 7569 current_desc.writable()) { | |
| 7570 return Just(false); | |
| 7571 } | |
| 7572 } | |
| 7573 } | |
| 7574 return Just(true); | |
| 7575 } | |
| 7513 | 7576 | 
| 7514 Maybe<bool> JSReceiver::PreventExtensions(Handle<JSReceiver> object, | 7577 Maybe<bool> JSReceiver::PreventExtensions(Handle<JSReceiver> object, | 
| 7515 ShouldThrow should_throw) { | 7578 ShouldThrow should_throw) { | 
| 7516 if (object->IsJSProxy()) { | 7579 if (object->IsJSProxy()) { | 
| 7517 return JSProxy::PreventExtensions(Handle<JSProxy>::cast(object), | 7580 return JSProxy::PreventExtensions(Handle<JSProxy>::cast(object), | 
| 7518 should_throw); | 7581 should_throw); | 
| 7519 } | 7582 } | 
| 7520 DCHECK(object->IsJSObject()); | 7583 DCHECK(object->IsJSObject()); | 
| 7521 return JSObject::PreventExtensions(Handle<JSObject>::cast(object), | 7584 return JSObject::PreventExtensions(Handle<JSObject>::cast(object), | 
| 7522 should_throw); | 7585 should_throw); | 
| (...skipping 13045 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 20568 // not | 20631 // not | 
| 20569 // depend on this. | 20632 // depend on this. | 
| 20570 return DICTIONARY_ELEMENTS; | 20633 return DICTIONARY_ELEMENTS; | 
| 20571 } | 20634 } | 
| 20572 DCHECK_LE(kind, LAST_ELEMENTS_KIND); | 20635 DCHECK_LE(kind, LAST_ELEMENTS_KIND); | 
| 20573 return kind; | 20636 return kind; | 
| 20574 } | 20637 } | 
| 20575 } | 20638 } | 
| 20576 } // namespace internal | 20639 } // namespace internal | 
| 20577 } // namespace v8 | 20640 } // namespace v8 | 
| OLD | NEW |