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

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: Fix the patch to match the spec for primitives 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) {
Toon Verwaest 2014/10/14 08:31:54 Replace by JSObject::GetOwnElementAccessorPair
Dmitry Lomov (no reviews) 2014/10/14 09:08:37 Is that enough? SetElementWithCallback handles mor
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()) {
857 Maybe<PropertyAttributes> from_interceptor =
858 JSObject::GetElementAttributeFromInterceptor(js_object, receiver,
859 index);
860 if (from_interceptor.has_value) {
Toon Verwaest 2014/10/14 08:31:54 The contract is normally that if !has_value, an ex
Dmitry Lomov (no reviews) 2014/10/14 09:08:37 I see. Wow, all those things could use some docume
Dmitry Lomov (no reviews) 2014/10/14 09:28:26 Done.
861 if ((from_interceptor.value & READ_ONLY) != 0) {
862 return WriteToReadOnlyElement(isolate, receiver, index, value,
863 strict_mode);
864 }
865 // Treat indexed interceptor as presence of data property.
866 done = true;
867 }
868 } else if (js_object->elements() != isolate->heap()->empty_fixed_array()) {
869 ElementsAccessor* accessor = js_object->GetElementsAccessor();
870 PropertyAttributes attrs =
871 accessor->GetAttributes(receiver, js_object, index);
872 if ((attrs & READ_ONLY) != 0) {
873 return WriteToReadOnlyElement(isolate, receiver, index, value,
874 strict_mode);
875 }
876 Handle<Object> element_structure;
877 if (GetElementStructure(isolate, js_object, index)
878 .ToHandle(&element_structure)) {
879 return JSObject::SetElementWithCallback(
880 receiver, element_structure, index, value, js_object, strict_mode);
881 } else {
882 done = attrs != ABSENT;
883 }
884 }
885 }
886
887 if (!receiver->IsJSObject()) {
888 return WriteToReadOnlyElement(isolate, receiver, index, value, strict_mode);
889 }
890 Handle<JSObject> target = Handle<JSObject>::cast(receiver);
891 ElementsAccessor* accessor = target->GetElementsAccessor();
892 PropertyAttributes attrs = accessor->GetAttributes(receiver, target, index);
893 if ((attrs & READ_ONLY) != 0) {
894 return WriteToReadOnlyElement(isolate, receiver, index, value, strict_mode);
895 }
896 PropertyAttributes new_attrs = attrs != ABSENT ? attrs : NONE;
897 return JSObject::SetElement(target, index, value, new_attrs, strict_mode,
898 false);
899 }
900
901
805 Map* Object::GetRootMap(Isolate* isolate) { 902 Map* Object::GetRootMap(Isolate* isolate) {
806 DisallowHeapAllocation no_alloc; 903 DisallowHeapAllocation no_alloc;
807 if (IsSmi()) { 904 if (IsSmi()) {
808 Context* context = isolate->context()->native_context(); 905 Context* context = isolate->context()->native_context();
809 return context->number_function()->initial_map(); 906 return context->number_function()->initial_map();
810 } 907 }
811 908
812 HeapObject* heap_object = HeapObject::cast(this); 909 HeapObject* heap_object = HeapObject::cast(this);
813 910
814 // The object is either a number, a string, a boolean, 911 // 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; 3020 if (strict_mode != STRICT) return value;
2924 3021
2925 Handle<Object> args[] = {it->name(), it->GetReceiver()}; 3022 Handle<Object> args[] = {it->name(), it->GetReceiver()};
2926 THROW_NEW_ERROR(it->isolate(), 3023 THROW_NEW_ERROR(it->isolate(),
2927 NewTypeError("strict_read_only_property", 3024 NewTypeError("strict_read_only_property",
2928 HandleVector(args, arraysize(args))), 3025 HandleVector(args, arraysize(args))),
2929 Object); 3026 Object);
2930 } 3027 }
2931 3028
2932 3029
3030 MaybeHandle<Object> Object::WriteToReadOnlyElement(Isolate* isolate,
3031 Handle<Object> receiver,
3032 uint32_t index,
3033 Handle<Object> value,
3034 StrictMode strict_mode) {
3035 if (strict_mode != STRICT) return value;
3036
3037 Handle<Object> args[] = {isolate->factory()->NewNumberFromUint(index),
3038 receiver};
3039 THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property",
3040 HandleVector(args, arraysize(args))),
3041 Object);
3042 }
3043
3044
2933 Handle<Object> Object::SetDataProperty(LookupIterator* it, 3045 Handle<Object> Object::SetDataProperty(LookupIterator* it,
2934 Handle<Object> value) { 3046 Handle<Object> value) {
2935 // Proxies are handled on the WithHandler path. Other non-JSObjects cannot 3047 // Proxies are handled on the WithHandler path. Other non-JSObjects cannot
2936 // have own properties. 3048 // have own properties.
2937 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver()); 3049 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver());
2938 3050
2939 // Store on the holder which may be hidden behind the receiver. 3051 // Store on the holder which may be hidden behind the receiver.
2940 DCHECK(it->HolderIsReceiverOrHiddenPrototype()); 3052 DCHECK(it->HolderIsReceiverOrHiddenPrototype());
2941 3053
2942 // Old value for the observation change record. 3054 // Old value for the observation change record.
(...skipping 1107 matching lines...) Expand 10 before | Expand all | Expand 10 after
4050 Maybe<PropertyAttributes> JSObject::GetElementAttributeWithInterceptor( 4162 Maybe<PropertyAttributes> JSObject::GetElementAttributeWithInterceptor(
4051 Handle<JSObject> object, Handle<JSReceiver> receiver, uint32_t index, 4163 Handle<JSObject> object, Handle<JSReceiver> receiver, uint32_t index,
4052 bool check_prototype) { 4164 bool check_prototype) {
4053 Isolate* isolate = object->GetIsolate(); 4165 Isolate* isolate = object->GetIsolate();
4054 HandleScope scope(isolate); 4166 HandleScope scope(isolate);
4055 4167
4056 // Make sure that the top context does not change when doing 4168 // Make sure that the top context does not change when doing
4057 // callbacks or interceptor calls. 4169 // callbacks or interceptor calls.
4058 AssertNoContextChange ncc(isolate); 4170 AssertNoContextChange ncc(isolate);
4059 4171
4172 Maybe<PropertyAttributes> from_interceptor =
4173 GetElementAttributeFromInterceptor(object, receiver, index);
4174
4175 if (from_interceptor.has_value) return from_interceptor;
4176
4177 return GetElementAttributeWithoutInterceptor(object, receiver, index,
4178 check_prototype);
4179 }
4180
4181
4182 Maybe<PropertyAttributes> JSObject::GetElementAttributeFromInterceptor(
4183 Handle<JSObject> object, Handle<Object> receiver, uint32_t index) {
4184 Isolate* isolate = object->GetIsolate();
4185 AssertNoContextChange ncc(isolate);
4186
4060 Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor()); 4187 Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor());
4061 PropertyCallbackArguments args( 4188 PropertyCallbackArguments args(
4062 isolate, interceptor->data(), *receiver, *object); 4189 isolate, interceptor->data(), *receiver, *object);
4063 if (!interceptor->query()->IsUndefined()) { 4190 if (!interceptor->query()->IsUndefined()) {
4064 v8::IndexedPropertyQueryCallback query = 4191 v8::IndexedPropertyQueryCallback query =
4065 v8::ToCData<v8::IndexedPropertyQueryCallback>(interceptor->query()); 4192 v8::ToCData<v8::IndexedPropertyQueryCallback>(interceptor->query());
4066 LOG(isolate, 4193 LOG(isolate,
4067 ApiIndexedPropertyAccess("interceptor-indexed-has", *object, index)); 4194 ApiIndexedPropertyAccess("interceptor-indexed-has", *object, index));
4068 v8::Handle<v8::Integer> result = args.Call(query, index); 4195 v8::Handle<v8::Integer> result = args.Call(query, index);
4069 if (!result.IsEmpty()) 4196 if (!result.IsEmpty())
4070 return maybe(static_cast<PropertyAttributes>(result->Int32Value())); 4197 return maybe(static_cast<PropertyAttributes>(result->Int32Value()));
4071 } else if (!interceptor->getter()->IsUndefined()) { 4198 } else if (!interceptor->getter()->IsUndefined()) {
4072 v8::IndexedPropertyGetterCallback getter = 4199 v8::IndexedPropertyGetterCallback getter =
4073 v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter()); 4200 v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter());
4074 LOG(isolate, 4201 LOG(isolate,
4075 ApiIndexedPropertyAccess( 4202 ApiIndexedPropertyAccess(
4076 "interceptor-indexed-get-has", *object, index)); 4203 "interceptor-indexed-get-has", *object, index));
4077 v8::Handle<v8::Value> result = args.Call(getter, index); 4204 v8::Handle<v8::Value> result = args.Call(getter, index);
4078 if (!result.IsEmpty()) return maybe(NONE); 4205 if (!result.IsEmpty()) return maybe(NONE);
4079 } 4206 }
4080 4207
4081 return GetElementAttributeWithoutInterceptor( 4208 return Maybe<PropertyAttributes>();
4082 object, receiver, index, check_prototype);
4083 } 4209 }
4084 4210
4085 4211
4086 Maybe<PropertyAttributes> JSObject::GetElementAttributeWithoutInterceptor( 4212 Maybe<PropertyAttributes> JSObject::GetElementAttributeWithoutInterceptor(
4087 Handle<JSObject> object, Handle<JSReceiver> receiver, uint32_t index, 4213 Handle<JSObject> object, Handle<JSReceiver> receiver, uint32_t index,
4088 bool check_prototype) { 4214 bool check_prototype) {
4089 PropertyAttributes attr = object->GetElementsAccessor()->GetAttributes( 4215 PropertyAttributes attr = object->GetElementsAccessor()->GetAttributes(
4090 receiver, object, index); 4216 receiver, object, index);
4091 if (attr != ABSENT) return maybe(attr); 4217 if (attr != ABSENT) return maybe(attr);
4092 4218
(...skipping 7771 matching lines...) Expand 10 before | Expand all | Expand 10 after
11864 if (structure->IsDeclaredAccessorInfo()) { 11990 if (structure->IsDeclaredAccessorInfo()) {
11865 return GetDeclaredAccessorProperty( 11991 return GetDeclaredAccessorProperty(
11866 receiver, Handle<DeclaredAccessorInfo>::cast(structure), isolate); 11992 receiver, Handle<DeclaredAccessorInfo>::cast(structure), isolate);
11867 } 11993 }
11868 11994
11869 UNREACHABLE(); 11995 UNREACHABLE();
11870 return MaybeHandle<Object>(); 11996 return MaybeHandle<Object>();
11871 } 11997 }
11872 11998
11873 11999
11874 MaybeHandle<Object> JSObject::SetElementWithCallback(Handle<JSObject> object, 12000 MaybeHandle<Object> JSObject::SetElementWithCallback(
11875 Handle<Object> structure, 12001 Handle<Object> object, Handle<Object> structure, uint32_t index,
11876 uint32_t index, 12002 Handle<Object> value, Handle<JSObject> holder, StrictMode strict_mode) {
11877 Handle<Object> value, 12003 Isolate* isolate = holder->GetIsolate();
11878 Handle<JSObject> holder,
11879 StrictMode strict_mode) {
11880 Isolate* isolate = object->GetIsolate();
11881 12004
11882 // We should never get here to initialize a const with the hole 12005 // We should never get here to initialize a const with the hole
11883 // value since a const declaration would conflict with the setter. 12006 // value since a const declaration would conflict with the setter.
11884 DCHECK(!value->IsTheHole()); 12007 DCHECK(!value->IsTheHole());
11885 DCHECK(!structure->IsForeign()); 12008 DCHECK(!structure->IsForeign());
11886 if (structure->IsExecutableAccessorInfo()) { 12009 if (structure->IsExecutableAccessorInfo()) {
11887 // api style callbacks 12010 // api style callbacks
11888 Handle<ExecutableAccessorInfo> data = 12011 Handle<ExecutableAccessorInfo> data =
11889 Handle<ExecutableAccessorInfo>::cast(structure); 12012 Handle<ExecutableAccessorInfo>::cast(structure);
11890 Object* call_obj = data->setter(); 12013 Object* call_obj = data->setter();
11891 v8::AccessorNameSetterCallback call_fun = 12014 v8::AccessorNameSetterCallback call_fun =
11892 v8::ToCData<v8::AccessorNameSetterCallback>(call_obj); 12015 v8::ToCData<v8::AccessorNameSetterCallback>(call_obj);
11893 if (call_fun == NULL) return value; 12016 if (call_fun == NULL) return value;
11894 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); 12017 Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
11895 Handle<String> key(isolate->factory()->NumberToString(number)); 12018 Handle<String> key(isolate->factory()->NumberToString(number));
11896 LOG(isolate, ApiNamedPropertyAccess("store", *object, *key)); 12019 LOG(isolate, ApiNamedPropertyAccess("store", *holder, *key));
11897 PropertyCallbackArguments 12020 PropertyCallbackArguments
11898 args(isolate, data->data(), *object, *holder); 12021 args(isolate, data->data(), *object, *holder);
11899 args.Call(call_fun, 12022 args.Call(call_fun,
11900 v8::Utils::ToLocal(key), 12023 v8::Utils::ToLocal(key),
11901 v8::Utils::ToLocal(value)); 12024 v8::Utils::ToLocal(value));
11902 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); 12025 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
11903 return value; 12026 return value;
11904 } 12027 }
11905 12028
11906 if (structure->IsAccessorPair()) { 12029 if (structure->IsAccessorPair()) {
(...skipping 4481 matching lines...) Expand 10 before | Expand all | Expand 10 after
16388 Handle<DependentCode> codes = 16511 Handle<DependentCode> codes =
16389 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), 16512 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()),
16390 DependentCode::kPropertyCellChangedGroup, 16513 DependentCode::kPropertyCellChangedGroup,
16391 info->object_wrapper()); 16514 info->object_wrapper());
16392 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); 16515 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes);
16393 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( 16516 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add(
16394 cell, info->zone()); 16517 cell, info->zone());
16395 } 16518 }
16396 16519
16397 } } // namespace v8::internal 16520 } } // 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