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

Side by Side Diff: src/objects.cc

Issue 934463003: super.property store (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Cleanup error messaging a bit Created 5 years, 10 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
« no previous file with comments | « src/objects.h ('k') | test/mjsunit/harmony/super.js » ('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 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 MaybeHandle<Object> Object::GetPropertyWithAccessor(Handle<Object> receiver, 284 MaybeHandle<Object> Object::GetPropertyWithAccessor(Handle<Object> receiver,
285 Handle<Name> name, 285 Handle<Name> name,
286 Handle<JSObject> holder, 286 Handle<JSObject> holder,
287 Handle<Object> structure) { 287 Handle<Object> structure) {
288 Isolate* isolate = name->GetIsolate(); 288 Isolate* isolate = name->GetIsolate();
289 DCHECK(!structure->IsForeign()); 289 DCHECK(!structure->IsForeign());
290 // api style callbacks. 290 // api style callbacks.
291 if (structure->IsAccessorInfo()) { 291 if (structure->IsAccessorInfo()) {
292 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(structure); 292 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(structure);
293 if (!info->IsCompatibleReceiver(*receiver)) { 293 if (!info->IsCompatibleReceiver(*receiver)) {
294 Handle<Object> args[2] = { name, receiver }; 294 Handle<Object> args[] = {name, receiver};
295 THROW_NEW_ERROR(isolate, 295 THROW_NEW_ERROR(isolate,
296 NewTypeError("incompatible_method_receiver", 296 NewTypeError("incompatible_method_receiver",
297 HandleVector(args, arraysize(args))), 297 HandleVector(args, arraysize(args))),
298 Object); 298 Object);
299 } 299 }
300 300
301 Handle<ExecutableAccessorInfo> data = 301 Handle<ExecutableAccessorInfo> data =
302 Handle<ExecutableAccessorInfo>::cast(structure); 302 Handle<ExecutableAccessorInfo>::cast(structure);
303 v8::AccessorNameGetterCallback call_fun = 303 v8::AccessorNameGetterCallback call_fun =
304 v8::ToCData<v8::AccessorNameGetterCallback>(data->getter()); 304 v8::ToCData<v8::AccessorNameGetterCallback>(data->getter());
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 349
350 // We should never get here to initialize a const with the hole 350 // We should never get here to initialize a const with the hole
351 // value since a const declaration would conflict with the setter. 351 // value since a const declaration would conflict with the setter.
352 DCHECK(!structure->IsForeign()); 352 DCHECK(!structure->IsForeign());
353 if (structure->IsExecutableAccessorInfo()) { 353 if (structure->IsExecutableAccessorInfo()) {
354 // Don't call executable accessor setters with non-JSObject receivers. 354 // Don't call executable accessor setters with non-JSObject receivers.
355 if (!receiver->IsJSObject()) return value; 355 if (!receiver->IsJSObject()) return value;
356 // api style callbacks 356 // api style callbacks
357 ExecutableAccessorInfo* info = ExecutableAccessorInfo::cast(*structure); 357 ExecutableAccessorInfo* info = ExecutableAccessorInfo::cast(*structure);
358 if (!info->IsCompatibleReceiver(*receiver)) { 358 if (!info->IsCompatibleReceiver(*receiver)) {
359 Handle<Object> args[2] = { name, receiver }; 359 Handle<Object> args[] = {name, receiver};
360 THROW_NEW_ERROR(isolate, 360 THROW_NEW_ERROR(isolate,
361 NewTypeError("incompatible_method_receiver", 361 NewTypeError("incompatible_method_receiver",
362 HandleVector(args, arraysize(args))), 362 HandleVector(args, arraysize(args))),
363 Object); 363 Object);
364 } 364 }
365 Object* call_obj = info->setter(); 365 Object* call_obj = info->setter();
366 v8::AccessorNameSetterCallback call_fun = 366 v8::AccessorNameSetterCallback call_fun =
367 v8::ToCData<v8::AccessorNameSetterCallback>(call_obj); 367 v8::ToCData<v8::AccessorNameSetterCallback>(call_obj);
368 if (call_fun == NULL) return value; 368 if (call_fun == NULL) return value;
369 LOG(isolate, ApiNamedPropertyAccess("store", *holder, *name)); 369 LOG(isolate, ApiNamedPropertyAccess("store", *holder, *name));
370 PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder); 370 PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder);
371 args.Call(call_fun, 371 args.Call(call_fun,
372 v8::Utils::ToLocal(name), 372 v8::Utils::ToLocal(name),
373 v8::Utils::ToLocal(value)); 373 v8::Utils::ToLocal(value));
374 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); 374 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
375 return value; 375 return value;
376 } 376 }
377 377
378 if (structure->IsAccessorPair()) { 378 if (structure->IsAccessorPair()) {
379 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate); 379 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate);
380 if (setter->IsSpecFunction()) { 380 if (setter->IsSpecFunction()) {
381 // TODO(rossberg): nicer would be to cast to some JSCallable here... 381 // TODO(rossberg): nicer would be to cast to some JSCallable here...
382 return SetPropertyWithDefinedSetter( 382 return SetPropertyWithDefinedSetter(
383 receiver, Handle<JSReceiver>::cast(setter), value); 383 receiver, Handle<JSReceiver>::cast(setter), value);
384 } else { 384 } else {
385 if (is_sloppy(language_mode)) return value; 385 if (is_sloppy(language_mode)) return value;
386 Handle<Object> args[2] = { name, holder }; 386 Handle<Object> args[] = {name, holder};
387 THROW_NEW_ERROR( 387 THROW_NEW_ERROR(isolate,
388 isolate, NewTypeError("no_setter_in_callback", HandleVector(args, 2)), 388 NewTypeError("no_setter_in_callback",
389 Object); 389 HandleVector(args, arraysize(args))),
390 Object);
390 } 391 }
391 } 392 }
392 393
393 UNREACHABLE(); 394 UNREACHABLE();
394 return MaybeHandle<Object>(); 395 return MaybeHandle<Object>();
395 } 396 }
396 397
397 398
398 MaybeHandle<Object> Object::GetPropertyWithDefinedGetter( 399 MaybeHandle<Object> Object::GetPropertyWithDefinedGetter(
399 Handle<Object> receiver, 400 Handle<Object> receiver,
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
748 } 749 }
749 } 750 }
750 751
751 if (!receiver->IsJSObject()) { 752 if (!receiver->IsJSObject()) {
752 return WriteToReadOnlyElement(isolate, receiver, index, value, 753 return WriteToReadOnlyElement(isolate, receiver, index, value,
753 language_mode); 754 language_mode);
754 } 755 }
755 Handle<JSObject> target = Handle<JSObject>::cast(receiver); 756 Handle<JSObject> target = Handle<JSObject>::cast(receiver);
756 ElementsAccessor* accessor = target->GetElementsAccessor(); 757 ElementsAccessor* accessor = target->GetElementsAccessor();
757 PropertyAttributes attrs = accessor->GetAttributes(receiver, target, index); 758 PropertyAttributes attrs = accessor->GetAttributes(receiver, target, index);
758 if ((attrs & READ_ONLY) != 0) { 759 if (attrs == ABSENT) {
759 return WriteToReadOnlyElement(isolate, receiver, index, value, 760 return JSObject::SetElement(target, index, value, NONE, language_mode,
760 language_mode); 761 false);
761 } 762 }
762 PropertyAttributes new_attrs = attrs != ABSENT ? attrs : NONE; 763 return JSObject::SetElement(target, index, value, attrs, language_mode, false,
763 return JSObject::SetElement(target, index, value, new_attrs, language_mode, 764 DEFINE_PROPERTY);
764 false);
765 } 765 }
766 766
767 767
768 Map* Object::GetRootMap(Isolate* isolate) { 768 Map* Object::GetRootMap(Isolate* isolate) {
769 DisallowHeapAllocation no_alloc; 769 DisallowHeapAllocation no_alloc;
770 if (IsSmi()) { 770 if (IsSmi()) {
771 Context* context = isolate->context()->native_context(); 771 Context* context = isolate->context()->native_context();
772 return context->number_function()->initial_map(); 772 return context->number_function()->initial_map();
773 } 773 }
774 774
(...skipping 2355 matching lines...) Expand 10 before | Expand all | Expand 10 after
3130 break; 3130 break;
3131 } 3131 }
3132 3132
3133 if (done) break; 3133 if (done) break;
3134 } 3134 }
3135 3135
3136 // If the receiver is the JSGlobalObject, the store was contextual. In case 3136 // If the receiver is the JSGlobalObject, the store was contextual. In case
3137 // the property did not exist yet on the global object itself, we have to 3137 // the property did not exist yet on the global object itself, we have to
3138 // throw a reference error in strict mode. 3138 // throw a reference error in strict mode.
3139 if (it->GetReceiver()->IsJSGlobalObject() && is_strict(language_mode)) { 3139 if (it->GetReceiver()->IsJSGlobalObject() && is_strict(language_mode)) {
3140 Handle<Object> args[1] = {it->name()}; 3140 Handle<Object> args[] = {it->name()};
3141 THROW_NEW_ERROR(it->isolate(), 3141 THROW_NEW_ERROR(
3142 NewReferenceError("not_defined", HandleVector(args, 1)), 3142 it->isolate(),
3143 Object); 3143 NewReferenceError("not_defined", HandleVector(args, arraysize(args))),
3144 Object);
3144 } 3145 }
3145 3146
3147 // super.property = value
3148 // No property was found starting from the prototype of [[HomeObject]].
3146 if (data_store_mode == SUPER_PROPERTY) { 3149 if (data_store_mode == SUPER_PROPERTY) {
Toon Verwaest 2015/02/18 13:54:08 Given that this flag just switches half of the imp
3147 LookupIterator own_lookup(it->GetReceiver(), it->name(), 3150 LookupIterator own_lookup(it->GetReceiver(), it->name(),
3148 LookupIterator::OWN); 3151 LookupIterator::OWN);
3152 if (!own_lookup.IsFound()) {
3153 return AddDataProperty(&own_lookup, value, NONE, language_mode,
3154 store_mode);
3155 }
3149 3156
3150 return JSObject::SetProperty(&own_lookup, value, language_mode, store_mode, 3157 PropertyDetails details = own_lookup.property_details();
3151 NORMAL_PROPERTY); 3158
3159 // Otherwise reconfigure property with descriptor {value: value}.
3160 if (details.IsConfigurable()) {
3161 return JSObject::SetOwnPropertyIgnoreAttributes(
3162 Handle<JSObject>::cast(it->GetReceiver()), it->name(), value,
3163 details.attributes());
3164 }
3165
3166 if (details.IsReadOnly()) {
3167 return WriteToReadOnlyProperty(&own_lookup, value, language_mode);
3168 }
3169
3170 if (details.kind() == kAccessor) {
3171 if (is_sloppy(language_mode)) return value;
3172 Handle<Object> args[] = {it->name()};
3173 THROW_NEW_ERROR(it->isolate(),
3174 NewTypeError("redefine_disallowed",
arv (Not doing code reviews) 2015/02/18 01:00:04 Maybe I should just use strict_read_only_property
adamk 2015/02/18 01:26:05 Or just make a new RedefineNonconfigurableProperty
arv (Not doing code reviews) 2015/02/18 17:46:14 Done.
3175 HandleVector(args, arraysize(args))),
3176 Object);
3177 }
3178
3179 return SetDataProperty(&own_lookup, value);
3152 } 3180 }
3153 3181
3154 return AddDataProperty(it, value, NONE, language_mode, store_mode); 3182 return AddDataProperty(it, value, NONE, language_mode, store_mode);
3155 } 3183 }
3156 3184
3157 3185
3158 MaybeHandle<Object> Object::WriteToReadOnlyProperty( 3186 MaybeHandle<Object> Object::WriteToReadOnlyProperty(
3159 LookupIterator* it, Handle<Object> value, LanguageMode language_mode) { 3187 LookupIterator* it, Handle<Object> value, LanguageMode language_mode) {
3188 return WriteToReadOnlyProperty(it->isolate(), it->GetReceiver(), it->name(),
3189 value, language_mode);
3190 }
3191
3192
3193 MaybeHandle<Object> Object::WriteToReadOnlyProperty(
3194 Isolate* isolate, Handle<Object> receiver, Handle<Object> name,
3195 Handle<Object> value, LanguageMode language_mode) {
3160 if (is_sloppy(language_mode)) return value; 3196 if (is_sloppy(language_mode)) return value;
3161 3197 Handle<Object> args[] = {name, receiver};
3162 Handle<Object> args[] = {it->name(), it->GetReceiver()}; 3198 THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property",
3163 THROW_NEW_ERROR(it->isolate(), 3199 HandleVector(args, arraysize(args))),
3164 NewTypeError("strict_read_only_property",
3165 HandleVector(args, arraysize(args))),
3166 Object); 3200 Object);
3167 } 3201 }
3168 3202
3169 3203
3170 MaybeHandle<Object> Object::WriteToReadOnlyElement(Isolate* isolate, 3204 MaybeHandle<Object> Object::WriteToReadOnlyElement(Isolate* isolate,
3171 Handle<Object> receiver, 3205 Handle<Object> receiver,
3172 uint32_t index, 3206 uint32_t index,
3173 Handle<Object> value, 3207 Handle<Object> value,
3174 LanguageMode language_mode) { 3208 LanguageMode language_mode) {
3175 if (is_sloppy(language_mode)) return value; 3209 return WriteToReadOnlyProperty(isolate, receiver,
3176 3210 isolate->factory()->NewNumberFromUint(index),
3177 Handle<Object> args[] = {isolate->factory()->NewNumberFromUint(index), 3211 value, language_mode);
3178 receiver};
3179 THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property",
3180 HandleVector(args, arraysize(args))),
3181 Object);
3182 } 3212 }
3183 3213
3184 3214
3185 MaybeHandle<Object> Object::SetDataProperty(LookupIterator* it, 3215 MaybeHandle<Object> Object::SetDataProperty(LookupIterator* it,
3186 Handle<Object> value) { 3216 Handle<Object> value) {
3187 // Proxies are handled on the WithHandler path. Other non-JSObjects cannot 3217 // Proxies are handled on the WithHandler path. Other non-JSObjects cannot
3188 // have own properties. 3218 // have own properties.
3189 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver()); 3219 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver());
3190 3220
3191 // Store on the holder which may be hidden behind the receiver. 3221 // Store on the holder which may be hidden behind the receiver.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
3238 // If the receiver is Indexed Exotic object (currently only typed arrays), 3268 // If the receiver is Indexed Exotic object (currently only typed arrays),
3239 // disallow adding properties with numeric names. 3269 // disallow adding properties with numeric names.
3240 if (it->IsSpecialNumericIndex()) return value; 3270 if (it->IsSpecialNumericIndex()) return value;
3241 3271
3242 // Possibly migrate to the most up-to-date map that will be able to store 3272 // Possibly migrate to the most up-to-date map that will be able to store
3243 // |value| under it->name() with |attributes|. 3273 // |value| under it->name() with |attributes|.
3244 it->PrepareTransitionToDataProperty(value, attributes, store_mode); 3274 it->PrepareTransitionToDataProperty(value, attributes, store_mode);
3245 if (it->state() != LookupIterator::TRANSITION) { 3275 if (it->state() != LookupIterator::TRANSITION) {
3246 if (is_sloppy(language_mode)) return value; 3276 if (is_sloppy(language_mode)) return value;
3247 3277
3248 Handle<Object> args[1] = {it->name()}; 3278 Handle<Object> args[] = {it->name()};
3249 THROW_NEW_ERROR(it->isolate(), 3279 THROW_NEW_ERROR(it->isolate(),
3250 NewTypeError("object_not_extensible", 3280 NewTypeError("object_not_extensible",
3251 HandleVector(args, arraysize(args))), 3281 HandleVector(args, arraysize(args))),
3252 Object); 3282 Object);
3253 } 3283 }
3254 it->ApplyTransitionToDataProperty(); 3284 it->ApplyTransitionToDataProperty();
3255 3285
3256 // TODO(verwaest): Encapsulate dictionary handling better. 3286 // TODO(verwaest): Encapsulate dictionary handling better.
3257 if (receiver->map()->is_dictionary_map()) { 3287 if (receiver->map()->is_dictionary_map()) {
3258 // TODO(verwaest): Probably should ensure this is done beforehand. 3288 // TODO(verwaest): Probably should ensure this is done beforehand.
(...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after
3784 Object::GetProperty(desc, hasWritable_name).ToHandleChecked(); 3814 Object::GetProperty(desc, hasWritable_name).ToHandleChecked();
3785 DCHECK(hasWritable->IsBoolean()); 3815 DCHECK(hasWritable->IsBoolean());
3786 if (hasWritable->IsTrue()) { 3816 if (hasWritable->IsTrue()) {
3787 Handle<String> writable_name = isolate->factory()->InternalizeOneByteString( 3817 Handle<String> writable_name = isolate->factory()->InternalizeOneByteString(
3788 STATIC_CHAR_VECTOR("writable_")); 3818 STATIC_CHAR_VECTOR("writable_"));
3789 Handle<Object> writable = 3819 Handle<Object> writable =
3790 Object::GetProperty(desc, writable_name).ToHandleChecked(); 3820 Object::GetProperty(desc, writable_name).ToHandleChecked();
3791 DCHECK(writable->IsBoolean()); 3821 DCHECK(writable->IsBoolean());
3792 *done = writable->IsFalse(); 3822 *done = writable->IsFalse();
3793 if (!*done) return isolate->factory()->the_hole_value(); 3823 if (!*done) return isolate->factory()->the_hole_value();
3794 if (is_sloppy(language_mode)) return value; 3824 return WriteToReadOnlyProperty(isolate, receiver, name, value,
3795 Handle<Object> args[] = { name, receiver }; 3825 language_mode);
3796 THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property",
3797 HandleVector(args, arraysize(args))),
3798 Object);
3799 } 3826 }
3800 3827
3801 // We have an AccessorDescriptor. 3828 // We have an AccessorDescriptor.
3802 Handle<String> set_name = 3829 Handle<String> set_name =
3803 isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("set_")); 3830 isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("set_"));
3804 Handle<Object> setter = Object::GetProperty(desc, set_name).ToHandleChecked(); 3831 Handle<Object> setter = Object::GetProperty(desc, set_name).ToHandleChecked();
3805 if (!setter->IsUndefined()) { 3832 if (!setter->IsUndefined()) {
3806 // TODO(rossberg): nicer would be to cast to some JSCallable here... 3833 // TODO(rossberg): nicer would be to cast to some JSCallable here...
3807 return SetPropertyWithDefinedSetter( 3834 return SetPropertyWithDefinedSetter(
3808 receiver, Handle<JSReceiver>::cast(setter), value); 3835 receiver, Handle<JSReceiver>::cast(setter), value);
(...skipping 1338 matching lines...) Expand 10 before | Expand all | Expand 10 after
5147 !isolate->MayIndexedAccess(object, index, v8::ACCESS_DELETE)) { 5174 !isolate->MayIndexedAccess(object, index, v8::ACCESS_DELETE)) {
5148 isolate->ReportFailedAccessCheck(object, v8::ACCESS_DELETE); 5175 isolate->ReportFailedAccessCheck(object, v8::ACCESS_DELETE);
5149 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); 5176 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
5150 return factory->false_value(); 5177 return factory->false_value();
5151 } 5178 }
5152 5179
5153 if (object->IsStringObjectWithCharacterAt(index)) { 5180 if (object->IsStringObjectWithCharacterAt(index)) {
5154 if (is_strict(language_mode)) { 5181 if (is_strict(language_mode)) {
5155 // Deleting a non-configurable property in strict mode. 5182 // Deleting a non-configurable property in strict mode.
5156 Handle<Object> name = factory->NewNumberFromUint(index); 5183 Handle<Object> name = factory->NewNumberFromUint(index);
5157 Handle<Object> args[2] = { name, object }; 5184 Handle<Object> args[] = {name, object};
5158 THROW_NEW_ERROR(isolate, NewTypeError("strict_delete_property", 5185 THROW_NEW_ERROR(isolate,
5159 HandleVector(args, 2)), 5186 NewTypeError("strict_delete_property",
5187 HandleVector(args, arraysize(args))),
5160 Object); 5188 Object);
5161 } 5189 }
5162 return factory->false_value(); 5190 return factory->false_value();
5163 } 5191 }
5164 5192
5165 if (object->IsJSGlobalProxy()) { 5193 if (object->IsJSGlobalProxy()) {
5166 PrototypeIterator iter(isolate, object); 5194 PrototypeIterator iter(isolate, object);
5167 if (iter.IsAtEnd()) return factory->false_value(); 5195 if (iter.IsAtEnd()) return factory->false_value();
5168 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); 5196 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
5169 return DeleteElement( 5197 return DeleteElement(
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
5280 } 5308 }
5281 case LookupIterator::DATA: 5309 case LookupIterator::DATA:
5282 if (is_observed) { 5310 if (is_observed) {
5283 old_value = it.GetDataValue(); 5311 old_value = it.GetDataValue();
5284 } 5312 }
5285 // Fall through. 5313 // Fall through.
5286 case LookupIterator::ACCESSOR: { 5314 case LookupIterator::ACCESSOR: {
5287 if (!it.IsConfigurable()) { 5315 if (!it.IsConfigurable()) {
5288 // Fail if the property is not configurable. 5316 // Fail if the property is not configurable.
5289 if (is_strict(language_mode)) { 5317 if (is_strict(language_mode)) {
5290 Handle<Object> args[2] = {name, object}; 5318 Handle<Object> args[] = {name, object};
5291 THROW_NEW_ERROR(it.isolate(), 5319 THROW_NEW_ERROR(it.isolate(),
5292 NewTypeError("strict_delete_property", 5320 NewTypeError("strict_delete_property",
5293 HandleVector(args, arraysize(args))), 5321 HandleVector(args, arraysize(args))),
5294 Object); 5322 Object);
5295 } 5323 }
5296 return it.isolate()->factory()->false_value(); 5324 return it.isolate()->factory()->false_value();
5297 } 5325 }
5298 5326
5299 PropertyNormalizationMode mode = object->map()->is_prototype_map() 5327 PropertyNormalizationMode mode = object->map()->is_prototype_map()
5300 ? KEEP_INOBJECT_PROPERTIES 5328 ? KEEP_INOBJECT_PROPERTIES
(...skipping 7337 matching lines...) Expand 10 before | Expand all | Expand 10 after
12638 12666
12639 if (structure->IsAccessorPair()) { 12667 if (structure->IsAccessorPair()) {
12640 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate); 12668 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate);
12641 if (setter->IsSpecFunction()) { 12669 if (setter->IsSpecFunction()) {
12642 // TODO(rossberg): nicer would be to cast to some JSCallable here... 12670 // TODO(rossberg): nicer would be to cast to some JSCallable here...
12643 return SetPropertyWithDefinedSetter( 12671 return SetPropertyWithDefinedSetter(
12644 object, Handle<JSReceiver>::cast(setter), value); 12672 object, Handle<JSReceiver>::cast(setter), value);
12645 } else { 12673 } else {
12646 if (is_sloppy(language_mode)) return value; 12674 if (is_sloppy(language_mode)) return value;
12647 Handle<Object> key(isolate->factory()->NewNumberFromUint(index)); 12675 Handle<Object> key(isolate->factory()->NewNumberFromUint(index));
12648 Handle<Object> args[2] = { key, holder }; 12676 Handle<Object> args[] = {key, holder};
12649 THROW_NEW_ERROR( 12677 THROW_NEW_ERROR(isolate,
12650 isolate, NewTypeError("no_setter_in_callback", HandleVector(args, 2)), 12678 NewTypeError("no_setter_in_callback",
12651 Object); 12679 HandleVector(args, arraysize(args))),
12680 Object);
12652 } 12681 }
12653 } 12682 }
12654 12683
12655 UNREACHABLE(); 12684 UNREACHABLE();
12656 return MaybeHandle<Object>(); 12685 return MaybeHandle<Object>();
12657 } 12686 }
12658 12687
12659 12688
12660 bool JSObject::HasFastArgumentsElements() { 12689 bool JSObject::HasFastArgumentsElements() {
12661 Heap* heap = GetHeap(); 12690 Heap* heap = GetHeap();
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
12828 ? SeededNumberDictionary::cast(elements->get(1)) 12857 ? SeededNumberDictionary::cast(elements->get(1))
12829 : SeededNumberDictionary::cast(*elements)); 12858 : SeededNumberDictionary::cast(*elements));
12830 12859
12831 int entry = dictionary->FindEntry(index); 12860 int entry = dictionary->FindEntry(index);
12832 if (entry != SeededNumberDictionary::kNotFound) { 12861 if (entry != SeededNumberDictionary::kNotFound) {
12833 Handle<Object> element(dictionary->ValueAt(entry), isolate); 12862 Handle<Object> element(dictionary->ValueAt(entry), isolate);
12834 PropertyDetails details = dictionary->DetailsAt(entry); 12863 PropertyDetails details = dictionary->DetailsAt(entry);
12835 if (details.type() == ACCESSOR_CONSTANT && set_mode == SET_PROPERTY) { 12864 if (details.type() == ACCESSOR_CONSTANT && set_mode == SET_PROPERTY) {
12836 return SetElementWithCallback(object, element, index, value, object, 12865 return SetElementWithCallback(object, element, index, value, object,
12837 language_mode); 12866 language_mode);
12867 } else if (set_mode == DEFINE_PROPERTY && !details.IsConfigurable() &&
12868 details.kind() == kAccessor) {
12869 if (is_sloppy(language_mode)) {
12870 return isolate->factory()->undefined_value();
12871 }
12872 Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
12873 Handle<Object> args[] = {number};
12874 THROW_NEW_ERROR(isolate,
12875 NewTypeError("redefine_disallowed",
12876 HandleVector(args, arraysize(args))),
12877 Object);
12878
12879 } else if ((set_mode == DEFINE_PROPERTY && !details.IsConfigurable() &&
12880 details.IsReadOnly() && details.kind() == kData) ||
adamk 2015/02/18 01:26:05 I take it we don't need this !IsTheHole() check in
Toon Verwaest 2015/02/18 13:54:08 details.kind() == kData isn't necessary since DEFI
Toon Verwaest 2015/02/18 13:54:08 We could add a DCHECK(element->IsTheHole()) inside
arv (Not doing code reviews) 2015/02/18 17:46:14 Done.
arv (Not doing code reviews) 2015/02/18 17:46:14 Done.
12881 (set_mode == SET_PROPERTY && details.IsReadOnly() &&
12882 !element->IsTheHole())) {
12883 // If a value has not been initialized we allow writing to it even if it
12884 // is read-only (a declared const that has not been initialized).
12885 return WriteToReadOnlyProperty(
12886 isolate, object, isolate->factory()->NewNumberFromUint(index),
12887 isolate->factory()->undefined_value(), language_mode);
12838 } else { 12888 } else {
12839 dictionary->UpdateMaxNumberKey(index); 12889 dictionary->UpdateMaxNumberKey(index);
12840 // If a value has not been initialized we allow writing to it even if it
12841 // is read-only (a declared const that has not been initialized). If a
12842 // value is being defined we skip attribute checks completely.
12843 if (set_mode == DEFINE_PROPERTY) { 12890 if (set_mode == DEFINE_PROPERTY) {
12844 details = PropertyDetails(attributes, DATA, details.dictionary_index()); 12891 details = PropertyDetails(attributes, DATA, details.dictionary_index());
12845 dictionary->DetailsAtPut(entry, details); 12892 dictionary->DetailsAtPut(entry, details);
12846 } else if (details.IsReadOnly() && !element->IsTheHole()) {
12847 if (is_sloppy(language_mode)) {
12848 return isolate->factory()->undefined_value();
12849 } else {
12850 Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
12851 Handle<Object> args[2] = { number, object };
12852 THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property",
12853 HandleVector(args, 2)),
12854 Object);
12855 }
12856 } 12893 }
12857 // Elements of the arguments object in slow mode might be slow aliases. 12894 // Elements of the arguments object in slow mode might be slow aliases.
12858 if (is_arguments && element->IsAliasedArgumentsEntry()) { 12895 if (is_arguments && element->IsAliasedArgumentsEntry()) {
12859 Handle<AliasedArgumentsEntry> entry = 12896 Handle<AliasedArgumentsEntry> entry =
12860 Handle<AliasedArgumentsEntry>::cast(element); 12897 Handle<AliasedArgumentsEntry>::cast(element);
12861 Handle<Context> context(Context::cast(elements->get(0))); 12898 Handle<Context> context(Context::cast(elements->get(0)));
12862 int context_index = entry->aliased_context_slot(); 12899 int context_index = entry->aliased_context_slot();
12863 DCHECK(!context->get(context_index)->IsTheHole()); 12900 DCHECK(!context->get(context_index)->IsTheHole());
12864 context->set(context_index, *value); 12901 context->set(context_index, *value);
12865 // For elements that are still writable we keep slow aliasing. 12902 // For elements that are still writable we keep slow aliasing.
(...skipping 12 matching lines...) Expand all
12878 } 12915 }
12879 12916
12880 // When we set the is_extensible flag to false we always force the 12917 // When we set the is_extensible flag to false we always force the
12881 // element into dictionary mode (and force them to stay there). 12918 // element into dictionary mode (and force them to stay there).
12882 if (!object->map()->is_extensible()) { 12919 if (!object->map()->is_extensible()) {
12883 if (is_sloppy(language_mode)) { 12920 if (is_sloppy(language_mode)) {
12884 return isolate->factory()->undefined_value(); 12921 return isolate->factory()->undefined_value();
12885 } else { 12922 } else {
12886 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); 12923 Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
12887 Handle<String> name = isolate->factory()->NumberToString(number); 12924 Handle<String> name = isolate->factory()->NumberToString(number);
12888 Handle<Object> args[1] = { name }; 12925 Handle<Object> args[] = {name};
12889 THROW_NEW_ERROR(isolate, NewTypeError("object_not_extensible", 12926 THROW_NEW_ERROR(isolate,
12890 HandleVector(args, 1)), 12927 NewTypeError("object_not_extensible",
12928 HandleVector(args, arraysize(args))),
12891 Object); 12929 Object);
12892 } 12930 }
12893 } 12931 }
12894 12932
12895 PropertyDetails details(attributes, DATA, 0); 12933 PropertyDetails details(attributes, DATA, 0);
12896 Handle<SeededNumberDictionary> new_dictionary = 12934 Handle<SeededNumberDictionary> new_dictionary =
12897 SeededNumberDictionary::AddNumberEntry(dictionary, index, value, 12935 SeededNumberDictionary::AddNumberEntry(dictionary, index, value,
12898 details); 12936 details);
12899 if (*dictionary != *new_dictionary) { 12937 if (*dictionary != *new_dictionary) {
12900 if (is_arguments) { 12938 if (is_arguments) {
(...skipping 689 matching lines...) Expand 10 before | Expand all | Expand 10 after
13590 uint32_t length = 0; 13628 uint32_t length = 0;
13591 CHECK(array->length()->ToArrayIndex(&length)); 13629 CHECK(array->length()->ToArrayIndex(&length));
13592 if (length <= index) return HasReadOnlyLength(array); 13630 if (length <= index) return HasReadOnlyLength(array);
13593 return false; 13631 return false;
13594 } 13632 }
13595 13633
13596 13634
13597 MaybeHandle<Object> JSArray::ReadOnlyLengthError(Handle<JSArray> array) { 13635 MaybeHandle<Object> JSArray::ReadOnlyLengthError(Handle<JSArray> array) {
13598 Isolate* isolate = array->GetIsolate(); 13636 Isolate* isolate = array->GetIsolate();
13599 Handle<Name> length = isolate->factory()->length_string(); 13637 Handle<Name> length = isolate->factory()->length_string();
13600 Handle<Object> args[2] = { length, array }; 13638 Handle<Object> args[] = {length, array};
13601 THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property", 13639 THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property",
13602 HandleVector(args, arraysize(args))), 13640 HandleVector(args, arraysize(args))),
13603 Object); 13641 Object);
13604 } 13642 }
13605 13643
13606 13644
13607 MaybeHandle<Object> JSObject::GetElementWithInterceptor(Handle<JSObject> object, 13645 MaybeHandle<Object> JSObject::GetElementWithInterceptor(Handle<JSObject> object,
13608 Handle<Object> receiver, 13646 Handle<Object> receiver,
13609 uint32_t index, 13647 uint32_t index,
13610 bool check_prototype) { 13648 bool check_prototype) {
(...skipping 3601 matching lines...) Expand 10 before | Expand all | Expand 10 after
17212 CompilationInfo* info) { 17250 CompilationInfo* info) {
17213 Handle<DependentCode> codes = DependentCode::InsertCompilationInfo( 17251 Handle<DependentCode> codes = DependentCode::InsertCompilationInfo(
17214 handle(cell->dependent_code(), info->isolate()), 17252 handle(cell->dependent_code(), info->isolate()),
17215 DependentCode::kPropertyCellChangedGroup, info->object_wrapper()); 17253 DependentCode::kPropertyCellChangedGroup, info->object_wrapper());
17216 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); 17254 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes);
17217 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( 17255 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add(
17218 cell, info->zone()); 17256 cell, info->zone());
17219 } 17257 }
17220 17258
17221 } } // namespace v8::internal 17259 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | test/mjsunit/harmony/super.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698