 Chromium Code Reviews
 Chromium Code Reviews Issue 649603003:
  Keyed stores to super with numeric keys.  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
    
  
    Issue 649603003:
  Keyed stores to super with numeric keys.  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge| 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 <sstream> | 5 #include <sstream> | 
| 6 | 6 | 
| 7 #include "src/v8.h" | 7 #include "src/v8.h" | 
| 8 | 8 | 
| 9 #include "src/accessors.h" | 9 #include "src/accessors.h" | 
| 10 #include "src/allocation-site-scopes.h" | 10 #include "src/allocation-site-scopes.h" | 
| (...skipping 784 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 795 js_object->GetElementsAccessor()->Get(receiver, js_object, index), | 795 js_object->GetElementsAccessor()->Get(receiver, js_object, index), | 
| 796 Object); | 796 Object); | 
| 797 if (!result->IsTheHole()) return result; | 797 if (!result->IsTheHole()) return result; | 
| 798 } | 798 } | 
| 799 } | 799 } | 
| 800 | 800 | 
| 801 return isolate->factory()->undefined_value(); | 801 return isolate->factory()->undefined_value(); | 
| 802 } | 802 } | 
| 803 | 803 | 
| 804 | 804 | 
| 805 static MaybeHandle<Object> GetElementStructure(Isolate* isolate, | |
| 806 Handle<JSObject> object, | |
| 807 uint32_t index) { | |
| 808 if (!object->HasDictionaryElements() && | |
| 809 !object->HasDictionaryArgumentsElements()) | |
| 810 return MaybeHandle<Object>(); | |
| 811 Handle<FixedArray> elements(FixedArray::cast(object->elements())); | |
| 812 bool is_arguments = | |
| 813 (elements->map() == isolate->heap()->sloppy_arguments_elements_map()); | |
| 814 Handle<SeededNumberDictionary> dictionary( | |
| 815 is_arguments ? SeededNumberDictionary::cast(elements->get(1)) | |
| 816 : SeededNumberDictionary::cast(*elements)); | |
| 817 int entry = dictionary->FindEntry(index); | |
| 818 if (entry != SeededNumberDictionary::kNotFound) { | |
| 819 Handle<Object> element(dictionary->ValueAt(entry), isolate); | |
| 820 PropertyDetails details = dictionary->DetailsAt(entry); | |
| 821 if (details.type() == CALLBACKS) return element; | |
| 822 } | |
| 823 return MaybeHandle<Object>(); | |
| 824 } | |
| 825 | |
| 826 | |
| 827 MaybeHandle<Object> Object::SetElementWithReceiver( | |
| 828 Isolate* isolate, Handle<Object> object, Handle<Object> receiver, | |
| 829 uint32_t index, Handle<Object> value, StrictMode strict_mode) { | |
| 830 // Iterate up the prototype chain until an element is found or the null | |
| 831 // prototype is encountered. | |
| 832 bool done = false; | |
| 833 for (PrototypeIterator iter(isolate, object, | |
| 834 object->IsJSProxy() || object->IsJSObject() | |
| 835 ? PrototypeIterator::START_AT_RECEIVER | |
| 836 : PrototypeIterator::START_AT_PROTOTYPE); | |
| 837 !iter.IsAtEnd() && !done; iter.Advance()) { | |
| 838 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) { | |
| 839 // TODO(dslomov): implement. | |
| 840 isolate->ThrowIllegalOperation(); | |
| 841 return MaybeHandle<Object>(); | |
| 842 } | |
| 843 | |
| 844 Handle<JSObject> js_object = | |
| 845 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); | |
| 846 | |
| 847 // Check access rights if needed. | |
| 848 if (js_object->IsAccessCheckNeeded()) { | |
| 849 if (!isolate->MayIndexedAccess(js_object, index, v8::ACCESS_SET)) { | |
| 850 isolate->ReportFailedAccessCheck(js_object, v8::ACCESS_SET); | |
| 851 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | |
| 852 return isolate->factory()->undefined_value(); | |
| 853 } | |
| 854 } | |
| 855 | |
| 856 if (js_object->HasIndexedInterceptor()) { | |
| 
Toon Verwaest
2014/10/13 12:16:36
If the holder is not the receiver, query the attri
 
Dmitry Lomov (no reviews)
2014/10/13 13:48:59
Done.
 | |
| 857 Handle<InterceptorInfo> interceptor(js_object->GetIndexedInterceptor()); | |
| 858 if (interceptor->setter()->IsUndefined()) { | |
| 859 return WriteToReadOnlyElement(isolate, receiver, index, value, | |
| 860 strict_mode); | |
| 861 } | |
| 862 // Treat indexed interceptor as presense of data property. | |
| 863 done = true; | |
| 864 } else if (js_object->elements() != isolate->heap()->empty_fixed_array()) { | |
| 865 ElementsAccessor* accessor = js_object->GetElementsAccessor(); | |
| 866 PropertyAttributes attrs = | |
| 867 accessor->GetAttributes(receiver, js_object, index); | |
| 868 if ((attrs & READ_ONLY) != 0) { | |
| 869 return WriteToReadOnlyElement(isolate, receiver, index, value, | |
| 870 strict_mode); | |
| 871 } | |
| 872 Handle<Object> element_structure; | |
| 873 if (GetElementStructure(isolate, js_object, index) | |
| 874 .ToHandle(&element_structure)) { | |
| 875 return JSObject::SetElementWithCallback( | |
| 876 receiver, element_structure, index, value, js_object, strict_mode); | |
| 877 } else { | |
| 878 done = attrs != ABSENT; | |
| 879 } | |
| 880 } | |
| 881 } | |
| 882 | |
| 883 if (!receiver->IsJSObject()) { | |
| 884 return WriteToReadOnlyElement(isolate, receiver, index, value, strict_mode); | |
| 
Toon Verwaest
2014/10/13 12:16:36
You only need to throw read-only exceptions for in
 
Dmitry Lomov (no reviews)
2014/10/13 13:48:59
Done.
 | |
| 885 } | |
| 886 Handle<JSObject> target = Handle<JSObject>::cast(receiver); | |
| 887 ElementsAccessor* accessor = target->GetElementsAccessor(); | |
| 888 PropertyAttributes attrs = accessor->GetAttributes(receiver, target, index); | |
| 889 if ((attrs & READ_ONLY) != 0) { | |
| 890 return WriteToReadOnlyElement(isolate, receiver, index, value, strict_mode); | |
| 891 } | |
| 892 PropertyAttributes new_attrs = attrs != ABSENT ? attrs : NONE; | |
| 893 return JSObject::SetElement(target, index, value, new_attrs, strict_mode, | |
| 894 false); | |
| 
Toon Verwaest
2014/10/13 12:16:36
Add a test to ensure that SetElement updates the l
 
Dmitry Lomov (no reviews)
2014/10/13 13:48:59
Done.
 | |
| 895 } | |
| 896 | |
| 897 | |
| 805 Map* Object::GetRootMap(Isolate* isolate) { | 898 Map* Object::GetRootMap(Isolate* isolate) { | 
| 806 DisallowHeapAllocation no_alloc; | 899 DisallowHeapAllocation no_alloc; | 
| 807 if (IsSmi()) { | 900 if (IsSmi()) { | 
| 808 Context* context = isolate->context()->native_context(); | 901 Context* context = isolate->context()->native_context(); | 
| 809 return context->number_function()->initial_map(); | 902 return context->number_function()->initial_map(); | 
| 810 } | 903 } | 
| 811 | 904 | 
| 812 HeapObject* heap_object = HeapObject::cast(this); | 905 HeapObject* heap_object = HeapObject::cast(this); | 
| 813 | 906 | 
| 814 // The object is either a number, a string, a boolean, | 907 // The object is either a number, a string, a boolean, | 
| (...skipping 2108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2923 if (strict_mode != STRICT) return value; | 3016 if (strict_mode != STRICT) return value; | 
| 2924 | 3017 | 
| 2925 Handle<Object> args[] = {it->name(), it->GetReceiver()}; | 3018 Handle<Object> args[] = {it->name(), it->GetReceiver()}; | 
| 2926 THROW_NEW_ERROR(it->isolate(), | 3019 THROW_NEW_ERROR(it->isolate(), | 
| 2927 NewTypeError("strict_read_only_property", | 3020 NewTypeError("strict_read_only_property", | 
| 2928 HandleVector(args, arraysize(args))), | 3021 HandleVector(args, arraysize(args))), | 
| 2929 Object); | 3022 Object); | 
| 2930 } | 3023 } | 
| 2931 | 3024 | 
| 2932 | 3025 | 
| 3026 MaybeHandle<Object> Object::WriteToReadOnlyElement(Isolate* isolate, | |
| 3027 Handle<Object> receiver, | |
| 3028 uint32_t index, | |
| 3029 Handle<Object> value, | |
| 3030 StrictMode strict_mode) { | |
| 3031 if (strict_mode != STRICT) return value; | |
| 3032 | |
| 3033 Handle<Object> args[] = {isolate->factory()->NewNumberFromUint(index), | |
| 3034 receiver}; | |
| 3035 THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property", | |
| 3036 HandleVector(args, arraysize(args))), | |
| 3037 Object); | |
| 3038 } | |
| 3039 | |
| 3040 | |
| 2933 Handle<Object> Object::SetDataProperty(LookupIterator* it, | 3041 Handle<Object> Object::SetDataProperty(LookupIterator* it, | 
| 2934 Handle<Object> value) { | 3042 Handle<Object> value) { | 
| 2935 // Proxies are handled on the WithHandler path. Other non-JSObjects cannot | 3043 // Proxies are handled on the WithHandler path. Other non-JSObjects cannot | 
| 2936 // have own properties. | 3044 // have own properties. | 
| 2937 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver()); | 3045 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver()); | 
| 2938 | 3046 | 
| 2939 // Store on the holder which may be hidden behind the receiver. | 3047 // Store on the holder which may be hidden behind the receiver. | 
| 2940 DCHECK(it->HolderIsReceiverOrHiddenPrototype()); | 3048 DCHECK(it->HolderIsReceiverOrHiddenPrototype()); | 
| 2941 | 3049 | 
| 2942 // Old value for the observation change record. | 3050 // Old value for the observation change record. | 
| (...skipping 8915 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11858 if (structure->IsDeclaredAccessorInfo()) { | 11966 if (structure->IsDeclaredAccessorInfo()) { | 
| 11859 return GetDeclaredAccessorProperty( | 11967 return GetDeclaredAccessorProperty( | 
| 11860 receiver, Handle<DeclaredAccessorInfo>::cast(structure), isolate); | 11968 receiver, Handle<DeclaredAccessorInfo>::cast(structure), isolate); | 
| 11861 } | 11969 } | 
| 11862 | 11970 | 
| 11863 UNREACHABLE(); | 11971 UNREACHABLE(); | 
| 11864 return MaybeHandle<Object>(); | 11972 return MaybeHandle<Object>(); | 
| 11865 } | 11973 } | 
| 11866 | 11974 | 
| 11867 | 11975 | 
| 11868 MaybeHandle<Object> JSObject::SetElementWithCallback(Handle<JSObject> object, | 11976 MaybeHandle<Object> JSObject::SetElementWithCallback( | 
| 11869 Handle<Object> structure, | 11977 Handle<Object> object, Handle<Object> structure, uint32_t index, | 
| 11870 uint32_t index, | 11978 Handle<Object> value, Handle<JSObject> holder, StrictMode strict_mode) { | 
| 11871 Handle<Object> value, | 11979 Isolate* isolate = holder->GetIsolate(); | 
| 11872 Handle<JSObject> holder, | |
| 11873 StrictMode strict_mode) { | |
| 11874 Isolate* isolate = object->GetIsolate(); | |
| 11875 | 11980 | 
| 11876 // We should never get here to initialize a const with the hole | 11981 // We should never get here to initialize a const with the hole | 
| 11877 // value since a const declaration would conflict with the setter. | 11982 // value since a const declaration would conflict with the setter. | 
| 11878 DCHECK(!value->IsTheHole()); | 11983 DCHECK(!value->IsTheHole()); | 
| 11879 DCHECK(!structure->IsForeign()); | 11984 DCHECK(!structure->IsForeign()); | 
| 11880 if (structure->IsExecutableAccessorInfo()) { | 11985 if (structure->IsExecutableAccessorInfo()) { | 
| 11881 // api style callbacks | 11986 // api style callbacks | 
| 11882 Handle<ExecutableAccessorInfo> data = | 11987 Handle<ExecutableAccessorInfo> data = | 
| 11883 Handle<ExecutableAccessorInfo>::cast(structure); | 11988 Handle<ExecutableAccessorInfo>::cast(structure); | 
| 11884 Object* call_obj = data->setter(); | 11989 Object* call_obj = data->setter(); | 
| 11885 v8::AccessorNameSetterCallback call_fun = | 11990 v8::AccessorNameSetterCallback call_fun = | 
| 11886 v8::ToCData<v8::AccessorNameSetterCallback>(call_obj); | 11991 v8::ToCData<v8::AccessorNameSetterCallback>(call_obj); | 
| 11887 if (call_fun == NULL) return value; | 11992 if (call_fun == NULL) return value; | 
| 11888 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 11993 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 
| 11889 Handle<String> key(isolate->factory()->NumberToString(number)); | 11994 Handle<String> key(isolate->factory()->NumberToString(number)); | 
| 11890 LOG(isolate, ApiNamedPropertyAccess("store", *object, *key)); | 11995 LOG(isolate, ApiNamedPropertyAccess("store", *holder, *key)); | 
| 11891 PropertyCallbackArguments | 11996 PropertyCallbackArguments | 
| 11892 args(isolate, data->data(), *object, *holder); | 11997 args(isolate, data->data(), *object, *holder); | 
| 11893 args.Call(call_fun, | 11998 args.Call(call_fun, | 
| 11894 v8::Utils::ToLocal(key), | 11999 v8::Utils::ToLocal(key), | 
| 11895 v8::Utils::ToLocal(value)); | 12000 v8::Utils::ToLocal(value)); | 
| 11896 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 12001 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 
| 11897 return value; | 12002 return value; | 
| 11898 } | 12003 } | 
| 11899 | 12004 | 
| 11900 if (structure->IsAccessorPair()) { | 12005 if (structure->IsAccessorPair()) { | 
| (...skipping 4481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 16382 Handle<DependentCode> codes = | 16487 Handle<DependentCode> codes = | 
| 16383 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), | 16488 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), | 
| 16384 DependentCode::kPropertyCellChangedGroup, | 16489 DependentCode::kPropertyCellChangedGroup, | 
| 16385 info->object_wrapper()); | 16490 info->object_wrapper()); | 
| 16386 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); | 16491 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); | 
| 16387 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( | 16492 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( | 
| 16388 cell, info->zone()); | 16493 cell, info->zone()); | 
| 16389 } | 16494 } | 
| 16390 | 16495 | 
| 16391 } } // namespace v8::internal | 16496 } } // namespace v8::internal | 
| OLD | NEW |