OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 <sstream> | 9 #include <sstream> |
10 | 10 |
(...skipping 827 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
838 Handle<FixedArray> elems(FixedArray::cast(object->elements()), isolate); | 838 Handle<FixedArray> elems(FixedArray::cast(object->elements()), isolate); |
839 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems; | 839 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems; |
840 Handle<FixedArray> writable_elems = isolate->factory()->CopyFixedArrayWithMap( | 840 Handle<FixedArray> writable_elems = isolate->factory()->CopyFixedArrayWithMap( |
841 elems, isolate->factory()->fixed_array_map()); | 841 elems, isolate->factory()->fixed_array_map()); |
842 object->set_elements(*writable_elems); | 842 object->set_elements(*writable_elems); |
843 isolate->counters()->cow_arrays_converted()->Increment(); | 843 isolate->counters()->cow_arrays_converted()->Increment(); |
844 return writable_elems; | 844 return writable_elems; |
845 } | 845 } |
846 | 846 |
847 | 847 |
| 848 // ES6 9.5.1 |
| 849 // static |
| 850 MaybeHandle<Object> JSProxy::GetPrototype(Handle<JSProxy> proxy) { |
| 851 Isolate* isolate = proxy->GetIsolate(); |
| 852 // 1. Let handler be the value of the [[ProxyHandler]] internal slot. |
| 853 Handle<Object> raw_handler(proxy->handler(), isolate); |
| 854 // 2. If handler is null, throw a TypeError exception. |
| 855 // 3. Assert: Type(handler) is Object. |
| 856 if (!raw_handler->IsSpecObject()) { |
| 857 // TODO(cbruni): Throw correct error message. |
| 858 THROW_NEW_ERROR( |
| 859 isolate, NewTypeError(MessageTemplate::kProxyHandlerNonObject), Object); |
| 860 } |
| 861 Handle<JSReceiver> handler = Handle<JSReceiver>::cast(raw_handler); |
| 862 // 4. Let target be the value of the [[ProxyTarget]] internal slot. |
| 863 // TODO(cbruni): Change target type to JSReceiver by default. |
| 864 Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate); |
| 865 // 5. Let trap be ? GetMethod(handler, "getPrototypeOf"). |
| 866 Handle<Object> trap; |
| 867 Handle<String> trap_name = isolate->factory()->getPrototypeOf_string(); |
| 868 ASSIGN_RETURN_ON_EXCEPTION(isolate, trap, GetMethod(handler, trap_name), |
| 869 Object); |
| 870 // 6. If trap is undefined, then return target.[[GetPrototypeOf]](). |
| 871 if (trap->IsUndefined()) { |
| 872 return Object::GetPrototype(isolate, target); |
| 873 } |
| 874 // 7. Let handlerProto be ? Call(trap, handler, «target»). |
| 875 Handle<Object> argv[] = {target}; |
| 876 Handle<Object> handler_proto; |
| 877 ASSIGN_RETURN_ON_EXCEPTION( |
| 878 isolate, handler_proto, |
| 879 Execution::Call(isolate, trap, handler, arraysize(argv), argv), Object); |
| 880 // 8. If Type(handlerProto) is neither Object nor Null, throw a TypeError. |
| 881 if (!(handler_proto->IsSpecObject() || handler_proto->IsNull())) { |
| 882 THROW_NEW_ERROR(isolate, |
| 883 NewTypeError(MessageTemplate::kProxyHandlerTrapMissing, |
| 884 handler, trap_name), |
| 885 Object); |
| 886 } |
| 887 // 9. Let extensibleTarget be ? IsExtensible(target). |
| 888 Maybe<bool> is_extensible = JSReceiver::IsExtensible(target); |
| 889 if (is_extensible.IsNothing()) return MaybeHandle<Object>(); |
| 890 // 10. If extensibleTarget is true, return handlerProto. |
| 891 if (is_extensible.FromJust()) return handler_proto; |
| 892 // 11. Let targetProto be ? target.[[GetPrototypeOf]](). |
| 893 Handle<Object> target_proto; |
| 894 ASSIGN_RETURN_ON_EXCEPTION(isolate, handler_proto, |
| 895 Object::GetPrototype(isolate, target), Object); |
| 896 // 12. If SameValue(handlerProto, targetProto) is false, throw a TypeError. |
| 897 if (!handler_proto->SameValue(*target_proto)) { |
| 898 THROW_NEW_ERROR(isolate, |
| 899 NewTypeError(MessageTemplate::kProxyHandlerTrapMissing, |
| 900 handler, trap_name), |
| 901 Object); |
| 902 } |
| 903 // 13. Return handlerProto. |
| 904 return handler_proto; |
| 905 } |
| 906 |
| 907 |
848 MaybeHandle<Object> JSProxy::GetPropertyWithHandler(Handle<JSProxy> proxy, | 908 MaybeHandle<Object> JSProxy::GetPropertyWithHandler(Handle<JSProxy> proxy, |
849 Handle<Object> receiver, | 909 Handle<Object> receiver, |
850 Handle<Name> name) { | 910 Handle<Name> name) { |
851 Isolate* isolate = proxy->GetIsolate(); | 911 Isolate* isolate = proxy->GetIsolate(); |
852 | 912 |
853 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 913 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
854 if (name->IsSymbol()) return isolate->factory()->undefined_value(); | 914 if (name->IsSymbol()) return isolate->factory()->undefined_value(); |
855 | 915 |
856 Handle<Object> args[] = { receiver, name }; | 916 Handle<Object> args[] = { receiver, name }; |
857 return CallTrap( | 917 return CallTrap( |
(...skipping 4689 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5547 hash_code_symbol).ToHandleChecked(); | 5607 hash_code_symbol).ToHandleChecked(); |
5548 return stored_value->IsSmi() ? *stored_value | 5608 return stored_value->IsSmi() ? *stored_value |
5549 : isolate->heap()->undefined_value(); | 5609 : isolate->heap()->undefined_value(); |
5550 } | 5610 } |
5551 | 5611 |
5552 | 5612 |
5553 Handle<Smi> JSObject::GetOrCreateIdentityHash(Handle<JSObject> object) { | 5613 Handle<Smi> JSObject::GetOrCreateIdentityHash(Handle<JSObject> object) { |
5554 if (object->IsJSGlobalProxy()) { | 5614 if (object->IsJSGlobalProxy()) { |
5555 return GetOrCreateIdentityHashHelper(Handle<JSGlobalProxy>::cast(object)); | 5615 return GetOrCreateIdentityHashHelper(Handle<JSGlobalProxy>::cast(object)); |
5556 } | 5616 } |
5557 | |
5558 Isolate* isolate = object->GetIsolate(); | 5617 Isolate* isolate = object->GetIsolate(); |
5559 | 5618 |
5560 Handle<Object> maybe_hash(object->GetIdentityHash(), isolate); | 5619 Handle<Object> maybe_hash(object->GetIdentityHash(), isolate); |
5561 if (maybe_hash->IsSmi()) return Handle<Smi>::cast(maybe_hash); | 5620 if (maybe_hash->IsSmi()) return Handle<Smi>::cast(maybe_hash); |
5562 | 5621 |
5563 Handle<Smi> hash(GenerateIdentityHash(isolate), isolate); | 5622 Handle<Smi> hash(GenerateIdentityHash(isolate), isolate); |
5564 Handle<Name> hash_code_symbol(isolate->heap()->hash_code_symbol()); | 5623 Handle<Name> hash_code_symbol(isolate->heap()->hash_code_symbol()); |
5565 JSObject::AddProperty(object, hash_code_symbol, hash, NONE); | 5624 JSObject::AddProperty(object, hash_code_symbol, hash, NONE); |
5566 return hash; | 5625 return hash; |
5567 } | 5626 } |
(...skipping 1282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6850 RETURN_ON_EXCEPTION_VALUE( | 6909 RETURN_ON_EXCEPTION_VALUE( |
6851 isolate, | 6910 isolate, |
6852 EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(), | 6911 EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(), |
6853 isolate->factory()->the_hole_value()), | 6912 isolate->factory()->the_hole_value()), |
6854 Nothing<bool>()); | 6913 Nothing<bool>()); |
6855 } | 6914 } |
6856 return Just(true); | 6915 return Just(true); |
6857 } | 6916 } |
6858 | 6917 |
6859 | 6918 |
| 6919 // static |
| 6920 Maybe<bool> JSReceiver::IsExtensible(Handle<JSReceiver> object) { |
| 6921 if (object->IsJSProxy()) { |
| 6922 // TODO(neis,cbruni): Redirect to the trap on JSProxy. |
| 6923 return Just(true); |
| 6924 } |
| 6925 return Just(JSObject::IsExtensible(Handle<JSObject>::cast(object))); |
| 6926 } |
| 6927 |
| 6928 |
6860 bool JSObject::IsExtensible(Handle<JSObject> object) { | 6929 bool JSObject::IsExtensible(Handle<JSObject> object) { |
6861 Isolate* isolate = object->GetIsolate(); | 6930 Isolate* isolate = object->GetIsolate(); |
6862 if (object->IsAccessCheckNeeded() && | 6931 if (object->IsAccessCheckNeeded() && |
6863 !isolate->MayAccess(handle(isolate->context()), object)) { | 6932 !isolate->MayAccess(handle(isolate->context()), object)) { |
6864 return true; | 6933 return true; |
6865 } | 6934 } |
6866 if (object->IsJSGlobalProxy()) { | 6935 if (object->IsJSGlobalProxy()) { |
6867 PrototypeIterator iter(isolate, *object); | 6936 PrototypeIterator iter(isolate, *object); |
6868 if (iter.IsAtEnd()) return false; | 6937 if (iter.IsAtEnd()) return false; |
6869 DCHECK(iter.GetCurrent()->IsJSGlobalObject()); | 6938 DCHECK(iter.GetCurrent()->IsJSGlobalObject()); |
(...skipping 1172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8042 } | 8111 } |
8043 | 8112 |
8044 return result; | 8113 return result; |
8045 } | 8114 } |
8046 | 8115 |
8047 | 8116 |
8048 Handle<Map> Map::CopyDropDescriptors(Handle<Map> map) { | 8117 Handle<Map> Map::CopyDropDescriptors(Handle<Map> map) { |
8049 Handle<Map> result = RawCopy(map, map->instance_size()); | 8118 Handle<Map> result = RawCopy(map, map->instance_size()); |
8050 | 8119 |
8051 // Please note instance_type and instance_size are set when allocated. | 8120 // Please note instance_type and instance_size are set when allocated. |
8052 result->SetInObjectProperties(map->GetInObjectProperties()); | 8121 if (map->IsJSObjectMap()) { |
8053 result->set_unused_property_fields(map->unused_property_fields()); | 8122 result->SetInObjectProperties(map->GetInObjectProperties()); |
8054 | 8123 result->set_unused_property_fields(map->unused_property_fields()); |
| 8124 } |
8055 result->ClearCodeCache(map->GetHeap()); | 8125 result->ClearCodeCache(map->GetHeap()); |
8056 map->NotifyLeafMapLayoutChange(); | 8126 map->NotifyLeafMapLayoutChange(); |
8057 return result; | 8127 return result; |
8058 } | 8128 } |
8059 | 8129 |
8060 | 8130 |
8061 Handle<Map> Map::ShareDescriptor(Handle<Map> map, | 8131 Handle<Map> Map::ShareDescriptor(Handle<Map> map, |
8062 Handle<DescriptorArray> descriptors, | 8132 Handle<DescriptorArray> descriptors, |
8063 Descriptor* descriptor) { | 8133 Descriptor* descriptor) { |
8064 // Sanity check. This path is only to be taken if the map owns its descriptor | 8134 // Sanity check. This path is only to be taken if the map owns its descriptor |
(...skipping 5828 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13893 | 13963 |
13894 | 13964 |
13895 Maybe<bool> JSObject::SetPrototype(Handle<JSObject> object, | 13965 Maybe<bool> JSObject::SetPrototype(Handle<JSObject> object, |
13896 Handle<Object> value, bool from_javascript, | 13966 Handle<Object> value, bool from_javascript, |
13897 ShouldThrow should_throw) { | 13967 ShouldThrow should_throw) { |
13898 Isolate* isolate = object->GetIsolate(); | 13968 Isolate* isolate = object->GetIsolate(); |
13899 | 13969 |
13900 const bool observed = from_javascript && object->map()->is_observed(); | 13970 const bool observed = from_javascript && object->map()->is_observed(); |
13901 Handle<Object> old_value; | 13971 Handle<Object> old_value; |
13902 if (observed) { | 13972 if (observed) { |
13903 old_value = Object::GetPrototype(isolate, object); | 13973 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, old_value, |
| 13974 Object::GetPrototype(isolate, object), |
| 13975 Nothing<bool>()); |
13904 } | 13976 } |
13905 | 13977 |
13906 Maybe<bool> result = | 13978 Maybe<bool> result = |
13907 SetPrototypeUnobserved(object, value, from_javascript, should_throw); | 13979 SetPrototypeUnobserved(object, value, from_javascript, should_throw); |
13908 MAYBE_RETURN(result, Nothing<bool>()); | 13980 MAYBE_RETURN(result, Nothing<bool>()); |
13909 | 13981 |
13910 if (result.FromJust() && observed) { | 13982 if (result.FromJust() && observed) { |
13911 Handle<Object> new_value = Object::GetPrototype(isolate, object); | 13983 Handle<Object> new_value; |
| 13984 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, new_value, |
| 13985 Object::GetPrototype(isolate, object), |
| 13986 Nothing<bool>()); |
13912 if (!new_value->SameValue(*old_value)) { | 13987 if (!new_value->SameValue(*old_value)) { |
13913 RETURN_ON_EXCEPTION_VALUE( | 13988 RETURN_ON_EXCEPTION_VALUE( |
13914 isolate, JSObject::EnqueueChangeRecord( | 13989 isolate, JSObject::EnqueueChangeRecord( |
13915 object, "setPrototype", | 13990 object, "setPrototype", |
13916 isolate->factory()->proto_string(), old_value), | 13991 isolate->factory()->proto_string(), old_value), |
13917 Nothing<bool>()); | 13992 Nothing<bool>()); |
13918 } | 13993 } |
13919 } | 13994 } |
13920 | 13995 |
13921 return result; | 13996 return result; |
(...skipping 3938 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17860 if (cell->value() != *new_value) { | 17935 if (cell->value() != *new_value) { |
17861 cell->set_value(*new_value); | 17936 cell->set_value(*new_value); |
17862 Isolate* isolate = cell->GetIsolate(); | 17937 Isolate* isolate = cell->GetIsolate(); |
17863 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 17938 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
17864 isolate, DependentCode::kPropertyCellChangedGroup); | 17939 isolate, DependentCode::kPropertyCellChangedGroup); |
17865 } | 17940 } |
17866 } | 17941 } |
17867 | 17942 |
17868 } // namespace internal | 17943 } // namespace internal |
17869 } // namespace v8 | 17944 } // namespace v8 |
OLD | NEW |