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 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 2267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3042 | 3042 |
3043 MaybeHandle<Object> Object::SetProperty(Handle<Object> object, | 3043 MaybeHandle<Object> Object::SetProperty(Handle<Object> object, |
3044 Handle<Name> name, Handle<Object> value, | 3044 Handle<Name> name, Handle<Object> value, |
3045 LanguageMode language_mode, | 3045 LanguageMode language_mode, |
3046 StoreFromKeyed store_mode) { | 3046 StoreFromKeyed store_mode) { |
3047 LookupIterator it(object, name); | 3047 LookupIterator it(object, name); |
3048 return SetProperty(&it, value, language_mode, store_mode); | 3048 return SetProperty(&it, value, language_mode, store_mode); |
3049 } | 3049 } |
3050 | 3050 |
3051 | 3051 |
3052 MaybeHandle<Object> Object::SetProperty(LookupIterator* it, | 3052 MaybeHandle<Object> Object::SetPropertyInternal(LookupIterator* it, |
3053 Handle<Object> value, | 3053 Handle<Object> value, |
3054 LanguageMode language_mode, | 3054 LanguageMode language_mode, |
3055 StoreFromKeyed store_mode, | 3055 StoreFromKeyed store_mode, |
3056 StorePropertyMode data_store_mode) { | 3056 bool* found) { |
3057 // Make sure that the top context does not change when doing callbacks or | 3057 // Make sure that the top context does not change when doing callbacks or |
3058 // interceptor calls. | 3058 // interceptor calls. |
3059 AssertNoContextChange ncc(it->isolate()); | 3059 AssertNoContextChange ncc(it->isolate()); |
3060 | 3060 |
3061 *found = true; | |
3062 | |
3061 bool done = false; | 3063 bool done = false; |
3062 for (; it->IsFound(); it->Next()) { | 3064 for (; it->IsFound(); it->Next()) { |
3063 switch (it->state()) { | 3065 switch (it->state()) { |
3064 case LookupIterator::NOT_FOUND: | 3066 case LookupIterator::NOT_FOUND: |
3065 UNREACHABLE(); | 3067 UNREACHABLE(); |
3066 | 3068 |
3067 case LookupIterator::ACCESS_CHECK: | 3069 case LookupIterator::ACCESS_CHECK: |
3068 // TODO(verwaest): Remove the distinction. This is mostly bogus since we | 3070 // TODO(verwaest): Remove the distinction. This is mostly bogus since we |
3069 // don't know whether we'll want to fetch attributes or call a setter | 3071 // don't know whether we'll want to fetch attributes or call a setter |
3070 // until we find the property. | 3072 // until we find the property. |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3130 break; | 3132 break; |
3131 } | 3133 } |
3132 | 3134 |
3133 if (done) break; | 3135 if (done) break; |
3134 } | 3136 } |
3135 | 3137 |
3136 // If the receiver is the JSGlobalObject, the store was contextual. In case | 3138 // 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 | 3139 // the property did not exist yet on the global object itself, we have to |
3138 // throw a reference error in strict mode. | 3140 // throw a reference error in strict mode. |
3139 if (it->GetReceiver()->IsJSGlobalObject() && is_strict(language_mode)) { | 3141 if (it->GetReceiver()->IsJSGlobalObject() && is_strict(language_mode)) { |
3140 Handle<Object> args[1] = {it->name()}; | 3142 Handle<Object> args[] = {it->name()}; |
3141 THROW_NEW_ERROR(it->isolate(), | 3143 THROW_NEW_ERROR( |
3142 NewReferenceError("not_defined", HandleVector(args, 1)), | 3144 it->isolate(), |
3143 Object); | 3145 NewReferenceError("not_defined", HandleVector(args, arraysize(args))), |
3146 Object); | |
3144 } | 3147 } |
3145 | 3148 |
3146 if (data_store_mode == SUPER_PROPERTY) { | 3149 *found = false; |
3147 LookupIterator own_lookup(it->GetReceiver(), it->name(), | 3150 return MaybeHandle<Object>(); |
3148 LookupIterator::OWN); | 3151 } |
3149 | 3152 |
3150 return JSObject::SetProperty(&own_lookup, value, language_mode, store_mode, | 3153 |
3151 NORMAL_PROPERTY); | 3154 MaybeHandle<Object> Object::SetProperty(LookupIterator* it, |
3155 Handle<Object> value, | |
3156 LanguageMode language_mode, | |
3157 StoreFromKeyed store_mode) { | |
3158 bool found = false; | |
3159 MaybeHandle<Object> result = | |
3160 SetPropertyInternal(it, value, language_mode, store_mode, &found); | |
3161 if (found) return result; | |
3162 return AddDataProperty(it, value, NONE, language_mode, store_mode); | |
3163 } | |
3164 | |
3165 | |
3166 MaybeHandle<Object> Object::SetSuperProperty(LookupIterator* it, | |
3167 Handle<Object> value, | |
3168 LanguageMode language_mode, | |
3169 StoreFromKeyed store_mode) { | |
3170 bool found = false; | |
3171 MaybeHandle<Object> result = | |
3172 SetPropertyInternal(it, value, language_mode, store_mode, &found); | |
3173 if (found) return result; | |
3174 | |
3175 LookupIterator own_lookup(it->GetReceiver(), it->name(), LookupIterator::OWN); | |
3176 | |
3177 switch (own_lookup.state()) { | |
3178 case LookupIterator::NOT_FOUND: | |
3179 return JSObject::AddDataProperty(&own_lookup, value, NONE, language_mode, | |
3180 store_mode); | |
3181 | |
3182 case LookupIterator::DATA: { | |
3183 PropertyDetails details = own_lookup.property_details(); | |
3184 if (details.IsConfigurable() || !details.IsReadOnly()) { | |
3185 return JSObject::SetOwnPropertyIgnoreAttributes( | |
3186 Handle<JSObject>::cast(it->GetReceiver()), it->name(), value, | |
3187 details.attributes()); | |
3188 } | |
3189 return WriteToReadOnlyProperty(&own_lookup, value, language_mode); | |
3190 } | |
3191 | |
3192 case LookupIterator::ACCESSOR: { | |
3193 PropertyDetails details = own_lookup.property_details(); | |
3194 if (details.IsConfigurable()) { | |
3195 return JSObject::SetOwnPropertyIgnoreAttributes( | |
3196 Handle<JSObject>::cast(it->GetReceiver()), it->name(), value, | |
3197 details.attributes()); | |
3198 } | |
3199 | |
3200 return RedefineNonconfigurableProperty(it->isolate(), it->name(), value, | |
3201 language_mode); | |
3202 } | |
3203 | |
3204 case LookupIterator::INTERCEPTOR: | |
3205 case LookupIterator::JSPROXY: | |
3206 case LookupIterator::ACCESS_CHECK: | |
3207 case LookupIterator::TRANSITION: { | |
Toon Verwaest
2015/02/19 05:32:19
TRANSITION should be UNREACHABLE()
| |
3208 bool found = false; | |
3209 MaybeHandle<Object> result = SetPropertyInternal( | |
3210 &own_lookup, value, language_mode, store_mode, &found); | |
3211 if (found) return result; | |
3212 return SetDataProperty(&own_lookup, value); | |
3213 } | |
3152 } | 3214 } |
3153 | 3215 |
3154 return AddDataProperty(it, value, NONE, language_mode, store_mode); | 3216 UNREACHABLE(); |
3217 return MaybeHandle<Object>(); | |
3155 } | 3218 } |
3156 | 3219 |
3157 | 3220 |
3158 MaybeHandle<Object> Object::WriteToReadOnlyProperty( | 3221 MaybeHandle<Object> Object::WriteToReadOnlyProperty( |
3159 LookupIterator* it, Handle<Object> value, LanguageMode language_mode) { | 3222 LookupIterator* it, Handle<Object> value, LanguageMode language_mode) { |
3223 return WriteToReadOnlyProperty(it->isolate(), it->GetReceiver(), it->name(), | |
3224 value, language_mode); | |
3225 } | |
3226 | |
3227 | |
3228 MaybeHandle<Object> Object::WriteToReadOnlyProperty( | |
3229 Isolate* isolate, Handle<Object> receiver, Handle<Object> name, | |
3230 Handle<Object> value, LanguageMode language_mode) { | |
3160 if (is_sloppy(language_mode)) return value; | 3231 if (is_sloppy(language_mode)) return value; |
3161 | 3232 Handle<Object> args[] = {name, receiver}; |
3162 Handle<Object> args[] = {it->name(), it->GetReceiver()}; | 3233 THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property", |
3163 THROW_NEW_ERROR(it->isolate(), | 3234 HandleVector(args, arraysize(args))), |
3164 NewTypeError("strict_read_only_property", | |
3165 HandleVector(args, arraysize(args))), | |
3166 Object); | 3235 Object); |
3167 } | 3236 } |
3168 | 3237 |
3169 | 3238 |
3170 MaybeHandle<Object> Object::WriteToReadOnlyElement(Isolate* isolate, | 3239 MaybeHandle<Object> Object::WriteToReadOnlyElement(Isolate* isolate, |
3171 Handle<Object> receiver, | 3240 Handle<Object> receiver, |
3172 uint32_t index, | 3241 uint32_t index, |
3173 Handle<Object> value, | 3242 Handle<Object> value, |
3174 LanguageMode language_mode) { | 3243 LanguageMode language_mode) { |
3244 return WriteToReadOnlyProperty(isolate, receiver, | |
3245 isolate->factory()->NewNumberFromUint(index), | |
3246 value, language_mode); | |
3247 } | |
3248 | |
3249 | |
3250 MaybeHandle<Object> Object::RedefineNonconfigurableProperty( | |
3251 Isolate* isolate, Handle<Object> name, Handle<Object> value, | |
3252 LanguageMode language_mode) { | |
3175 if (is_sloppy(language_mode)) return value; | 3253 if (is_sloppy(language_mode)) return value; |
3176 | 3254 Handle<Object> args[] = {name}; |
3177 Handle<Object> args[] = {isolate->factory()->NewNumberFromUint(index), | 3255 THROW_NEW_ERROR(isolate, NewTypeError("redefine_disallowed", |
3178 receiver}; | |
3179 THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property", | |
3180 HandleVector(args, arraysize(args))), | 3256 HandleVector(args, arraysize(args))), |
3181 Object); | 3257 Object); |
3182 } | 3258 } |
3183 | 3259 |
3184 | 3260 |
3185 MaybeHandle<Object> Object::SetDataProperty(LookupIterator* it, | 3261 MaybeHandle<Object> Object::SetDataProperty(LookupIterator* it, |
3186 Handle<Object> value) { | 3262 Handle<Object> value) { |
3187 // Proxies are handled on the WithHandler path. Other non-JSObjects cannot | 3263 // Proxies are handled on the WithHandler path. Other non-JSObjects cannot |
3188 // have own properties. | 3264 // have own properties. |
3189 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver()); | 3265 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver()); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3238 // If the receiver is Indexed Exotic object (currently only typed arrays), | 3314 // If the receiver is Indexed Exotic object (currently only typed arrays), |
3239 // disallow adding properties with numeric names. | 3315 // disallow adding properties with numeric names. |
3240 if (it->IsSpecialNumericIndex()) return value; | 3316 if (it->IsSpecialNumericIndex()) return value; |
3241 | 3317 |
3242 // Possibly migrate to the most up-to-date map that will be able to store | 3318 // Possibly migrate to the most up-to-date map that will be able to store |
3243 // |value| under it->name() with |attributes|. | 3319 // |value| under it->name() with |attributes|. |
3244 it->PrepareTransitionToDataProperty(value, attributes, store_mode); | 3320 it->PrepareTransitionToDataProperty(value, attributes, store_mode); |
3245 if (it->state() != LookupIterator::TRANSITION) { | 3321 if (it->state() != LookupIterator::TRANSITION) { |
3246 if (is_sloppy(language_mode)) return value; | 3322 if (is_sloppy(language_mode)) return value; |
3247 | 3323 |
3248 Handle<Object> args[1] = {it->name()}; | 3324 Handle<Object> args[] = {it->name()}; |
3249 THROW_NEW_ERROR(it->isolate(), | 3325 THROW_NEW_ERROR(it->isolate(), |
3250 NewTypeError("object_not_extensible", | 3326 NewTypeError("object_not_extensible", |
3251 HandleVector(args, arraysize(args))), | 3327 HandleVector(args, arraysize(args))), |
3252 Object); | 3328 Object); |
3253 } | 3329 } |
3254 it->ApplyTransitionToDataProperty(); | 3330 it->ApplyTransitionToDataProperty(); |
3255 | 3331 |
3256 // TODO(verwaest): Encapsulate dictionary handling better. | 3332 // TODO(verwaest): Encapsulate dictionary handling better. |
3257 if (receiver->map()->is_dictionary_map()) { | 3333 if (receiver->map()->is_dictionary_map()) { |
3258 // TODO(verwaest): Probably should ensure this is done beforehand. | 3334 // TODO(verwaest): Probably should ensure this is done beforehand. |
(...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3784 Object::GetProperty(desc, hasWritable_name).ToHandleChecked(); | 3860 Object::GetProperty(desc, hasWritable_name).ToHandleChecked(); |
3785 DCHECK(hasWritable->IsBoolean()); | 3861 DCHECK(hasWritable->IsBoolean()); |
3786 if (hasWritable->IsTrue()) { | 3862 if (hasWritable->IsTrue()) { |
3787 Handle<String> writable_name = isolate->factory()->InternalizeOneByteString( | 3863 Handle<String> writable_name = isolate->factory()->InternalizeOneByteString( |
3788 STATIC_CHAR_VECTOR("writable_")); | 3864 STATIC_CHAR_VECTOR("writable_")); |
3789 Handle<Object> writable = | 3865 Handle<Object> writable = |
3790 Object::GetProperty(desc, writable_name).ToHandleChecked(); | 3866 Object::GetProperty(desc, writable_name).ToHandleChecked(); |
3791 DCHECK(writable->IsBoolean()); | 3867 DCHECK(writable->IsBoolean()); |
3792 *done = writable->IsFalse(); | 3868 *done = writable->IsFalse(); |
3793 if (!*done) return isolate->factory()->the_hole_value(); | 3869 if (!*done) return isolate->factory()->the_hole_value(); |
3794 if (is_sloppy(language_mode)) return value; | 3870 return WriteToReadOnlyProperty(isolate, receiver, name, value, |
3795 Handle<Object> args[] = { name, receiver }; | 3871 language_mode); |
3796 THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property", | |
3797 HandleVector(args, arraysize(args))), | |
3798 Object); | |
3799 } | 3872 } |
3800 | 3873 |
3801 // We have an AccessorDescriptor. | 3874 // We have an AccessorDescriptor. |
3802 Handle<String> set_name = | 3875 Handle<String> set_name = |
3803 isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("set_")); | 3876 isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("set_")); |
3804 Handle<Object> setter = Object::GetProperty(desc, set_name).ToHandleChecked(); | 3877 Handle<Object> setter = Object::GetProperty(desc, set_name).ToHandleChecked(); |
3805 if (!setter->IsUndefined()) { | 3878 if (!setter->IsUndefined()) { |
3806 // TODO(rossberg): nicer would be to cast to some JSCallable here... | 3879 // TODO(rossberg): nicer would be to cast to some JSCallable here... |
3807 return SetPropertyWithDefinedSetter( | 3880 return SetPropertyWithDefinedSetter( |
3808 receiver, Handle<JSReceiver>::cast(setter), value); | 3881 receiver, Handle<JSReceiver>::cast(setter), value); |
(...skipping 1338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5147 !isolate->MayIndexedAccess(object, index, v8::ACCESS_DELETE)) { | 5220 !isolate->MayIndexedAccess(object, index, v8::ACCESS_DELETE)) { |
5148 isolate->ReportFailedAccessCheck(object, v8::ACCESS_DELETE); | 5221 isolate->ReportFailedAccessCheck(object, v8::ACCESS_DELETE); |
5149 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 5222 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
5150 return factory->false_value(); | 5223 return factory->false_value(); |
5151 } | 5224 } |
5152 | 5225 |
5153 if (object->IsStringObjectWithCharacterAt(index)) { | 5226 if (object->IsStringObjectWithCharacterAt(index)) { |
5154 if (is_strict(language_mode)) { | 5227 if (is_strict(language_mode)) { |
5155 // Deleting a non-configurable property in strict mode. | 5228 // Deleting a non-configurable property in strict mode. |
5156 Handle<Object> name = factory->NewNumberFromUint(index); | 5229 Handle<Object> name = factory->NewNumberFromUint(index); |
5157 Handle<Object> args[2] = { name, object }; | 5230 Handle<Object> args[] = {name, object}; |
5158 THROW_NEW_ERROR(isolate, NewTypeError("strict_delete_property", | 5231 THROW_NEW_ERROR(isolate, |
5159 HandleVector(args, 2)), | 5232 NewTypeError("strict_delete_property", |
5233 HandleVector(args, arraysize(args))), | |
5160 Object); | 5234 Object); |
5161 } | 5235 } |
5162 return factory->false_value(); | 5236 return factory->false_value(); |
5163 } | 5237 } |
5164 | 5238 |
5165 if (object->IsJSGlobalProxy()) { | 5239 if (object->IsJSGlobalProxy()) { |
5166 PrototypeIterator iter(isolate, object); | 5240 PrototypeIterator iter(isolate, object); |
5167 if (iter.IsAtEnd()) return factory->false_value(); | 5241 if (iter.IsAtEnd()) return factory->false_value(); |
5168 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 5242 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
5169 return DeleteElement( | 5243 return DeleteElement( |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5280 } | 5354 } |
5281 case LookupIterator::DATA: | 5355 case LookupIterator::DATA: |
5282 if (is_observed) { | 5356 if (is_observed) { |
5283 old_value = it.GetDataValue(); | 5357 old_value = it.GetDataValue(); |
5284 } | 5358 } |
5285 // Fall through. | 5359 // Fall through. |
5286 case LookupIterator::ACCESSOR: { | 5360 case LookupIterator::ACCESSOR: { |
5287 if (!it.IsConfigurable()) { | 5361 if (!it.IsConfigurable()) { |
5288 // Fail if the property is not configurable. | 5362 // Fail if the property is not configurable. |
5289 if (is_strict(language_mode)) { | 5363 if (is_strict(language_mode)) { |
5290 Handle<Object> args[2] = {name, object}; | 5364 Handle<Object> args[] = {name, object}; |
5291 THROW_NEW_ERROR(it.isolate(), | 5365 THROW_NEW_ERROR(it.isolate(), |
5292 NewTypeError("strict_delete_property", | 5366 NewTypeError("strict_delete_property", |
5293 HandleVector(args, arraysize(args))), | 5367 HandleVector(args, arraysize(args))), |
5294 Object); | 5368 Object); |
5295 } | 5369 } |
5296 return it.isolate()->factory()->false_value(); | 5370 return it.isolate()->factory()->false_value(); |
5297 } | 5371 } |
5298 | 5372 |
5299 PropertyNormalizationMode mode = object->map()->is_prototype_map() | 5373 PropertyNormalizationMode mode = object->map()->is_prototype_map() |
5300 ? KEEP_INOBJECT_PROPERTIES | 5374 ? KEEP_INOBJECT_PROPERTIES |
(...skipping 7337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12638 | 12712 |
12639 if (structure->IsAccessorPair()) { | 12713 if (structure->IsAccessorPair()) { |
12640 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate); | 12714 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate); |
12641 if (setter->IsSpecFunction()) { | 12715 if (setter->IsSpecFunction()) { |
12642 // TODO(rossberg): nicer would be to cast to some JSCallable here... | 12716 // TODO(rossberg): nicer would be to cast to some JSCallable here... |
12643 return SetPropertyWithDefinedSetter( | 12717 return SetPropertyWithDefinedSetter( |
12644 object, Handle<JSReceiver>::cast(setter), value); | 12718 object, Handle<JSReceiver>::cast(setter), value); |
12645 } else { | 12719 } else { |
12646 if (is_sloppy(language_mode)) return value; | 12720 if (is_sloppy(language_mode)) return value; |
12647 Handle<Object> key(isolate->factory()->NewNumberFromUint(index)); | 12721 Handle<Object> key(isolate->factory()->NewNumberFromUint(index)); |
12648 Handle<Object> args[2] = { key, holder }; | 12722 Handle<Object> args[] = {key, holder}; |
12649 THROW_NEW_ERROR( | 12723 THROW_NEW_ERROR(isolate, |
12650 isolate, NewTypeError("no_setter_in_callback", HandleVector(args, 2)), | 12724 NewTypeError("no_setter_in_callback", |
12651 Object); | 12725 HandleVector(args, arraysize(args))), |
12726 Object); | |
12652 } | 12727 } |
12653 } | 12728 } |
12654 | 12729 |
12655 UNREACHABLE(); | 12730 UNREACHABLE(); |
12656 return MaybeHandle<Object>(); | 12731 return MaybeHandle<Object>(); |
12657 } | 12732 } |
12658 | 12733 |
12659 | 12734 |
12660 bool JSObject::HasFastArgumentsElements() { | 12735 bool JSObject::HasFastArgumentsElements() { |
12661 Heap* heap = GetHeap(); | 12736 Heap* heap = GetHeap(); |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12828 ? SeededNumberDictionary::cast(elements->get(1)) | 12903 ? SeededNumberDictionary::cast(elements->get(1)) |
12829 : SeededNumberDictionary::cast(*elements)); | 12904 : SeededNumberDictionary::cast(*elements)); |
12830 | 12905 |
12831 int entry = dictionary->FindEntry(index); | 12906 int entry = dictionary->FindEntry(index); |
12832 if (entry != SeededNumberDictionary::kNotFound) { | 12907 if (entry != SeededNumberDictionary::kNotFound) { |
12833 Handle<Object> element(dictionary->ValueAt(entry), isolate); | 12908 Handle<Object> element(dictionary->ValueAt(entry), isolate); |
12834 PropertyDetails details = dictionary->DetailsAt(entry); | 12909 PropertyDetails details = dictionary->DetailsAt(entry); |
12835 if (details.type() == ACCESSOR_CONSTANT && set_mode == SET_PROPERTY) { | 12910 if (details.type() == ACCESSOR_CONSTANT && set_mode == SET_PROPERTY) { |
12836 return SetElementWithCallback(object, element, index, value, object, | 12911 return SetElementWithCallback(object, element, index, value, object, |
12837 language_mode); | 12912 language_mode); |
12913 } else if (set_mode == DEFINE_PROPERTY && !details.IsConfigurable() && | |
12914 details.kind() == kAccessor) { | |
12915 return RedefineNonconfigurableProperty( | |
12916 isolate, isolate->factory()->NewNumberFromUint(index), | |
12917 isolate->factory()->undefined_value(), language_mode); | |
12918 | |
12919 } else if ((set_mode == DEFINE_PROPERTY && !details.IsConfigurable() && | |
12920 details.IsReadOnly()) || | |
12921 (set_mode == SET_PROPERTY && details.IsReadOnly() && | |
12922 !element->IsTheHole())) { | |
12923 // If a value has not been initialized we allow writing to it even if it | |
12924 // is read-only (a declared const that has not been initialized). | |
12925 return WriteToReadOnlyProperty( | |
12926 isolate, object, isolate->factory()->NewNumberFromUint(index), | |
12927 isolate->factory()->undefined_value(), language_mode); | |
12838 } else { | 12928 } else { |
12929 DCHECK(details.IsConfigurable() || !details.IsReadOnly() || | |
12930 element->IsTheHole()); | |
12839 dictionary->UpdateMaxNumberKey(index); | 12931 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) { | 12932 if (set_mode == DEFINE_PROPERTY) { |
12844 details = PropertyDetails(attributes, DATA, details.dictionary_index()); | 12933 details = PropertyDetails(attributes, DATA, details.dictionary_index()); |
12845 dictionary->DetailsAtPut(entry, details); | 12934 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 } | 12935 } |
12936 | |
12857 // Elements of the arguments object in slow mode might be slow aliases. | 12937 // Elements of the arguments object in slow mode might be slow aliases. |
12858 if (is_arguments && element->IsAliasedArgumentsEntry()) { | 12938 if (is_arguments && element->IsAliasedArgumentsEntry()) { |
12859 Handle<AliasedArgumentsEntry> entry = | 12939 Handle<AliasedArgumentsEntry> entry = |
12860 Handle<AliasedArgumentsEntry>::cast(element); | 12940 Handle<AliasedArgumentsEntry>::cast(element); |
12861 Handle<Context> context(Context::cast(elements->get(0))); | 12941 Handle<Context> context(Context::cast(elements->get(0))); |
12862 int context_index = entry->aliased_context_slot(); | 12942 int context_index = entry->aliased_context_slot(); |
12863 DCHECK(!context->get(context_index)->IsTheHole()); | 12943 DCHECK(!context->get(context_index)->IsTheHole()); |
12864 context->set(context_index, *value); | 12944 context->set(context_index, *value); |
12865 // For elements that are still writable we keep slow aliasing. | 12945 // For elements that are still writable we keep slow aliasing. |
12866 if (!details.IsReadOnly()) value = element; | 12946 if (!details.IsReadOnly()) value = element; |
(...skipping 11 matching lines...) Expand all Loading... | |
12878 } | 12958 } |
12879 | 12959 |
12880 // When we set the is_extensible flag to false we always force the | 12960 // When we set the is_extensible flag to false we always force the |
12881 // element into dictionary mode (and force them to stay there). | 12961 // element into dictionary mode (and force them to stay there). |
12882 if (!object->map()->is_extensible()) { | 12962 if (!object->map()->is_extensible()) { |
12883 if (is_sloppy(language_mode)) { | 12963 if (is_sloppy(language_mode)) { |
12884 return isolate->factory()->undefined_value(); | 12964 return isolate->factory()->undefined_value(); |
12885 } else { | 12965 } else { |
12886 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 12966 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
12887 Handle<String> name = isolate->factory()->NumberToString(number); | 12967 Handle<String> name = isolate->factory()->NumberToString(number); |
12888 Handle<Object> args[1] = { name }; | 12968 Handle<Object> args[] = {name}; |
12889 THROW_NEW_ERROR(isolate, NewTypeError("object_not_extensible", | 12969 THROW_NEW_ERROR(isolate, |
12890 HandleVector(args, 1)), | 12970 NewTypeError("object_not_extensible", |
12971 HandleVector(args, arraysize(args))), | |
12891 Object); | 12972 Object); |
12892 } | 12973 } |
12893 } | 12974 } |
12894 | 12975 |
12895 PropertyDetails details(attributes, DATA, 0); | 12976 PropertyDetails details(attributes, DATA, 0); |
12896 Handle<SeededNumberDictionary> new_dictionary = | 12977 Handle<SeededNumberDictionary> new_dictionary = |
12897 SeededNumberDictionary::AddNumberEntry(dictionary, index, value, | 12978 SeededNumberDictionary::AddNumberEntry(dictionary, index, value, |
12898 details); | 12979 details); |
12899 if (*dictionary != *new_dictionary) { | 12980 if (*dictionary != *new_dictionary) { |
12900 if (is_arguments) { | 12981 if (is_arguments) { |
(...skipping 689 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
13590 uint32_t length = 0; | 13671 uint32_t length = 0; |
13591 CHECK(array->length()->ToArrayIndex(&length)); | 13672 CHECK(array->length()->ToArrayIndex(&length)); |
13592 if (length <= index) return HasReadOnlyLength(array); | 13673 if (length <= index) return HasReadOnlyLength(array); |
13593 return false; | 13674 return false; |
13594 } | 13675 } |
13595 | 13676 |
13596 | 13677 |
13597 MaybeHandle<Object> JSArray::ReadOnlyLengthError(Handle<JSArray> array) { | 13678 MaybeHandle<Object> JSArray::ReadOnlyLengthError(Handle<JSArray> array) { |
13598 Isolate* isolate = array->GetIsolate(); | 13679 Isolate* isolate = array->GetIsolate(); |
13599 Handle<Name> length = isolate->factory()->length_string(); | 13680 Handle<Name> length = isolate->factory()->length_string(); |
13600 Handle<Object> args[2] = { length, array }; | 13681 Handle<Object> args[] = {length, array}; |
13601 THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property", | 13682 THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property", |
13602 HandleVector(args, arraysize(args))), | 13683 HandleVector(args, arraysize(args))), |
13603 Object); | 13684 Object); |
13604 } | 13685 } |
13605 | 13686 |
13606 | 13687 |
13607 MaybeHandle<Object> JSObject::GetElementWithInterceptor(Handle<JSObject> object, | 13688 MaybeHandle<Object> JSObject::GetElementWithInterceptor(Handle<JSObject> object, |
13608 Handle<Object> receiver, | 13689 Handle<Object> receiver, |
13609 uint32_t index, | 13690 uint32_t index, |
13610 bool check_prototype) { | 13691 bool check_prototype) { |
(...skipping 3601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
17212 CompilationInfo* info) { | 17293 CompilationInfo* info) { |
17213 Handle<DependentCode> codes = DependentCode::InsertCompilationInfo( | 17294 Handle<DependentCode> codes = DependentCode::InsertCompilationInfo( |
17214 handle(cell->dependent_code(), info->isolate()), | 17295 handle(cell->dependent_code(), info->isolate()), |
17215 DependentCode::kPropertyCellChangedGroup, info->object_wrapper()); | 17296 DependentCode::kPropertyCellChangedGroup, info->object_wrapper()); |
17216 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); | 17297 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); |
17217 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( | 17298 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( |
17218 cell, info->zone()); | 17299 cell, info->zone()); |
17219 } | 17300 } |
17220 | 17301 |
17221 } } // namespace v8::internal | 17302 } } // namespace v8::internal |
OLD | NEW |