| 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 "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/allocation-site-scopes.h" | 8 #include "src/allocation-site-scopes.h" |
| 9 #include "src/api.h" | 9 #include "src/api.h" |
| 10 #include "src/arguments.h" | 10 #include "src/arguments.h" |
| (...skipping 1955 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1966 Handle<JSFunction>(isolate->observers_notify_change()), | 1966 Handle<JSFunction>(isolate->observers_notify_change()), |
| 1967 isolate->factory()->undefined_value(), | 1967 isolate->factory()->undefined_value(), |
| 1968 argc, args).Assert(); | 1968 argc, args).Assert(); |
| 1969 } | 1969 } |
| 1970 | 1970 |
| 1971 | 1971 |
| 1972 MaybeHandle<Object> JSObject::SetPropertyPostInterceptor( | 1972 MaybeHandle<Object> JSObject::SetPropertyPostInterceptor( |
| 1973 Handle<JSObject> object, | 1973 Handle<JSObject> object, |
| 1974 Handle<Name> name, | 1974 Handle<Name> name, |
| 1975 Handle<Object> value, | 1975 Handle<Object> value, |
| 1976 PropertyAttributes attributes, | |
| 1977 StrictMode strict_mode) { | 1976 StrictMode strict_mode) { |
| 1978 // Check own property, ignore interceptor. | 1977 // Check own property, ignore interceptor. |
| 1979 Isolate* isolate = object->GetIsolate(); | 1978 Isolate* isolate = object->GetIsolate(); |
| 1980 LookupResult result(isolate); | 1979 LookupResult result(isolate); |
| 1981 object->LookupOwnRealNamedProperty(name, &result); | 1980 object->LookupOwnRealNamedProperty(name, &result); |
| 1982 if (!result.IsFound()) { | 1981 if (!result.IsFound()) { |
| 1983 object->map()->LookupTransition(*object, *name, &result); | 1982 object->map()->LookupTransition(*object, *name, &result); |
| 1984 } | 1983 } |
| 1985 return SetPropertyForResult(object, &result, name, value, attributes, | 1984 return SetPropertyForResult(object, &result, name, value, strict_mode, |
| 1986 strict_mode, MAY_BE_STORE_FROM_KEYED); | 1985 MAY_BE_STORE_FROM_KEYED); |
| 1987 } | 1986 } |
| 1988 | 1987 |
| 1989 | 1988 |
| 1990 static void ReplaceSlowProperty(Handle<JSObject> object, | 1989 static void ReplaceSlowProperty(Handle<JSObject> object, |
| 1991 Handle<Name> name, | 1990 Handle<Name> name, |
| 1992 Handle<Object> value, | 1991 Handle<Object> value, |
| 1993 PropertyAttributes attributes) { | 1992 PropertyAttributes attributes) { |
| 1994 NameDictionary* dictionary = object->property_dictionary(); | 1993 NameDictionary* dictionary = object->property_dictionary(); |
| 1995 int old_index = dictionary->FindEntry(name); | 1994 int old_index = dictionary->FindEntry(name); |
| 1996 int new_enumeration_index = 0; // 0 means "Use the next available index." | 1995 int new_enumeration_index = 0; // 0 means "Use the next available index." |
| (...skipping 973 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2970 } | 2969 } |
| 2971 if (new_map->NumberOfOwnDescriptors() != old_nof) return MaybeHandle<Map>(); | 2970 if (new_map->NumberOfOwnDescriptors() != old_nof) return MaybeHandle<Map>(); |
| 2972 return handle(new_map); | 2971 return handle(new_map); |
| 2973 } | 2972 } |
| 2974 | 2973 |
| 2975 | 2974 |
| 2976 MaybeHandle<Object> JSObject::SetPropertyWithInterceptor( | 2975 MaybeHandle<Object> JSObject::SetPropertyWithInterceptor( |
| 2977 Handle<JSObject> object, | 2976 Handle<JSObject> object, |
| 2978 Handle<Name> name, | 2977 Handle<Name> name, |
| 2979 Handle<Object> value, | 2978 Handle<Object> value, |
| 2980 PropertyAttributes attributes, | |
| 2981 StrictMode strict_mode) { | 2979 StrictMode strict_mode) { |
| 2982 // TODO(rossberg): Support symbols in the API. | 2980 // TODO(rossberg): Support symbols in the API. |
| 2983 if (name->IsSymbol()) return value; | 2981 if (name->IsSymbol()) return value; |
| 2984 Isolate* isolate = object->GetIsolate(); | 2982 Isolate* isolate = object->GetIsolate(); |
| 2985 Handle<String> name_string = Handle<String>::cast(name); | 2983 Handle<String> name_string = Handle<String>::cast(name); |
| 2986 Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor()); | 2984 Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor()); |
| 2987 if (!interceptor->setter()->IsUndefined()) { | 2985 if (!interceptor->setter()->IsUndefined()) { |
| 2988 LOG(isolate, | 2986 LOG(isolate, |
| 2989 ApiNamedPropertyAccess("interceptor-named-set", *object, *name)); | 2987 ApiNamedPropertyAccess("interceptor-named-set", *object, *name)); |
| 2990 PropertyCallbackArguments args( | 2988 PropertyCallbackArguments args( |
| 2991 isolate, interceptor->data(), *object, *object); | 2989 isolate, interceptor->data(), *object, *object); |
| 2992 v8::NamedPropertySetterCallback setter = | 2990 v8::NamedPropertySetterCallback setter = |
| 2993 v8::ToCData<v8::NamedPropertySetterCallback>(interceptor->setter()); | 2991 v8::ToCData<v8::NamedPropertySetterCallback>(interceptor->setter()); |
| 2994 Handle<Object> value_unhole = value->IsTheHole() | 2992 Handle<Object> value_unhole = value->IsTheHole() |
| 2995 ? Handle<Object>(isolate->factory()->undefined_value()) : value; | 2993 ? Handle<Object>(isolate->factory()->undefined_value()) : value; |
| 2996 v8::Handle<v8::Value> result = args.Call(setter, | 2994 v8::Handle<v8::Value> result = args.Call(setter, |
| 2997 v8::Utils::ToLocal(name_string), | 2995 v8::Utils::ToLocal(name_string), |
| 2998 v8::Utils::ToLocal(value_unhole)); | 2996 v8::Utils::ToLocal(value_unhole)); |
| 2999 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 2997 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 3000 if (!result.IsEmpty()) return value; | 2998 if (!result.IsEmpty()) return value; |
| 3001 } | 2999 } |
| 3002 return SetPropertyPostInterceptor( | 3000 return SetPropertyPostInterceptor(object, name, value, strict_mode); |
| 3003 object, name, value, attributes, strict_mode); | |
| 3004 } | 3001 } |
| 3005 | 3002 |
| 3006 | 3003 |
| 3007 MaybeHandle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object, | 3004 MaybeHandle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object, |
| 3008 Handle<Name> name, | 3005 Handle<Name> name, |
| 3009 Handle<Object> value, | 3006 Handle<Object> value, |
| 3010 PropertyAttributes attributes, | |
| 3011 StrictMode strict_mode, | 3007 StrictMode strict_mode, |
| 3012 StoreFromKeyed store_mode) { | 3008 StoreFromKeyed store_mode) { |
| 3013 LookupResult result(object->GetIsolate()); | 3009 LookupResult result(object->GetIsolate()); |
| 3014 object->LookupOwn(name, &result, true); | 3010 object->LookupOwn(name, &result, true); |
| 3015 if (!result.IsFound()) { | 3011 if (!result.IsFound()) { |
| 3016 object->map()->LookupTransition(JSObject::cast(*object), *name, &result); | 3012 object->map()->LookupTransition(JSObject::cast(*object), *name, &result); |
| 3017 } | 3013 } |
| 3018 return SetProperty(object, &result, name, value, attributes, strict_mode, | 3014 return SetProperty(object, &result, name, value, strict_mode, store_mode); |
| 3019 store_mode); | |
| 3020 } | 3015 } |
| 3021 | 3016 |
| 3022 | 3017 |
| 3023 MaybeHandle<Object> JSObject::SetElementWithCallbackSetterInPrototypes( | 3018 MaybeHandle<Object> JSObject::SetElementWithCallbackSetterInPrototypes( |
| 3024 Handle<JSObject> object, | 3019 Handle<JSObject> object, |
| 3025 uint32_t index, | 3020 uint32_t index, |
| 3026 Handle<Object> value, | 3021 Handle<Object> value, |
| 3027 bool* found, | 3022 bool* found, |
| 3028 StrictMode strict_mode) { | 3023 StrictMode strict_mode) { |
| 3029 Isolate *isolate = object->GetIsolate(); | 3024 Isolate *isolate = object->GetIsolate(); |
| 3030 for (PrototypeIterator iter(isolate, object); !iter.IsAtEnd(); | 3025 for (PrototypeIterator iter(isolate, object); !iter.IsAtEnd(); |
| 3031 iter.Advance()) { | 3026 iter.Advance()) { |
| 3032 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) { | 3027 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) { |
| 3033 return JSProxy::SetPropertyViaPrototypesWithHandler( | 3028 return JSProxy::SetPropertyViaPrototypesWithHandler( |
| 3034 Handle<JSProxy>::cast(PrototypeIterator::GetCurrent(iter)), object, | 3029 Handle<JSProxy>::cast(PrototypeIterator::GetCurrent(iter)), object, |
| 3035 isolate->factory()->Uint32ToString(index), // name | 3030 isolate->factory()->Uint32ToString(index), // name |
| 3036 value, NONE, strict_mode, found); | 3031 value, strict_mode, found); |
| 3037 } | 3032 } |
| 3038 Handle<JSObject> js_proto = | 3033 Handle<JSObject> js_proto = |
| 3039 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); | 3034 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); |
| 3040 if (!js_proto->HasDictionaryElements()) { | 3035 if (!js_proto->HasDictionaryElements()) { |
| 3041 continue; | 3036 continue; |
| 3042 } | 3037 } |
| 3043 Handle<SeededNumberDictionary> dictionary(js_proto->element_dictionary()); | 3038 Handle<SeededNumberDictionary> dictionary(js_proto->element_dictionary()); |
| 3044 int entry = dictionary->FindEntry(index); | 3039 int entry = dictionary->FindEntry(index); |
| 3045 if (entry != SeededNumberDictionary::kNotFound) { | 3040 if (entry != SeededNumberDictionary::kNotFound) { |
| 3046 PropertyDetails details = dictionary->DetailsAt(entry); | 3041 PropertyDetails details = dictionary->DetailsAt(entry); |
| 3047 if (details.type() == CALLBACKS) { | 3042 if (details.type() == CALLBACKS) { |
| 3048 *found = true; | 3043 *found = true; |
| 3049 Handle<Object> structure(dictionary->ValueAt(entry), isolate); | 3044 Handle<Object> structure(dictionary->ValueAt(entry), isolate); |
| 3050 return SetElementWithCallback(object, structure, index, value, js_proto, | 3045 return SetElementWithCallback(object, structure, index, value, js_proto, |
| 3051 strict_mode); | 3046 strict_mode); |
| 3052 } | 3047 } |
| 3053 } | 3048 } |
| 3054 } | 3049 } |
| 3055 *found = false; | 3050 *found = false; |
| 3056 return isolate->factory()->the_hole_value(); | 3051 return isolate->factory()->the_hole_value(); |
| 3057 } | 3052 } |
| 3058 | 3053 |
| 3059 | 3054 |
| 3060 MaybeHandle<Object> JSObject::SetPropertyViaPrototypes( | 3055 MaybeHandle<Object> JSObject::SetPropertyViaPrototypes( |
| 3061 Handle<JSObject> object, | 3056 Handle<JSObject> object, |
| 3062 Handle<Name> name, | 3057 Handle<Name> name, |
| 3063 Handle<Object> value, | 3058 Handle<Object> value, |
| 3064 PropertyAttributes attributes, | |
| 3065 StrictMode strict_mode, | 3059 StrictMode strict_mode, |
| 3066 bool* done) { | 3060 bool* done) { |
| 3067 Isolate* isolate = object->GetIsolate(); | 3061 Isolate* isolate = object->GetIsolate(); |
| 3068 | 3062 |
| 3069 *done = false; | 3063 *done = false; |
| 3070 // We could not find an own property, so let's check whether there is an | 3064 // We could not find an own property, so let's check whether there is an |
| 3071 // accessor that wants to handle the property, or whether the property is | 3065 // accessor that wants to handle the property, or whether the property is |
| 3072 // read-only on the prototype chain. | 3066 // read-only on the prototype chain. |
| 3073 LookupResult result(isolate); | 3067 LookupResult result(isolate); |
| 3074 object->LookupRealNamedPropertyInPrototypes(name, &result); | 3068 object->LookupRealNamedPropertyInPrototypes(name, &result); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 3091 Handle<Object> callback_object(result.GetCallbackObject(), isolate); | 3085 Handle<Object> callback_object(result.GetCallbackObject(), isolate); |
| 3092 return SetPropertyWithCallback(object, name, value, | 3086 return SetPropertyWithCallback(object, name, value, |
| 3093 handle(result.holder()), | 3087 handle(result.holder()), |
| 3094 callback_object, strict_mode); | 3088 callback_object, strict_mode); |
| 3095 } | 3089 } |
| 3096 break; | 3090 break; |
| 3097 } | 3091 } |
| 3098 case HANDLER: { | 3092 case HANDLER: { |
| 3099 Handle<JSProxy> proxy(result.proxy()); | 3093 Handle<JSProxy> proxy(result.proxy()); |
| 3100 return JSProxy::SetPropertyViaPrototypesWithHandler( | 3094 return JSProxy::SetPropertyViaPrototypesWithHandler( |
| 3101 proxy, object, name, value, attributes, strict_mode, done); | 3095 proxy, object, name, value, strict_mode, done); |
| 3102 } | 3096 } |
| 3103 case NONEXISTENT: | 3097 case NONEXISTENT: |
| 3104 UNREACHABLE(); | 3098 UNREACHABLE(); |
| 3105 break; | 3099 break; |
| 3106 } | 3100 } |
| 3107 } | 3101 } |
| 3108 | 3102 |
| 3109 // If we get here with *done true, we have encountered a read-only property. | 3103 // If we get here with *done true, we have encountered a read-only property. |
| 3110 if (*done) { | 3104 if (*done) { |
| 3111 if (strict_mode == SLOPPY) return value; | 3105 if (strict_mode == SLOPPY) return value; |
| (...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3523 if (result->IsFound()) return; | 3517 if (result->IsFound()) return; |
| 3524 } | 3518 } |
| 3525 result->NotFound(); | 3519 result->NotFound(); |
| 3526 } | 3520 } |
| 3527 | 3521 |
| 3528 | 3522 |
| 3529 MaybeHandle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object, | 3523 MaybeHandle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object, |
| 3530 LookupResult* result, | 3524 LookupResult* result, |
| 3531 Handle<Name> key, | 3525 Handle<Name> key, |
| 3532 Handle<Object> value, | 3526 Handle<Object> value, |
| 3533 PropertyAttributes attributes, | |
| 3534 StrictMode strict_mode, | 3527 StrictMode strict_mode, |
| 3535 StoreFromKeyed store_mode) { | 3528 StoreFromKeyed store_mode) { |
| 3536 if (result->IsHandler()) { | 3529 if (result->IsHandler()) { |
| 3537 return JSProxy::SetPropertyWithHandler(handle(result->proxy()), | 3530 return JSProxy::SetPropertyWithHandler(handle(result->proxy()), object, key, |
| 3538 object, key, value, attributes, strict_mode); | 3531 value, strict_mode); |
| 3539 } else { | 3532 } else { |
| 3540 return JSObject::SetPropertyForResult(Handle<JSObject>::cast(object), | 3533 return JSObject::SetPropertyForResult(Handle<JSObject>::cast(object), |
| 3541 result, key, value, attributes, strict_mode, store_mode); | 3534 result, key, value, strict_mode, |
| 3535 store_mode); |
| 3542 } | 3536 } |
| 3543 } | 3537 } |
| 3544 | 3538 |
| 3545 | 3539 |
| 3546 bool JSProxy::HasPropertyWithHandler(Handle<JSProxy> proxy, Handle<Name> name) { | 3540 bool JSProxy::HasPropertyWithHandler(Handle<JSProxy> proxy, Handle<Name> name) { |
| 3547 Isolate* isolate = proxy->GetIsolate(); | 3541 Isolate* isolate = proxy->GetIsolate(); |
| 3548 | 3542 |
| 3549 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 3543 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 3550 if (name->IsSymbol()) return false; | 3544 if (name->IsSymbol()) return false; |
| 3551 | 3545 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3562 | 3556 |
| 3563 return result->BooleanValue(); | 3557 return result->BooleanValue(); |
| 3564 } | 3558 } |
| 3565 | 3559 |
| 3566 | 3560 |
| 3567 MaybeHandle<Object> JSProxy::SetPropertyWithHandler( | 3561 MaybeHandle<Object> JSProxy::SetPropertyWithHandler( |
| 3568 Handle<JSProxy> proxy, | 3562 Handle<JSProxy> proxy, |
| 3569 Handle<JSReceiver> receiver, | 3563 Handle<JSReceiver> receiver, |
| 3570 Handle<Name> name, | 3564 Handle<Name> name, |
| 3571 Handle<Object> value, | 3565 Handle<Object> value, |
| 3572 PropertyAttributes attributes, | |
| 3573 StrictMode strict_mode) { | 3566 StrictMode strict_mode) { |
| 3574 Isolate* isolate = proxy->GetIsolate(); | 3567 Isolate* isolate = proxy->GetIsolate(); |
| 3575 | 3568 |
| 3576 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 3569 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 3577 if (name->IsSymbol()) return value; | 3570 if (name->IsSymbol()) return value; |
| 3578 | 3571 |
| 3579 Handle<Object> args[] = { receiver, name, value }; | 3572 Handle<Object> args[] = { receiver, name, value }; |
| 3580 RETURN_ON_EXCEPTION( | 3573 RETURN_ON_EXCEPTION( |
| 3581 isolate, | 3574 isolate, |
| 3582 CallTrap(proxy, | 3575 CallTrap(proxy, |
| 3583 "set", | 3576 "set", |
| 3584 isolate->derived_set_trap(), | 3577 isolate->derived_set_trap(), |
| 3585 ARRAY_SIZE(args), | 3578 ARRAY_SIZE(args), |
| 3586 args), | 3579 args), |
| 3587 Object); | 3580 Object); |
| 3588 | 3581 |
| 3589 return value; | 3582 return value; |
| 3590 } | 3583 } |
| 3591 | 3584 |
| 3592 | 3585 |
| 3593 MaybeHandle<Object> JSProxy::SetPropertyViaPrototypesWithHandler( | 3586 MaybeHandle<Object> JSProxy::SetPropertyViaPrototypesWithHandler( |
| 3594 Handle<JSProxy> proxy, | 3587 Handle<JSProxy> proxy, |
| 3595 Handle<JSReceiver> receiver, | 3588 Handle<JSReceiver> receiver, |
| 3596 Handle<Name> name, | 3589 Handle<Name> name, |
| 3597 Handle<Object> value, | 3590 Handle<Object> value, |
| 3598 PropertyAttributes attributes, | |
| 3599 StrictMode strict_mode, | 3591 StrictMode strict_mode, |
| 3600 bool* done) { | 3592 bool* done) { |
| 3601 Isolate* isolate = proxy->GetIsolate(); | 3593 Isolate* isolate = proxy->GetIsolate(); |
| 3602 Handle<Object> handler(proxy->handler(), isolate); // Trap might morph proxy. | 3594 Handle<Object> handler(proxy->handler(), isolate); // Trap might morph proxy. |
| 3603 | 3595 |
| 3604 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 3596 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 3605 if (name->IsSymbol()) { | 3597 if (name->IsSymbol()) { |
| 3606 *done = false; | 3598 *done = false; |
| 3607 return isolate->factory()->the_hole_value(); | 3599 return isolate->factory()->the_hole_value(); |
| 3608 } | 3600 } |
| (...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4052 ConvertAndSetOwnProperty(lookup, name, value, attributes); | 4044 ConvertAndSetOwnProperty(lookup, name, value, attributes); |
| 4053 } | 4045 } |
| 4054 } | 4046 } |
| 4055 | 4047 |
| 4056 | 4048 |
| 4057 MaybeHandle<Object> JSObject::SetPropertyForResult( | 4049 MaybeHandle<Object> JSObject::SetPropertyForResult( |
| 4058 Handle<JSObject> object, | 4050 Handle<JSObject> object, |
| 4059 LookupResult* lookup, | 4051 LookupResult* lookup, |
| 4060 Handle<Name> name, | 4052 Handle<Name> name, |
| 4061 Handle<Object> value, | 4053 Handle<Object> value, |
| 4062 PropertyAttributes attributes, | |
| 4063 StrictMode strict_mode, | 4054 StrictMode strict_mode, |
| 4064 StoreFromKeyed store_mode) { | 4055 StoreFromKeyed store_mode) { |
| 4065 Isolate* isolate = object->GetIsolate(); | 4056 Isolate* isolate = object->GetIsolate(); |
| 4066 | 4057 |
| 4067 // Make sure that the top context does not change when doing callbacks or | 4058 // Make sure that the top context does not change when doing callbacks or |
| 4068 // interceptor calls. | 4059 // interceptor calls. |
| 4069 AssertNoContextChange ncc(isolate); | 4060 AssertNoContextChange ncc(isolate); |
| 4070 | 4061 |
| 4071 // Optimization for 2-byte strings often used as keys in a decompression | 4062 // Optimization for 2-byte strings often used as keys in a decompression |
| 4072 // dictionary. We internalize these short keys to avoid constantly | 4063 // dictionary. We internalize these short keys to avoid constantly |
| 4073 // reallocating them. | 4064 // reallocating them. |
| 4074 if (name->IsString() && !name->IsInternalizedString() && | 4065 if (name->IsString() && !name->IsInternalizedString() && |
| 4075 Handle<String>::cast(name)->length() <= 2) { | 4066 Handle<String>::cast(name)->length() <= 2) { |
| 4076 name = isolate->factory()->InternalizeString(Handle<String>::cast(name)); | 4067 name = isolate->factory()->InternalizeString(Handle<String>::cast(name)); |
| 4077 } | 4068 } |
| 4078 | 4069 |
| 4079 // Check access rights if needed. | 4070 // Check access rights if needed. |
| 4080 if (object->IsAccessCheckNeeded()) { | 4071 if (object->IsAccessCheckNeeded()) { |
| 4081 if (!isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) { | 4072 if (!isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) { |
| 4082 return SetPropertyWithFailedAccessCheck(object, lookup, name, value, | 4073 return SetPropertyWithFailedAccessCheck(object, lookup, name, value, |
| 4083 true, strict_mode); | 4074 true, strict_mode); |
| 4084 } | 4075 } |
| 4085 } | 4076 } |
| 4086 | 4077 |
| 4087 if (object->IsJSGlobalProxy()) { | 4078 if (object->IsJSGlobalProxy()) { |
| 4088 Handle<Object> proto(object->GetPrototype(), isolate); | 4079 Handle<Object> proto(object->GetPrototype(), isolate); |
| 4089 if (proto->IsNull()) return value; | 4080 if (proto->IsNull()) return value; |
| 4090 ASSERT(proto->IsJSGlobalObject()); | 4081 ASSERT(proto->IsJSGlobalObject()); |
| 4091 return SetPropertyForResult(Handle<JSObject>::cast(proto), | 4082 return SetPropertyForResult(Handle<JSObject>::cast(proto), lookup, name, |
| 4092 lookup, name, value, attributes, strict_mode, store_mode); | 4083 value, strict_mode, store_mode); |
| 4093 } | 4084 } |
| 4094 | 4085 |
| 4095 ASSERT(!lookup->IsFound() || lookup->holder() == *object || | 4086 ASSERT(!lookup->IsFound() || lookup->holder() == *object || |
| 4096 lookup->holder()->map()->is_hidden_prototype()); | 4087 lookup->holder()->map()->is_hidden_prototype()); |
| 4097 | 4088 |
| 4098 if (!lookup->IsProperty() && !object->IsJSContextExtensionObject()) { | 4089 if (!lookup->IsProperty() && !object->IsJSContextExtensionObject()) { |
| 4099 bool done = false; | 4090 bool done = false; |
| 4100 Handle<Object> result_object; | 4091 Handle<Object> result_object; |
| 4101 ASSIGN_RETURN_ON_EXCEPTION( | 4092 ASSIGN_RETURN_ON_EXCEPTION( |
| 4102 isolate, result_object, | 4093 isolate, result_object, |
| 4103 SetPropertyViaPrototypes( | 4094 SetPropertyViaPrototypes(object, name, value, strict_mode, &done), |
| 4104 object, name, value, attributes, strict_mode, &done), | |
| 4105 Object); | 4095 Object); |
| 4106 if (done) return result_object; | 4096 if (done) return result_object; |
| 4107 } | 4097 } |
| 4108 | 4098 |
| 4109 if (!lookup->IsFound()) { | 4099 if (!lookup->IsFound()) { |
| 4110 // Neither properties nor transitions found. | 4100 // Neither properties nor transitions found. |
| 4111 return AddPropertyInternal( | 4101 return AddPropertyInternal(object, name, value, NONE, strict_mode, |
| 4112 object, name, value, attributes, strict_mode, store_mode); | 4102 store_mode); |
| 4113 } | 4103 } |
| 4114 | 4104 |
| 4115 if (lookup->IsProperty() && lookup->IsReadOnly()) { | 4105 if (lookup->IsProperty() && lookup->IsReadOnly()) { |
| 4116 if (strict_mode == STRICT) { | 4106 if (strict_mode == STRICT) { |
| 4117 Handle<Object> args[] = { name, object }; | 4107 Handle<Object> args[] = { name, object }; |
| 4118 Handle<Object> error = isolate->factory()->NewTypeError( | 4108 Handle<Object> error = isolate->factory()->NewTypeError( |
| 4119 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); | 4109 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); |
| 4120 return isolate->Throw<Object>(error); | 4110 return isolate->Throw<Object>(error); |
| 4121 } else { | 4111 } else { |
| 4122 return value; | 4112 return value; |
| 4123 } | 4113 } |
| 4124 } | 4114 } |
| 4125 | 4115 |
| 4126 Handle<Object> old_value = isolate->factory()->the_hole_value(); | 4116 Handle<Object> old_value = isolate->factory()->the_hole_value(); |
| 4127 bool is_observed = object->map()->is_observed() && | 4117 bool is_observed = object->map()->is_observed() && |
| 4128 *name != isolate->heap()->hidden_string(); | 4118 *name != isolate->heap()->hidden_string(); |
| 4129 if (is_observed && lookup->IsDataProperty()) { | 4119 if (is_observed && lookup->IsDataProperty()) { |
| 4130 old_value = Object::GetPropertyOrElement(object, name).ToHandleChecked(); | 4120 old_value = Object::GetPropertyOrElement(object, name).ToHandleChecked(); |
| 4131 } | 4121 } |
| 4132 | 4122 |
| 4133 // This is a real property that is not read-only, or it is a | 4123 // This is a real property that is not read-only, or it is a |
| 4134 // transition or null descriptor and there are no setters in the prototypes. | 4124 // transition or null descriptor and there are no setters in the prototypes. |
| 4135 MaybeHandle<Object> maybe_result = value; | 4125 MaybeHandle<Object> maybe_result = value; |
| 4136 if (lookup->IsTransition()) { | 4126 if (lookup->IsTransition()) { |
| 4137 maybe_result = SetPropertyUsingTransition(handle(lookup->holder()), lookup, | 4127 maybe_result = SetPropertyUsingTransition(handle(lookup->holder()), lookup, |
| 4138 name, value, attributes); | 4128 name, value, NONE); |
| 4139 } else { | 4129 } else { |
| 4140 switch (lookup->type()) { | 4130 switch (lookup->type()) { |
| 4141 case NORMAL: | 4131 case NORMAL: |
| 4142 SetNormalizedProperty(handle(lookup->holder()), lookup, value); | 4132 SetNormalizedProperty(handle(lookup->holder()), lookup, value); |
| 4143 break; | 4133 break; |
| 4144 case FIELD: | 4134 case FIELD: |
| 4145 SetPropertyToField(lookup, value); | 4135 SetPropertyToField(lookup, value); |
| 4146 break; | 4136 break; |
| 4147 case CONSTANT: | 4137 case CONSTANT: |
| 4148 // Only replace the constant if necessary. | 4138 // Only replace the constant if necessary. |
| 4149 if (*value == lookup->GetConstant()) return value; | 4139 if (*value == lookup->GetConstant()) return value; |
| 4150 SetPropertyToField(lookup, value); | 4140 SetPropertyToField(lookup, value); |
| 4151 break; | 4141 break; |
| 4152 case CALLBACKS: { | 4142 case CALLBACKS: { |
| 4153 Handle<Object> callback_object(lookup->GetCallbackObject(), isolate); | 4143 Handle<Object> callback_object(lookup->GetCallbackObject(), isolate); |
| 4154 return SetPropertyWithCallback(object, name, value, | 4144 return SetPropertyWithCallback(object, name, value, |
| 4155 handle(lookup->holder()), | 4145 handle(lookup->holder()), |
| 4156 callback_object, strict_mode); | 4146 callback_object, strict_mode); |
| 4157 } | 4147 } |
| 4158 case INTERCEPTOR: | 4148 case INTERCEPTOR: |
| 4159 maybe_result = SetPropertyWithInterceptor( | 4149 maybe_result = SetPropertyWithInterceptor(handle(lookup->holder()), |
| 4160 handle(lookup->holder()), name, value, attributes, strict_mode); | 4150 name, value, strict_mode); |
| 4161 break; | 4151 break; |
| 4162 case HANDLER: | 4152 case HANDLER: |
| 4163 case NONEXISTENT: | 4153 case NONEXISTENT: |
| 4164 UNREACHABLE(); | 4154 UNREACHABLE(); |
| 4165 } | 4155 } |
| 4166 } | 4156 } |
| 4167 | 4157 |
| 4168 Handle<Object> result; | 4158 Handle<Object> result; |
| 4169 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, maybe_result, Object); | 4159 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, maybe_result, Object); |
| 4170 | 4160 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 4201 LookupIterator it(object, name, LookupIterator::CHECK_OWN_REAL); | 4191 LookupIterator it(object, name, LookupIterator::CHECK_OWN_REAL); |
| 4202 GetPropertyAttributes(&it); | 4192 GetPropertyAttributes(&it); |
| 4203 ASSERT(!it.IsFound()); | 4193 ASSERT(!it.IsFound()); |
| 4204 ASSERT(object->map()->is_extensible()); | 4194 ASSERT(object->map()->is_extensible()); |
| 4205 #endif | 4195 #endif |
| 4206 SetOwnPropertyIgnoreAttributes(object, name, value, attributes, store_mode, | 4196 SetOwnPropertyIgnoreAttributes(object, name, value, attributes, store_mode, |
| 4207 OMIT_EXTENSIBILITY_CHECK).Check(); | 4197 OMIT_EXTENSIBILITY_CHECK).Check(); |
| 4208 } | 4198 } |
| 4209 | 4199 |
| 4210 | 4200 |
| 4211 // Set a real own property, even if it is READ_ONLY. If the property is not | 4201 // Reconfigures a property to a data property with attributes, even if it is not |
| 4212 // present, add it with attributes NONE. This code is an exact clone of | 4202 // reconfigurable. |
| 4213 // SetProperty, with the check for IsReadOnly and the check for a | |
| 4214 // callback setter removed. The two lines looking up the LookupResult | |
| 4215 // result are also added. If one of the functions is changed, the other | |
| 4216 // should be. | |
| 4217 MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes( | 4203 MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes( |
| 4218 Handle<JSObject> object, | 4204 Handle<JSObject> object, |
| 4219 Handle<Name> name, | 4205 Handle<Name> name, |
| 4220 Handle<Object> value, | 4206 Handle<Object> value, |
| 4221 PropertyAttributes attributes, | 4207 PropertyAttributes attributes, |
| 4222 StoreMode mode, | 4208 StoreMode mode, |
| 4223 ExtensibilityCheck extensibility_check, | 4209 ExtensibilityCheck extensibility_check, |
| 4224 StoreFromKeyed store_from_keyed, | 4210 StoreFromKeyed store_from_keyed, |
| 4225 ExecutableAccessorInfoHandling handling) { | 4211 ExecutableAccessorInfoHandling handling) { |
| 4226 Isolate* isolate = object->GetIsolate(); | 4212 Isolate* isolate = object->GetIsolate(); |
| (...skipping 1720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5947 Handle<Object> value = | 5933 Handle<Object> value = |
| 5948 Object::GetProperty(copy, key_string).ToHandleChecked(); | 5934 Object::GetProperty(copy, key_string).ToHandleChecked(); |
| 5949 if (value->IsJSObject()) { | 5935 if (value->IsJSObject()) { |
| 5950 Handle<JSObject> result; | 5936 Handle<JSObject> result; |
| 5951 ASSIGN_RETURN_ON_EXCEPTION( | 5937 ASSIGN_RETURN_ON_EXCEPTION( |
| 5952 isolate, result, | 5938 isolate, result, |
| 5953 VisitElementOrProperty(copy, Handle<JSObject>::cast(value)), | 5939 VisitElementOrProperty(copy, Handle<JSObject>::cast(value)), |
| 5954 JSObject); | 5940 JSObject); |
| 5955 if (copying) { | 5941 if (copying) { |
| 5956 // Creating object copy for literals. No strict mode needed. | 5942 // Creating object copy for literals. No strict mode needed. |
| 5957 JSObject::SetProperty( | 5943 JSObject::SetProperty(copy, key_string, result, SLOPPY).Assert(); |
| 5958 copy, key_string, result, NONE, SLOPPY).Assert(); | |
| 5959 } | 5944 } |
| 5960 } | 5945 } |
| 5961 } | 5946 } |
| 5962 } | 5947 } |
| 5963 | 5948 |
| 5964 // Deep copy own elements. | 5949 // Deep copy own elements. |
| 5965 // Pixel elements cannot be created using an object literal. | 5950 // Pixel elements cannot be created using an object literal. |
| 5966 ASSERT(!copy->HasExternalArrayElements()); | 5951 ASSERT(!copy->HasExternalArrayElements()); |
| 5967 switch (kind) { | 5952 switch (kind) { |
| 5968 case FAST_SMI_ELEMENTS: | 5953 case FAST_SMI_ELEMENTS: |
| (...skipping 5831 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11800 for (int i = indices.length() - 1; i >= 0; i--) { | 11785 for (int i = indices.length() - 1; i >= 0; i--) { |
| 11801 // Skip deletions where the property was an accessor, leaving holes | 11786 // Skip deletions where the property was an accessor, leaving holes |
| 11802 // in the array of old values. | 11787 // in the array of old values. |
| 11803 if (old_values[i]->IsTheHole()) continue; | 11788 if (old_values[i]->IsTheHole()) continue; |
| 11804 JSObject::SetElement( | 11789 JSObject::SetElement( |
| 11805 deleted, indices[i] - index, old_values[i], NONE, SLOPPY).Assert(); | 11790 deleted, indices[i] - index, old_values[i], NONE, SLOPPY).Assert(); |
| 11806 } | 11791 } |
| 11807 | 11792 |
| 11808 SetProperty(deleted, isolate->factory()->length_string(), | 11793 SetProperty(deleted, isolate->factory()->length_string(), |
| 11809 isolate->factory()->NewNumberFromUint(delete_count), | 11794 isolate->factory()->NewNumberFromUint(delete_count), |
| 11810 NONE, SLOPPY).Assert(); | 11795 STRICT).Assert(); |
| 11811 } | 11796 } |
| 11812 | 11797 |
| 11813 EnqueueSpliceRecord(array, index, deleted, add_count); | 11798 EnqueueSpliceRecord(array, index, deleted, add_count); |
| 11814 | 11799 |
| 11815 return hresult; | 11800 return hresult; |
| 11816 } | 11801 } |
| 11817 | 11802 |
| 11818 | 11803 |
| 11819 Handle<Map> Map::GetPrototypeTransition(Handle<Map> map, | 11804 Handle<Map> Map::GetPrototypeTransition(Handle<Map> map, |
| 11820 Handle<Object> prototype) { | 11805 Handle<Object> prototype) { |
| (...skipping 5169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16990 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16975 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 16991 static const char* error_messages_[] = { | 16976 static const char* error_messages_[] = { |
| 16992 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16977 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 16993 }; | 16978 }; |
| 16994 #undef ERROR_MESSAGES_TEXTS | 16979 #undef ERROR_MESSAGES_TEXTS |
| 16995 return error_messages_[reason]; | 16980 return error_messages_[reason]; |
| 16996 } | 16981 } |
| 16997 | 16982 |
| 16998 | 16983 |
| 16999 } } // namespace v8::internal | 16984 } } // namespace v8::internal |
| OLD | NEW |