| 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 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 746 } | 747 } |
| 747 } | 748 } |
| 748 | 749 |
| 749 if (!receiver->IsJSObject()) { | 750 if (!receiver->IsJSObject()) { |
| 750 return WriteToReadOnlyElement(isolate, receiver, index, value, | 751 return WriteToReadOnlyElement(isolate, receiver, index, value, |
| 751 language_mode); | 752 language_mode); |
| 752 } | 753 } |
| 753 Handle<JSObject> target = Handle<JSObject>::cast(receiver); | 754 Handle<JSObject> target = Handle<JSObject>::cast(receiver); |
| 754 ElementsAccessor* accessor = target->GetElementsAccessor(); | 755 ElementsAccessor* accessor = target->GetElementsAccessor(); |
| 755 PropertyAttributes attrs = accessor->GetAttributes(target, index); | 756 PropertyAttributes attrs = accessor->GetAttributes(target, index); |
| 756 if ((attrs & READ_ONLY) != 0) { | 757 if (attrs == ABSENT) { |
| 757 return WriteToReadOnlyElement(isolate, receiver, index, value, | 758 return JSObject::SetElement(target, index, value, NONE, language_mode, |
| 758 language_mode); | 759 false); |
| 759 } | 760 } |
| 760 PropertyAttributes new_attrs = attrs != ABSENT ? attrs : NONE; | 761 return JSObject::SetElement(target, index, value, attrs, language_mode, false, |
| 761 return JSObject::SetElement(target, index, value, new_attrs, language_mode, | 762 DEFINE_PROPERTY); |
| 762 false); | |
| 763 } | 763 } |
| 764 | 764 |
| 765 | 765 |
| 766 Map* Object::GetRootMap(Isolate* isolate) { | 766 Map* Object::GetRootMap(Isolate* isolate) { |
| 767 DisallowHeapAllocation no_alloc; | 767 DisallowHeapAllocation no_alloc; |
| 768 if (IsSmi()) { | 768 if (IsSmi()) { |
| 769 Context* context = isolate->context()->native_context(); | 769 Context* context = isolate->context()->native_context(); |
| 770 return context->number_function()->initial_map(); | 770 return context->number_function()->initial_map(); |
| 771 } | 771 } |
| 772 | 772 |
| (...skipping 2267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3040 | 3040 |
| 3041 MaybeHandle<Object> Object::SetProperty(Handle<Object> object, | 3041 MaybeHandle<Object> Object::SetProperty(Handle<Object> object, |
| 3042 Handle<Name> name, Handle<Object> value, | 3042 Handle<Name> name, Handle<Object> value, |
| 3043 LanguageMode language_mode, | 3043 LanguageMode language_mode, |
| 3044 StoreFromKeyed store_mode) { | 3044 StoreFromKeyed store_mode) { |
| 3045 LookupIterator it(object, name); | 3045 LookupIterator it(object, name); |
| 3046 return SetProperty(&it, value, language_mode, store_mode); | 3046 return SetProperty(&it, value, language_mode, store_mode); |
| 3047 } | 3047 } |
| 3048 | 3048 |
| 3049 | 3049 |
| 3050 MaybeHandle<Object> Object::SetProperty(LookupIterator* it, | 3050 MaybeHandle<Object> Object::SetPropertyInternal(LookupIterator* it, |
| 3051 Handle<Object> value, | 3051 Handle<Object> value, |
| 3052 LanguageMode language_mode, | 3052 LanguageMode language_mode, |
| 3053 StoreFromKeyed store_mode, | 3053 StoreFromKeyed store_mode, |
| 3054 StorePropertyMode data_store_mode) { | 3054 bool* found) { |
| 3055 // Make sure that the top context does not change when doing callbacks or | 3055 // Make sure that the top context does not change when doing callbacks or |
| 3056 // interceptor calls. | 3056 // interceptor calls. |
| 3057 AssertNoContextChange ncc(it->isolate()); | 3057 AssertNoContextChange ncc(it->isolate()); |
| 3058 | 3058 |
| 3059 *found = true; |
| 3060 |
| 3059 bool done = false; | 3061 bool done = false; |
| 3060 for (; it->IsFound(); it->Next()) { | 3062 for (; it->IsFound(); it->Next()) { |
| 3061 switch (it->state()) { | 3063 switch (it->state()) { |
| 3062 case LookupIterator::NOT_FOUND: | 3064 case LookupIterator::NOT_FOUND: |
| 3063 UNREACHABLE(); | 3065 UNREACHABLE(); |
| 3064 | 3066 |
| 3065 case LookupIterator::ACCESS_CHECK: | 3067 case LookupIterator::ACCESS_CHECK: |
| 3066 // TODO(verwaest): Remove the distinction. This is mostly bogus since we | 3068 // TODO(verwaest): Remove the distinction. This is mostly bogus since we |
| 3067 // don't know whether we'll want to fetch attributes or call a setter | 3069 // don't know whether we'll want to fetch attributes or call a setter |
| 3068 // until we find the property. | 3070 // until we find the property. |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3128 break; | 3130 break; |
| 3129 } | 3131 } |
| 3130 | 3132 |
| 3131 if (done) break; | 3133 if (done) break; |
| 3132 } | 3134 } |
| 3133 | 3135 |
| 3134 // 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 |
| 3135 // 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 |
| 3136 // throw a reference error in strict mode. | 3138 // throw a reference error in strict mode. |
| 3137 if (it->GetReceiver()->IsJSGlobalObject() && is_strict(language_mode)) { | 3139 if (it->GetReceiver()->IsJSGlobalObject() && is_strict(language_mode)) { |
| 3138 Handle<Object> args[1] = {it->name()}; | 3140 Handle<Object> args[] = {it->name()}; |
| 3139 THROW_NEW_ERROR(it->isolate(), | 3141 THROW_NEW_ERROR( |
| 3140 NewReferenceError("not_defined", HandleVector(args, 1)), | 3142 it->isolate(), |
| 3141 Object); | 3143 NewReferenceError("not_defined", HandleVector(args, arraysize(args))), |
| 3144 Object); |
| 3142 } | 3145 } |
| 3143 | 3146 |
| 3144 if (data_store_mode == SUPER_PROPERTY) { | 3147 *found = false; |
| 3145 LookupIterator own_lookup(it->GetReceiver(), it->name(), | 3148 return MaybeHandle<Object>(); |
| 3146 LookupIterator::OWN); | 3149 } |
| 3147 | 3150 |
| 3148 return JSObject::SetProperty(&own_lookup, value, language_mode, store_mode, | 3151 |
| 3149 NORMAL_PROPERTY); | 3152 MaybeHandle<Object> Object::SetProperty(LookupIterator* it, |
| 3153 Handle<Object> value, |
| 3154 LanguageMode language_mode, |
| 3155 StoreFromKeyed store_mode) { |
| 3156 bool found = false; |
| 3157 MaybeHandle<Object> result = |
| 3158 SetPropertyInternal(it, value, language_mode, store_mode, &found); |
| 3159 if (found) return result; |
| 3160 return AddDataProperty(it, value, NONE, language_mode, store_mode); |
| 3161 } |
| 3162 |
| 3163 |
| 3164 MaybeHandle<Object> Object::SetSuperProperty(LookupIterator* it, |
| 3165 Handle<Object> value, |
| 3166 LanguageMode language_mode, |
| 3167 StoreFromKeyed store_mode) { |
| 3168 bool found = false; |
| 3169 MaybeHandle<Object> result = |
| 3170 SetPropertyInternal(it, value, language_mode, store_mode, &found); |
| 3171 if (found) return result; |
| 3172 |
| 3173 LookupIterator own_lookup(it->GetReceiver(), it->name(), LookupIterator::OWN); |
| 3174 |
| 3175 switch (own_lookup.state()) { |
| 3176 case LookupIterator::NOT_FOUND: |
| 3177 return JSObject::AddDataProperty(&own_lookup, value, NONE, language_mode, |
| 3178 store_mode); |
| 3179 |
| 3180 case LookupIterator::DATA: { |
| 3181 PropertyDetails details = own_lookup.property_details(); |
| 3182 if (details.IsConfigurable() || !details.IsReadOnly()) { |
| 3183 return JSObject::SetOwnPropertyIgnoreAttributes( |
| 3184 Handle<JSObject>::cast(it->GetReceiver()), it->name(), value, |
| 3185 details.attributes()); |
| 3186 } |
| 3187 return WriteToReadOnlyProperty(&own_lookup, value, language_mode); |
| 3188 } |
| 3189 |
| 3190 case LookupIterator::ACCESSOR: { |
| 3191 PropertyDetails details = own_lookup.property_details(); |
| 3192 if (details.IsConfigurable()) { |
| 3193 return JSObject::SetOwnPropertyIgnoreAttributes( |
| 3194 Handle<JSObject>::cast(it->GetReceiver()), it->name(), value, |
| 3195 details.attributes()); |
| 3196 } |
| 3197 |
| 3198 return RedefineNonconfigurableProperty(it->isolate(), it->name(), value, |
| 3199 language_mode); |
| 3200 } |
| 3201 |
| 3202 case LookupIterator::TRANSITION: |
| 3203 UNREACHABLE(); |
| 3204 break; |
| 3205 |
| 3206 case LookupIterator::INTERCEPTOR: |
| 3207 case LookupIterator::JSPROXY: |
| 3208 case LookupIterator::ACCESS_CHECK: { |
| 3209 bool found = false; |
| 3210 MaybeHandle<Object> result = SetPropertyInternal( |
| 3211 &own_lookup, value, language_mode, store_mode, &found); |
| 3212 if (found) return result; |
| 3213 return SetDataProperty(&own_lookup, value); |
| 3214 } |
| 3150 } | 3215 } |
| 3151 | 3216 |
| 3152 return AddDataProperty(it, value, NONE, language_mode, store_mode); | 3217 UNREACHABLE(); |
| 3218 return MaybeHandle<Object>(); |
| 3153 } | 3219 } |
| 3154 | 3220 |
| 3155 | 3221 |
| 3156 MaybeHandle<Object> Object::WriteToReadOnlyProperty( | 3222 MaybeHandle<Object> Object::WriteToReadOnlyProperty( |
| 3157 LookupIterator* it, Handle<Object> value, LanguageMode language_mode) { | 3223 LookupIterator* it, Handle<Object> value, LanguageMode language_mode) { |
| 3224 return WriteToReadOnlyProperty(it->isolate(), it->GetReceiver(), it->name(), |
| 3225 value, language_mode); |
| 3226 } |
| 3227 |
| 3228 |
| 3229 MaybeHandle<Object> Object::WriteToReadOnlyProperty( |
| 3230 Isolate* isolate, Handle<Object> receiver, Handle<Object> name, |
| 3231 Handle<Object> value, LanguageMode language_mode) { |
| 3158 if (is_sloppy(language_mode)) return value; | 3232 if (is_sloppy(language_mode)) return value; |
| 3159 | 3233 Handle<Object> args[] = {name, receiver}; |
| 3160 Handle<Object> args[] = {it->name(), it->GetReceiver()}; | 3234 THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property", |
| 3161 THROW_NEW_ERROR(it->isolate(), | 3235 HandleVector(args, arraysize(args))), |
| 3162 NewTypeError("strict_read_only_property", | |
| 3163 HandleVector(args, arraysize(args))), | |
| 3164 Object); | 3236 Object); |
| 3165 } | 3237 } |
| 3166 | 3238 |
| 3167 | 3239 |
| 3168 MaybeHandle<Object> Object::WriteToReadOnlyElement(Isolate* isolate, | 3240 MaybeHandle<Object> Object::WriteToReadOnlyElement(Isolate* isolate, |
| 3169 Handle<Object> receiver, | 3241 Handle<Object> receiver, |
| 3170 uint32_t index, | 3242 uint32_t index, |
| 3171 Handle<Object> value, | 3243 Handle<Object> value, |
| 3172 LanguageMode language_mode) { | 3244 LanguageMode language_mode) { |
| 3245 return WriteToReadOnlyProperty(isolate, receiver, |
| 3246 isolate->factory()->NewNumberFromUint(index), |
| 3247 value, language_mode); |
| 3248 } |
| 3249 |
| 3250 |
| 3251 MaybeHandle<Object> Object::RedefineNonconfigurableProperty( |
| 3252 Isolate* isolate, Handle<Object> name, Handle<Object> value, |
| 3253 LanguageMode language_mode) { |
| 3173 if (is_sloppy(language_mode)) return value; | 3254 if (is_sloppy(language_mode)) return value; |
| 3174 | 3255 Handle<Object> args[] = {name}; |
| 3175 Handle<Object> args[] = {isolate->factory()->NewNumberFromUint(index), | 3256 THROW_NEW_ERROR(isolate, NewTypeError("redefine_disallowed", |
| 3176 receiver}; | |
| 3177 THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property", | |
| 3178 HandleVector(args, arraysize(args))), | 3257 HandleVector(args, arraysize(args))), |
| 3179 Object); | 3258 Object); |
| 3180 } | 3259 } |
| 3181 | 3260 |
| 3182 | 3261 |
| 3183 MaybeHandle<Object> Object::SetDataProperty(LookupIterator* it, | 3262 MaybeHandle<Object> Object::SetDataProperty(LookupIterator* it, |
| 3184 Handle<Object> value) { | 3263 Handle<Object> value) { |
| 3185 // Proxies are handled on the WithHandler path. Other non-JSObjects cannot | 3264 // Proxies are handled on the WithHandler path. Other non-JSObjects cannot |
| 3186 // have own properties. | 3265 // have own properties. |
| 3187 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver()); | 3266 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver()); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3236 // If the receiver is Indexed Exotic object (currently only typed arrays), | 3315 // If the receiver is Indexed Exotic object (currently only typed arrays), |
| 3237 // disallow adding properties with numeric names. | 3316 // disallow adding properties with numeric names. |
| 3238 if (it->IsSpecialNumericIndex()) return value; | 3317 if (it->IsSpecialNumericIndex()) return value; |
| 3239 | 3318 |
| 3240 // Possibly migrate to the most up-to-date map that will be able to store | 3319 // Possibly migrate to the most up-to-date map that will be able to store |
| 3241 // |value| under it->name() with |attributes|. | 3320 // |value| under it->name() with |attributes|. |
| 3242 it->PrepareTransitionToDataProperty(value, attributes, store_mode); | 3321 it->PrepareTransitionToDataProperty(value, attributes, store_mode); |
| 3243 if (it->state() != LookupIterator::TRANSITION) { | 3322 if (it->state() != LookupIterator::TRANSITION) { |
| 3244 if (is_sloppy(language_mode)) return value; | 3323 if (is_sloppy(language_mode)) return value; |
| 3245 | 3324 |
| 3246 Handle<Object> args[1] = {it->name()}; | 3325 Handle<Object> args[] = {it->name()}; |
| 3247 THROW_NEW_ERROR(it->isolate(), | 3326 THROW_NEW_ERROR(it->isolate(), |
| 3248 NewTypeError("object_not_extensible", | 3327 NewTypeError("object_not_extensible", |
| 3249 HandleVector(args, arraysize(args))), | 3328 HandleVector(args, arraysize(args))), |
| 3250 Object); | 3329 Object); |
| 3251 } | 3330 } |
| 3252 it->ApplyTransitionToDataProperty(); | 3331 it->ApplyTransitionToDataProperty(); |
| 3253 | 3332 |
| 3254 // TODO(verwaest): Encapsulate dictionary handling better. | 3333 // TODO(verwaest): Encapsulate dictionary handling better. |
| 3255 if (receiver->map()->is_dictionary_map()) { | 3334 if (receiver->map()->is_dictionary_map()) { |
| 3256 // TODO(verwaest): Probably should ensure this is done beforehand. | 3335 // TODO(verwaest): Probably should ensure this is done beforehand. |
| (...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3782 Object::GetProperty(desc, hasWritable_name).ToHandleChecked(); | 3861 Object::GetProperty(desc, hasWritable_name).ToHandleChecked(); |
| 3783 DCHECK(hasWritable->IsBoolean()); | 3862 DCHECK(hasWritable->IsBoolean()); |
| 3784 if (hasWritable->IsTrue()) { | 3863 if (hasWritable->IsTrue()) { |
| 3785 Handle<String> writable_name = isolate->factory()->InternalizeOneByteString( | 3864 Handle<String> writable_name = isolate->factory()->InternalizeOneByteString( |
| 3786 STATIC_CHAR_VECTOR("writable_")); | 3865 STATIC_CHAR_VECTOR("writable_")); |
| 3787 Handle<Object> writable = | 3866 Handle<Object> writable = |
| 3788 Object::GetProperty(desc, writable_name).ToHandleChecked(); | 3867 Object::GetProperty(desc, writable_name).ToHandleChecked(); |
| 3789 DCHECK(writable->IsBoolean()); | 3868 DCHECK(writable->IsBoolean()); |
| 3790 *done = writable->IsFalse(); | 3869 *done = writable->IsFalse(); |
| 3791 if (!*done) return isolate->factory()->the_hole_value(); | 3870 if (!*done) return isolate->factory()->the_hole_value(); |
| 3792 if (is_sloppy(language_mode)) return value; | 3871 return WriteToReadOnlyProperty(isolate, receiver, name, value, |
| 3793 Handle<Object> args[] = { name, receiver }; | 3872 language_mode); |
| 3794 THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property", | |
| 3795 HandleVector(args, arraysize(args))), | |
| 3796 Object); | |
| 3797 } | 3873 } |
| 3798 | 3874 |
| 3799 // We have an AccessorDescriptor. | 3875 // We have an AccessorDescriptor. |
| 3800 Handle<String> set_name = | 3876 Handle<String> set_name = |
| 3801 isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("set_")); | 3877 isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("set_")); |
| 3802 Handle<Object> setter = Object::GetProperty(desc, set_name).ToHandleChecked(); | 3878 Handle<Object> setter = Object::GetProperty(desc, set_name).ToHandleChecked(); |
| 3803 if (!setter->IsUndefined()) { | 3879 if (!setter->IsUndefined()) { |
| 3804 // TODO(rossberg): nicer would be to cast to some JSCallable here... | 3880 // TODO(rossberg): nicer would be to cast to some JSCallable here... |
| 3805 return SetPropertyWithDefinedSetter( | 3881 return SetPropertyWithDefinedSetter( |
| 3806 receiver, Handle<JSReceiver>::cast(setter), value); | 3882 receiver, Handle<JSReceiver>::cast(setter), value); |
| (...skipping 1338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5145 !isolate->MayIndexedAccess(object, index, v8::ACCESS_DELETE)) { | 5221 !isolate->MayIndexedAccess(object, index, v8::ACCESS_DELETE)) { |
| 5146 isolate->ReportFailedAccessCheck(object, v8::ACCESS_DELETE); | 5222 isolate->ReportFailedAccessCheck(object, v8::ACCESS_DELETE); |
| 5147 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 5223 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 5148 return factory->false_value(); | 5224 return factory->false_value(); |
| 5149 } | 5225 } |
| 5150 | 5226 |
| 5151 if (object->IsStringObjectWithCharacterAt(index)) { | 5227 if (object->IsStringObjectWithCharacterAt(index)) { |
| 5152 if (is_strict(language_mode)) { | 5228 if (is_strict(language_mode)) { |
| 5153 // Deleting a non-configurable property in strict mode. | 5229 // Deleting a non-configurable property in strict mode. |
| 5154 Handle<Object> name = factory->NewNumberFromUint(index); | 5230 Handle<Object> name = factory->NewNumberFromUint(index); |
| 5155 Handle<Object> args[2] = { name, object }; | 5231 Handle<Object> args[] = {name, object}; |
| 5156 THROW_NEW_ERROR(isolate, NewTypeError("strict_delete_property", | 5232 THROW_NEW_ERROR(isolate, |
| 5157 HandleVector(args, 2)), | 5233 NewTypeError("strict_delete_property", |
| 5234 HandleVector(args, arraysize(args))), |
| 5158 Object); | 5235 Object); |
| 5159 } | 5236 } |
| 5160 return factory->false_value(); | 5237 return factory->false_value(); |
| 5161 } | 5238 } |
| 5162 | 5239 |
| 5163 if (object->IsJSGlobalProxy()) { | 5240 if (object->IsJSGlobalProxy()) { |
| 5164 PrototypeIterator iter(isolate, object); | 5241 PrototypeIterator iter(isolate, object); |
| 5165 if (iter.IsAtEnd()) return factory->false_value(); | 5242 if (iter.IsAtEnd()) return factory->false_value(); |
| 5166 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 5243 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
| 5167 return DeleteElement( | 5244 return DeleteElement( |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5278 } | 5355 } |
| 5279 case LookupIterator::DATA: | 5356 case LookupIterator::DATA: |
| 5280 if (is_observed) { | 5357 if (is_observed) { |
| 5281 old_value = it.GetDataValue(); | 5358 old_value = it.GetDataValue(); |
| 5282 } | 5359 } |
| 5283 // Fall through. | 5360 // Fall through. |
| 5284 case LookupIterator::ACCESSOR: { | 5361 case LookupIterator::ACCESSOR: { |
| 5285 if (!it.IsConfigurable()) { | 5362 if (!it.IsConfigurable()) { |
| 5286 // Fail if the property is not configurable. | 5363 // Fail if the property is not configurable. |
| 5287 if (is_strict(language_mode)) { | 5364 if (is_strict(language_mode)) { |
| 5288 Handle<Object> args[2] = {name, object}; | 5365 Handle<Object> args[] = {name, object}; |
| 5289 THROW_NEW_ERROR(it.isolate(), | 5366 THROW_NEW_ERROR(it.isolate(), |
| 5290 NewTypeError("strict_delete_property", | 5367 NewTypeError("strict_delete_property", |
| 5291 HandleVector(args, arraysize(args))), | 5368 HandleVector(args, arraysize(args))), |
| 5292 Object); | 5369 Object); |
| 5293 } | 5370 } |
| 5294 return it.isolate()->factory()->false_value(); | 5371 return it.isolate()->factory()->false_value(); |
| 5295 } | 5372 } |
| 5296 | 5373 |
| 5297 PropertyNormalizationMode mode = object->map()->is_prototype_map() | 5374 PropertyNormalizationMode mode = object->map()->is_prototype_map() |
| 5298 ? KEEP_INOBJECT_PROPERTIES | 5375 ? KEEP_INOBJECT_PROPERTIES |
| (...skipping 7354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12653 | 12730 |
| 12654 if (structure->IsAccessorPair()) { | 12731 if (structure->IsAccessorPair()) { |
| 12655 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate); | 12732 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate); |
| 12656 if (setter->IsSpecFunction()) { | 12733 if (setter->IsSpecFunction()) { |
| 12657 // TODO(rossberg): nicer would be to cast to some JSCallable here... | 12734 // TODO(rossberg): nicer would be to cast to some JSCallable here... |
| 12658 return SetPropertyWithDefinedSetter( | 12735 return SetPropertyWithDefinedSetter( |
| 12659 object, Handle<JSReceiver>::cast(setter), value); | 12736 object, Handle<JSReceiver>::cast(setter), value); |
| 12660 } else { | 12737 } else { |
| 12661 if (is_sloppy(language_mode)) return value; | 12738 if (is_sloppy(language_mode)) return value; |
| 12662 Handle<Object> key(isolate->factory()->NewNumberFromUint(index)); | 12739 Handle<Object> key(isolate->factory()->NewNumberFromUint(index)); |
| 12663 Handle<Object> args[2] = { key, holder }; | 12740 Handle<Object> args[] = {key, holder}; |
| 12664 THROW_NEW_ERROR( | 12741 THROW_NEW_ERROR(isolate, |
| 12665 isolate, NewTypeError("no_setter_in_callback", HandleVector(args, 2)), | 12742 NewTypeError("no_setter_in_callback", |
| 12666 Object); | 12743 HandleVector(args, arraysize(args))), |
| 12744 Object); |
| 12667 } | 12745 } |
| 12668 } | 12746 } |
| 12669 | 12747 |
| 12670 UNREACHABLE(); | 12748 UNREACHABLE(); |
| 12671 return MaybeHandle<Object>(); | 12749 return MaybeHandle<Object>(); |
| 12672 } | 12750 } |
| 12673 | 12751 |
| 12674 | 12752 |
| 12675 bool JSObject::HasFastArgumentsElements() { | 12753 bool JSObject::HasFastArgumentsElements() { |
| 12676 Heap* heap = GetHeap(); | 12754 Heap* heap = GetHeap(); |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12843 ? SeededNumberDictionary::cast(elements->get(1)) | 12921 ? SeededNumberDictionary::cast(elements->get(1)) |
| 12844 : SeededNumberDictionary::cast(*elements)); | 12922 : SeededNumberDictionary::cast(*elements)); |
| 12845 | 12923 |
| 12846 int entry = dictionary->FindEntry(index); | 12924 int entry = dictionary->FindEntry(index); |
| 12847 if (entry != SeededNumberDictionary::kNotFound) { | 12925 if (entry != SeededNumberDictionary::kNotFound) { |
| 12848 Handle<Object> element(dictionary->ValueAt(entry), isolate); | 12926 Handle<Object> element(dictionary->ValueAt(entry), isolate); |
| 12849 PropertyDetails details = dictionary->DetailsAt(entry); | 12927 PropertyDetails details = dictionary->DetailsAt(entry); |
| 12850 if (details.type() == ACCESSOR_CONSTANT && set_mode == SET_PROPERTY) { | 12928 if (details.type() == ACCESSOR_CONSTANT && set_mode == SET_PROPERTY) { |
| 12851 return SetElementWithCallback(object, element, index, value, object, | 12929 return SetElementWithCallback(object, element, index, value, object, |
| 12852 language_mode); | 12930 language_mode); |
| 12931 } else if (set_mode == DEFINE_PROPERTY && !details.IsConfigurable() && |
| 12932 details.kind() == kAccessor) { |
| 12933 return RedefineNonconfigurableProperty( |
| 12934 isolate, isolate->factory()->NewNumberFromUint(index), |
| 12935 isolate->factory()->undefined_value(), language_mode); |
| 12936 |
| 12937 } else if ((set_mode == DEFINE_PROPERTY && !details.IsConfigurable() && |
| 12938 details.IsReadOnly()) || |
| 12939 (set_mode == SET_PROPERTY && details.IsReadOnly() && |
| 12940 !element->IsTheHole())) { |
| 12941 // If a value has not been initialized we allow writing to it even if it |
| 12942 // is read-only (a declared const that has not been initialized). |
| 12943 return WriteToReadOnlyProperty( |
| 12944 isolate, object, isolate->factory()->NewNumberFromUint(index), |
| 12945 isolate->factory()->undefined_value(), language_mode); |
| 12853 } else { | 12946 } else { |
| 12947 DCHECK(details.IsConfigurable() || !details.IsReadOnly() || |
| 12948 element->IsTheHole()); |
| 12854 dictionary->UpdateMaxNumberKey(index); | 12949 dictionary->UpdateMaxNumberKey(index); |
| 12855 // If a value has not been initialized we allow writing to it even if it | |
| 12856 // is read-only (a declared const that has not been initialized). If a | |
| 12857 // value is being defined we skip attribute checks completely. | |
| 12858 if (set_mode == DEFINE_PROPERTY) { | 12950 if (set_mode == DEFINE_PROPERTY) { |
| 12859 details = PropertyDetails(attributes, DATA, details.dictionary_index()); | 12951 details = PropertyDetails(attributes, DATA, details.dictionary_index()); |
| 12860 dictionary->DetailsAtPut(entry, details); | 12952 dictionary->DetailsAtPut(entry, details); |
| 12861 } else if (details.IsReadOnly() && !element->IsTheHole()) { | |
| 12862 if (is_sloppy(language_mode)) { | |
| 12863 return isolate->factory()->undefined_value(); | |
| 12864 } else { | |
| 12865 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | |
| 12866 Handle<Object> args[2] = { number, object }; | |
| 12867 THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property", | |
| 12868 HandleVector(args, 2)), | |
| 12869 Object); | |
| 12870 } | |
| 12871 } | 12953 } |
| 12954 |
| 12872 // Elements of the arguments object in slow mode might be slow aliases. | 12955 // Elements of the arguments object in slow mode might be slow aliases. |
| 12873 if (is_arguments && element->IsAliasedArgumentsEntry()) { | 12956 if (is_arguments && element->IsAliasedArgumentsEntry()) { |
| 12874 Handle<AliasedArgumentsEntry> entry = | 12957 Handle<AliasedArgumentsEntry> entry = |
| 12875 Handle<AliasedArgumentsEntry>::cast(element); | 12958 Handle<AliasedArgumentsEntry>::cast(element); |
| 12876 Handle<Context> context(Context::cast(elements->get(0))); | 12959 Handle<Context> context(Context::cast(elements->get(0))); |
| 12877 int context_index = entry->aliased_context_slot(); | 12960 int context_index = entry->aliased_context_slot(); |
| 12878 DCHECK(!context->get(context_index)->IsTheHole()); | 12961 DCHECK(!context->get(context_index)->IsTheHole()); |
| 12879 context->set(context_index, *value); | 12962 context->set(context_index, *value); |
| 12880 // For elements that are still writable we keep slow aliasing. | 12963 // For elements that are still writable we keep slow aliasing. |
| 12881 if (!details.IsReadOnly()) value = element; | 12964 if (!details.IsReadOnly()) value = element; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 12893 } | 12976 } |
| 12894 | 12977 |
| 12895 // When we set the is_extensible flag to false we always force the | 12978 // When we set the is_extensible flag to false we always force the |
| 12896 // element into dictionary mode (and force them to stay there). | 12979 // element into dictionary mode (and force them to stay there). |
| 12897 if (!object->map()->is_extensible()) { | 12980 if (!object->map()->is_extensible()) { |
| 12898 if (is_sloppy(language_mode)) { | 12981 if (is_sloppy(language_mode)) { |
| 12899 return isolate->factory()->undefined_value(); | 12982 return isolate->factory()->undefined_value(); |
| 12900 } else { | 12983 } else { |
| 12901 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 12984 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
| 12902 Handle<String> name = isolate->factory()->NumberToString(number); | 12985 Handle<String> name = isolate->factory()->NumberToString(number); |
| 12903 Handle<Object> args[1] = { name }; | 12986 Handle<Object> args[] = {name}; |
| 12904 THROW_NEW_ERROR(isolate, NewTypeError("object_not_extensible", | 12987 THROW_NEW_ERROR(isolate, |
| 12905 HandleVector(args, 1)), | 12988 NewTypeError("object_not_extensible", |
| 12989 HandleVector(args, arraysize(args))), |
| 12906 Object); | 12990 Object); |
| 12907 } | 12991 } |
| 12908 } | 12992 } |
| 12909 | 12993 |
| 12910 PropertyDetails details(attributes, DATA, 0); | 12994 PropertyDetails details(attributes, DATA, 0); |
| 12911 Handle<SeededNumberDictionary> new_dictionary = | 12995 Handle<SeededNumberDictionary> new_dictionary = |
| 12912 SeededNumberDictionary::AddNumberEntry(dictionary, index, value, | 12996 SeededNumberDictionary::AddNumberEntry(dictionary, index, value, |
| 12913 details); | 12997 details); |
| 12914 if (*dictionary != *new_dictionary) { | 12998 if (*dictionary != *new_dictionary) { |
| 12915 if (is_arguments) { | 12999 if (is_arguments) { |
| (...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13595 uint32_t length = 0; | 13679 uint32_t length = 0; |
| 13596 CHECK(array->length()->ToArrayIndex(&length)); | 13680 CHECK(array->length()->ToArrayIndex(&length)); |
| 13597 if (length <= index) return HasReadOnlyLength(array); | 13681 if (length <= index) return HasReadOnlyLength(array); |
| 13598 return false; | 13682 return false; |
| 13599 } | 13683 } |
| 13600 | 13684 |
| 13601 | 13685 |
| 13602 MaybeHandle<Object> JSArray::ReadOnlyLengthError(Handle<JSArray> array) { | 13686 MaybeHandle<Object> JSArray::ReadOnlyLengthError(Handle<JSArray> array) { |
| 13603 Isolate* isolate = array->GetIsolate(); | 13687 Isolate* isolate = array->GetIsolate(); |
| 13604 Handle<Name> length = isolate->factory()->length_string(); | 13688 Handle<Name> length = isolate->factory()->length_string(); |
| 13605 Handle<Object> args[2] = { length, array }; | 13689 Handle<Object> args[] = {length, array}; |
| 13606 THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property", | 13690 THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property", |
| 13607 HandleVector(args, arraysize(args))), | 13691 HandleVector(args, arraysize(args))), |
| 13608 Object); | 13692 Object); |
| 13609 } | 13693 } |
| 13610 | 13694 |
| 13611 | 13695 |
| 13612 MaybeHandle<Object> JSObject::GetElementWithInterceptor(Handle<JSObject> object, | 13696 MaybeHandle<Object> JSObject::GetElementWithInterceptor(Handle<JSObject> object, |
| 13613 Handle<Object> receiver, | 13697 Handle<Object> receiver, |
| 13614 uint32_t index, | 13698 uint32_t index, |
| 13615 bool check_prototype) { | 13699 bool check_prototype) { |
| (...skipping 3601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17217 CompilationInfo* info) { | 17301 CompilationInfo* info) { |
| 17218 Handle<DependentCode> codes = DependentCode::InsertCompilationInfo( | 17302 Handle<DependentCode> codes = DependentCode::InsertCompilationInfo( |
| 17219 handle(cell->dependent_code(), info->isolate()), | 17303 handle(cell->dependent_code(), info->isolate()), |
| 17220 DependentCode::kPropertyCellChangedGroup, info->object_wrapper()); | 17304 DependentCode::kPropertyCellChangedGroup, info->object_wrapper()); |
| 17221 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); | 17305 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); |
| 17222 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( | 17306 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( |
| 17223 cell, info->zone()); | 17307 cell, info->zone()); |
| 17224 } | 17308 } |
| 17225 | 17309 |
| 17226 } } // namespace v8::internal | 17310 } } // namespace v8::internal |
| OLD | NEW |