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 |