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

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: Rebased 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 MaybeHandle<Object> Object::SetElementWithReceiver(
806 Isolate* isolate, Handle<Object> object, Handle<Object> receiver,
807 uint32_t index, Handle<Object> value, StrictMode strict_mode) {
808 // Iterate up the prototype chain until an element is found or the null
809 // prototype is encountered.
810 bool done = false;
811 for (PrototypeIterator iter(isolate, object,
812 object->IsJSProxy() || object->IsJSObject()
813 ? PrototypeIterator::START_AT_RECEIVER
814 : PrototypeIterator::START_AT_PROTOTYPE);
815 !iter.IsAtEnd() && !done; iter.Advance()) {
816 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
817 // TODO(dslomov): implement.
818 isolate->ThrowIllegalOperation();
819 return MaybeHandle<Object>();
820 }
821
822 Handle<JSObject> js_object =
823 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
824
825 // Check access rights if needed.
826 if (js_object->IsAccessCheckNeeded()) {
827 if (!isolate->MayIndexedAccess(js_object, index, v8::ACCESS_SET)) {
828 isolate->ReportFailedAccessCheck(js_object, v8::ACCESS_SET);
829 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
830 return isolate->factory()->undefined_value();
831 }
832 }
833
834 if (js_object->HasIndexedInterceptor()) {
835 Maybe<PropertyAttributes> from_interceptor =
836 JSObject::GetElementAttributeFromInterceptor(js_object, receiver,
837 index);
838 if (!from_interceptor.has_value) return MaybeHandle<Object>();
839 if ((from_interceptor.value & READ_ONLY) != 0) {
840 return WriteToReadOnlyElement(isolate, receiver, index, value,
841 strict_mode);
842 }
843 done = from_interceptor.value != ABSENT;
844 }
845
846 if (!done &&
847 js_object->elements() != isolate->heap()->empty_fixed_array()) {
848 ElementsAccessor* accessor = js_object->GetElementsAccessor();
849 PropertyAttributes attrs =
850 accessor->GetAttributes(receiver, js_object, index);
851 if ((attrs & READ_ONLY) != 0) {
852 return WriteToReadOnlyElement(isolate, receiver, index, value,
853 strict_mode);
854 }
855 Handle<AccessorPair> accessor_pair;
856 if (accessor->GetAccessorPair(receiver, js_object, index)
857 .ToHandle(&accessor_pair)) {
858 return JSObject::SetElementWithCallback(receiver, accessor_pair, index,
859 value, js_object, strict_mode);
860 } else {
861 done = attrs != ABSENT;
862 }
863 }
864 }
865
866 if (!receiver->IsJSObject()) {
867 return WriteToReadOnlyElement(isolate, receiver, index, value, strict_mode);
868 }
869 Handle<JSObject> target = Handle<JSObject>::cast(receiver);
870 ElementsAccessor* accessor = target->GetElementsAccessor();
871 PropertyAttributes attrs = accessor->GetAttributes(receiver, target, index);
872 if ((attrs & READ_ONLY) != 0) {
873 return WriteToReadOnlyElement(isolate, receiver, index, value, strict_mode);
874 }
875 PropertyAttributes new_attrs = attrs != ABSENT ? attrs : NONE;
876 return JSObject::SetElement(target, index, value, new_attrs, strict_mode,
877 false);
878 }
879
880
805 Map* Object::GetRootMap(Isolate* isolate) { 881 Map* Object::GetRootMap(Isolate* isolate) {
806 DisallowHeapAllocation no_alloc; 882 DisallowHeapAllocation no_alloc;
807 if (IsSmi()) { 883 if (IsSmi()) {
808 Context* context = isolate->context()->native_context(); 884 Context* context = isolate->context()->native_context();
809 return context->number_function()->initial_map(); 885 return context->number_function()->initial_map();
810 } 886 }
811 887
812 HeapObject* heap_object = HeapObject::cast(this); 888 HeapObject* heap_object = HeapObject::cast(this);
813 889
814 // The object is either a number, a string, a boolean, 890 // The object is either a number, a string, a boolean,
(...skipping 2110 matching lines...) Expand 10 before | Expand all | Expand 10 after
2925 if (strict_mode != STRICT) return value; 3001 if (strict_mode != STRICT) return value;
2926 3002
2927 Handle<Object> args[] = {it->name(), it->GetReceiver()}; 3003 Handle<Object> args[] = {it->name(), it->GetReceiver()};
2928 THROW_NEW_ERROR(it->isolate(), 3004 THROW_NEW_ERROR(it->isolate(),
2929 NewTypeError("strict_read_only_property", 3005 NewTypeError("strict_read_only_property",
2930 HandleVector(args, arraysize(args))), 3006 HandleVector(args, arraysize(args))),
2931 Object); 3007 Object);
2932 } 3008 }
2933 3009
2934 3010
3011 MaybeHandle<Object> Object::WriteToReadOnlyElement(Isolate* isolate,
3012 Handle<Object> receiver,
3013 uint32_t index,
3014 Handle<Object> value,
3015 StrictMode strict_mode) {
3016 if (strict_mode != STRICT) return value;
3017
3018 Handle<Object> args[] = {isolate->factory()->NewNumberFromUint(index),
3019 receiver};
3020 THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property",
3021 HandleVector(args, arraysize(args))),
3022 Object);
3023 }
3024
3025
2935 MaybeHandle<Object> Object::SetDataProperty(LookupIterator* it, 3026 MaybeHandle<Object> Object::SetDataProperty(LookupIterator* it,
2936 Handle<Object> value) { 3027 Handle<Object> value) {
2937 // Proxies are handled on the WithHandler path. Other non-JSObjects cannot 3028 // Proxies are handled on the WithHandler path. Other non-JSObjects cannot
2938 // have own properties. 3029 // have own properties.
2939 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver()); 3030 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver());
2940 3031
2941 // Store on the holder which may be hidden behind the receiver. 3032 // Store on the holder which may be hidden behind the receiver.
2942 DCHECK(it->HolderIsReceiverOrHiddenPrototype()); 3033 DCHECK(it->HolderIsReceiverOrHiddenPrototype());
2943 3034
2944 // Old value for the observation change record. 3035 // Old value for the observation change record.
(...skipping 1127 matching lines...) Expand 10 before | Expand all | Expand 10 after
4072 Maybe<PropertyAttributes> JSObject::GetElementAttributeWithInterceptor( 4163 Maybe<PropertyAttributes> JSObject::GetElementAttributeWithInterceptor(
4073 Handle<JSObject> object, Handle<JSReceiver> receiver, uint32_t index, 4164 Handle<JSObject> object, Handle<JSReceiver> receiver, uint32_t index,
4074 bool check_prototype) { 4165 bool check_prototype) {
4075 Isolate* isolate = object->GetIsolate(); 4166 Isolate* isolate = object->GetIsolate();
4076 HandleScope scope(isolate); 4167 HandleScope scope(isolate);
4077 4168
4078 // Make sure that the top context does not change when doing 4169 // Make sure that the top context does not change when doing
4079 // callbacks or interceptor calls. 4170 // callbacks or interceptor calls.
4080 AssertNoContextChange ncc(isolate); 4171 AssertNoContextChange ncc(isolate);
4081 4172
4173 Maybe<PropertyAttributes> from_interceptor =
4174 GetElementAttributeFromInterceptor(object, receiver, index);
4175 if (!from_interceptor.has_value) return Maybe<PropertyAttributes>();
4176 if (from_interceptor.value != ABSENT) return maybe(from_interceptor.value);
4177
4178 return GetElementAttributeWithoutInterceptor(object, receiver, index,
4179 check_prototype);
4180 }
4181
4182
4183 Maybe<PropertyAttributes> JSObject::GetElementAttributeFromInterceptor(
4184 Handle<JSObject> object, Handle<Object> receiver, uint32_t index) {
4185 Isolate* isolate = object->GetIsolate();
4186 AssertNoContextChange ncc(isolate);
4187
4082 Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor()); 4188 Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor());
4083 PropertyCallbackArguments args( 4189 PropertyCallbackArguments args(
4084 isolate, interceptor->data(), *receiver, *object); 4190 isolate, interceptor->data(), *receiver, *object);
4085 if (!interceptor->query()->IsUndefined()) { 4191 if (!interceptor->query()->IsUndefined()) {
4086 v8::IndexedPropertyQueryCallback query = 4192 v8::IndexedPropertyQueryCallback query =
4087 v8::ToCData<v8::IndexedPropertyQueryCallback>(interceptor->query()); 4193 v8::ToCData<v8::IndexedPropertyQueryCallback>(interceptor->query());
4088 LOG(isolate, 4194 LOG(isolate,
4089 ApiIndexedPropertyAccess("interceptor-indexed-has", *object, index)); 4195 ApiIndexedPropertyAccess("interceptor-indexed-has", *object, index));
4090 v8::Handle<v8::Integer> result = args.Call(query, index); 4196 v8::Handle<v8::Integer> result = args.Call(query, index);
4091 if (!result.IsEmpty()) 4197 if (!result.IsEmpty())
4092 return maybe(static_cast<PropertyAttributes>(result->Int32Value())); 4198 return maybe(static_cast<PropertyAttributes>(result->Int32Value()));
4093 } else if (!interceptor->getter()->IsUndefined()) { 4199 } else if (!interceptor->getter()->IsUndefined()) {
4094 v8::IndexedPropertyGetterCallback getter = 4200 v8::IndexedPropertyGetterCallback getter =
4095 v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter()); 4201 v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter());
4096 LOG(isolate, 4202 LOG(isolate,
4097 ApiIndexedPropertyAccess( 4203 ApiIndexedPropertyAccess(
4098 "interceptor-indexed-get-has", *object, index)); 4204 "interceptor-indexed-get-has", *object, index));
4099 v8::Handle<v8::Value> result = args.Call(getter, index); 4205 v8::Handle<v8::Value> result = args.Call(getter, index);
4100 if (!result.IsEmpty()) return maybe(NONE); 4206 if (!result.IsEmpty()) return maybe(NONE);
4101 } 4207 }
4102 4208 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Maybe<PropertyAttributes>());
4103 return GetElementAttributeWithoutInterceptor( 4209 return maybe(ABSENT);
4104 object, receiver, index, check_prototype);
4105 } 4210 }
4106 4211
4107 4212
4108 Maybe<PropertyAttributes> JSObject::GetElementAttributeWithoutInterceptor( 4213 Maybe<PropertyAttributes> JSObject::GetElementAttributeWithoutInterceptor(
4109 Handle<JSObject> object, Handle<JSReceiver> receiver, uint32_t index, 4214 Handle<JSObject> object, Handle<JSReceiver> receiver, uint32_t index,
4110 bool check_prototype) { 4215 bool check_prototype) {
4111 PropertyAttributes attr = object->GetElementsAccessor()->GetAttributes( 4216 PropertyAttributes attr = object->GetElementsAccessor()->GetAttributes(
4112 receiver, object, index); 4217 receiver, object, index);
4113 if (attr != ABSENT) return maybe(attr); 4218 if (attr != ABSENT) return maybe(attr);
4114 4219
(...skipping 7749 matching lines...) Expand 10 before | Expand all | Expand 10 after
11864 if (structure->IsDeclaredAccessorInfo()) { 11969 if (structure->IsDeclaredAccessorInfo()) {
11865 return GetDeclaredAccessorProperty( 11970 return GetDeclaredAccessorProperty(
11866 receiver, Handle<DeclaredAccessorInfo>::cast(structure), isolate); 11971 receiver, Handle<DeclaredAccessorInfo>::cast(structure), isolate);
11867 } 11972 }
11868 11973
11869 UNREACHABLE(); 11974 UNREACHABLE();
11870 return MaybeHandle<Object>(); 11975 return MaybeHandle<Object>();
11871 } 11976 }
11872 11977
11873 11978
11874 MaybeHandle<Object> JSObject::SetElementWithCallback(Handle<JSObject> object, 11979 MaybeHandle<Object> JSObject::SetElementWithCallback(
11875 Handle<Object> structure, 11980 Handle<Object> object, Handle<Object> structure, uint32_t index,
11876 uint32_t index, 11981 Handle<Object> value, Handle<JSObject> holder, StrictMode strict_mode) {
11877 Handle<Object> value, 11982 Isolate* isolate = holder->GetIsolate();
11878 Handle<JSObject> holder,
11879 StrictMode strict_mode) {
11880 Isolate* isolate = object->GetIsolate();
11881 11983
11882 // We should never get here to initialize a const with the hole 11984 // We should never get here to initialize a const with the hole
11883 // value since a const declaration would conflict with the setter. 11985 // value since a const declaration would conflict with the setter.
11884 DCHECK(!value->IsTheHole()); 11986 DCHECK(!value->IsTheHole());
11885 DCHECK(!structure->IsForeign()); 11987 DCHECK(!structure->IsForeign());
11886 if (structure->IsExecutableAccessorInfo()) { 11988 if (structure->IsExecutableAccessorInfo()) {
11887 // api style callbacks 11989 // api style callbacks
11888 Handle<ExecutableAccessorInfo> data = 11990 Handle<ExecutableAccessorInfo> data =
11889 Handle<ExecutableAccessorInfo>::cast(structure); 11991 Handle<ExecutableAccessorInfo>::cast(structure);
11890 Object* call_obj = data->setter(); 11992 Object* call_obj = data->setter();
11891 v8::AccessorNameSetterCallback call_fun = 11993 v8::AccessorNameSetterCallback call_fun =
11892 v8::ToCData<v8::AccessorNameSetterCallback>(call_obj); 11994 v8::ToCData<v8::AccessorNameSetterCallback>(call_obj);
11893 if (call_fun == NULL) return value; 11995 if (call_fun == NULL) return value;
11894 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); 11996 Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
11895 Handle<String> key(isolate->factory()->NumberToString(number)); 11997 Handle<String> key(isolate->factory()->NumberToString(number));
11896 LOG(isolate, ApiNamedPropertyAccess("store", *object, *key)); 11998 LOG(isolate, ApiNamedPropertyAccess("store", *holder, *key));
11897 PropertyCallbackArguments 11999 PropertyCallbackArguments
11898 args(isolate, data->data(), *object, *holder); 12000 args(isolate, data->data(), *object, *holder);
11899 args.Call(call_fun, 12001 args.Call(call_fun,
11900 v8::Utils::ToLocal(key), 12002 v8::Utils::ToLocal(key),
11901 v8::Utils::ToLocal(value)); 12003 v8::Utils::ToLocal(value));
11902 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); 12004 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
11903 return value; 12005 return value;
11904 } 12006 }
11905 12007
11906 if (structure->IsAccessorPair()) { 12008 if (structure->IsAccessorPair()) {
(...skipping 4506 matching lines...) Expand 10 before | Expand all | Expand 10 after
16413 Handle<DependentCode> codes = 16515 Handle<DependentCode> codes =
16414 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), 16516 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()),
16415 DependentCode::kPropertyCellChangedGroup, 16517 DependentCode::kPropertyCellChangedGroup,
16416 info->object_wrapper()); 16518 info->object_wrapper());
16417 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); 16519 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes);
16418 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( 16520 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add(
16419 cell, info->zone()); 16521 cell, info->zone());
16420 } 16522 }
16421 16523
16422 } } // namespace v8::internal 16524 } } // 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