Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: src/objects.cc

Issue 649603003: Keyed stores to super with numeric keys. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Stray declaration removed Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/runtime/runtime-classes.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/runtime/runtime-classes.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698