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 |