OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 <stdlib.h> | 5 #include <stdlib.h> |
6 #include <limits> | 6 #include <limits> |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/accessors.h" | 10 #include "src/accessors.h" |
(...skipping 1972 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1983 } | 1983 } |
1984 } else { | 1984 } else { |
1985 // Get attributes. | 1985 // Get attributes. |
1986 LookupIterator it(obj, name, LookupIterator::HIDDEN); | 1986 LookupIterator it(obj, name, LookupIterator::HIDDEN); |
1987 Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(&it); | 1987 Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(&it); |
1988 if (!maybe.has_value) return MaybeHandle<Object>(); | 1988 if (!maybe.has_value) return MaybeHandle<Object>(); |
1989 attrs = maybe.value; | 1989 attrs = maybe.value; |
1990 if (attrs == ABSENT) return factory->undefined_value(); | 1990 if (attrs == ABSENT) return factory->undefined_value(); |
1991 | 1991 |
1992 // Get AccessorPair if present. | 1992 // Get AccessorPair if present. |
1993 if (it.state() == LookupIterator::PROPERTY && | 1993 if (it.state() == LookupIterator::ACCESSOR && |
1994 it.property_kind() == LookupIterator::ACCESSOR && | |
1995 it.GetAccessors()->IsAccessorPair()) { | 1994 it.GetAccessors()->IsAccessorPair()) { |
1996 maybe_accessors = Handle<AccessorPair>::cast(it.GetAccessors()); | 1995 maybe_accessors = Handle<AccessorPair>::cast(it.GetAccessors()); |
1997 } | 1996 } |
1998 | 1997 |
1999 // Get value if not an AccessorPair. | 1998 // Get value if not an AccessorPair. |
2000 if (maybe_accessors.is_null()) { | 1999 if (maybe_accessors.is_null()) { |
2001 ASSIGN_RETURN_ON_EXCEPTION( | 2000 ASSIGN_RETURN_ON_EXCEPTION( |
2002 isolate, value, Object::GetProperty(&it), Object); | 2001 isolate, value, Object::GetProperty(&it), Object); |
2003 } | 2002 } |
2004 } | 2003 } |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2316 PropertyAttributes old_attributes = maybe.value; | 2315 PropertyAttributes old_attributes = maybe.value; |
2317 | 2316 |
2318 PropertyAttributes attr = | 2317 PropertyAttributes attr = |
2319 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); | 2318 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); |
2320 // Set the value if the property is either missing, or the property attributes | 2319 // Set the value if the property is either missing, or the property attributes |
2321 // allow setting the value without invoking an accessor. | 2320 // allow setting the value without invoking an accessor. |
2322 if (it.IsFound()) { | 2321 if (it.IsFound()) { |
2323 // Ignore if we can't reconfigure the value. | 2322 // Ignore if we can't reconfigure the value. |
2324 if ((old_attributes & DONT_DELETE) != 0) { | 2323 if ((old_attributes & DONT_DELETE) != 0) { |
2325 if ((old_attributes & READ_ONLY) != 0 || | 2324 if ((old_attributes & READ_ONLY) != 0 || |
2326 it.property_kind() == LookupIterator::ACCESSOR) { | 2325 it.state() == LookupIterator::ACCESSOR) { |
2327 return *value; | 2326 return *value; |
2328 } | 2327 } |
2329 attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY); | 2328 attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY); |
2330 } | 2329 } |
2331 } | 2330 } |
2332 | 2331 |
2333 RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes( | 2332 RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes( |
2334 global, name, value, attr)); | 2333 global, name, value, attr)); |
2335 | 2334 |
2336 return *value; | 2335 return *value; |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2461 DCHECK(holder->IsJSGlobalObject() || holder->IsJSContextExtensionObject()); | 2460 DCHECK(holder->IsJSGlobalObject() || holder->IsJSContextExtensionObject()); |
2462 | 2461 |
2463 LookupIterator it(holder, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR); | 2462 LookupIterator it(holder, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR); |
2464 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); | 2463 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); |
2465 if (!maybe.has_value) return isolate->heap()->exception(); | 2464 if (!maybe.has_value) return isolate->heap()->exception(); |
2466 PropertyAttributes old_attributes = maybe.value; | 2465 PropertyAttributes old_attributes = maybe.value; |
2467 | 2466 |
2468 // Ignore if we can't reconfigure the value. | 2467 // Ignore if we can't reconfigure the value. |
2469 if ((old_attributes & DONT_DELETE) != 0) { | 2468 if ((old_attributes & DONT_DELETE) != 0) { |
2470 if ((old_attributes & READ_ONLY) != 0 || | 2469 if ((old_attributes & READ_ONLY) != 0 || |
2471 it.property_kind() == LookupIterator::ACCESSOR) { | 2470 it.state() == LookupIterator::ACCESSOR) { |
2472 return *value; | 2471 return *value; |
2473 } | 2472 } |
2474 attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY); | 2473 attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY); |
2475 } | 2474 } |
2476 } | 2475 } |
2477 | 2476 |
2478 RETURN_FAILURE_ON_EXCEPTION( | 2477 RETURN_FAILURE_ON_EXCEPTION( |
2479 isolate, JSObject::SetOwnPropertyIgnoreAttributes( | 2478 isolate, JSObject::SetOwnPropertyIgnoreAttributes( |
2480 Handle<JSObject>::cast(holder), name, value, attr)); | 2479 Handle<JSObject>::cast(holder), name, value, attr)); |
2481 | 2480 |
(...skipping 2402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4884 KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache(); | 4883 KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache(); |
4885 int index = keyed_lookup_cache->Lookup(receiver_map, key); | 4884 int index = keyed_lookup_cache->Lookup(receiver_map, key); |
4886 if (index != -1) { | 4885 if (index != -1) { |
4887 // Doubles are not cached, so raw read the value. | 4886 // Doubles are not cached, so raw read the value. |
4888 return receiver->RawFastPropertyAt( | 4887 return receiver->RawFastPropertyAt( |
4889 FieldIndex::ForKeyedLookupCacheIndex(*receiver_map, index)); | 4888 FieldIndex::ForKeyedLookupCacheIndex(*receiver_map, index)); |
4890 } | 4889 } |
4891 // Lookup cache miss. Perform lookup and update the cache if | 4890 // Lookup cache miss. Perform lookup and update the cache if |
4892 // appropriate. | 4891 // appropriate. |
4893 LookupIterator it(receiver, key, LookupIterator::OWN); | 4892 LookupIterator it(receiver, key, LookupIterator::OWN); |
4894 if (it.IsFound() && it.state() == LookupIterator::PROPERTY && | 4893 if (it.state() == LookupIterator::DATA && |
4895 it.HasProperty() && it.property_details().type() == FIELD) { | 4894 it.property_details().type() == FIELD) { |
4896 FieldIndex field_index = it.GetFieldIndex(); | 4895 FieldIndex field_index = it.GetFieldIndex(); |
4897 // Do not track double fields in the keyed lookup cache. Reading | 4896 // Do not track double fields in the keyed lookup cache. Reading |
4898 // double values requires boxing. | 4897 // double values requires boxing. |
4899 if (!it.representation().IsDouble()) { | 4898 if (!it.representation().IsDouble()) { |
4900 keyed_lookup_cache->Update(receiver_map, key, | 4899 keyed_lookup_cache->Update(receiver_map, key, |
4901 field_index.GetKeyedLookupCacheIndex()); | 4900 field_index.GetKeyedLookupCacheIndex()); |
4902 } | 4901 } |
4903 AllowHeapAllocation allow_allocation; | 4902 AllowHeapAllocation allow_allocation; |
4904 return *JSObject::FastPropertyAt(receiver, it.representation(), | 4903 return *JSObject::FastPropertyAt(receiver, it.representation(), |
4905 field_index); | 4904 field_index); |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5043 LookupIterator it(js_object, name, LookupIterator::OWN_SKIP_INTERCEPTOR); | 5042 LookupIterator it(js_object, name, LookupIterator::OWN_SKIP_INTERCEPTOR); |
5044 if (it.IsFound() && it.state() == LookupIterator::ACCESS_CHECK) { | 5043 if (it.IsFound() && it.state() == LookupIterator::ACCESS_CHECK) { |
5045 if (!isolate->MayNamedAccess(js_object, name, v8::ACCESS_SET)) { | 5044 if (!isolate->MayNamedAccess(js_object, name, v8::ACCESS_SET)) { |
5046 return isolate->heap()->undefined_value(); | 5045 return isolate->heap()->undefined_value(); |
5047 } | 5046 } |
5048 it.Next(); | 5047 it.Next(); |
5049 } | 5048 } |
5050 | 5049 |
5051 // Take special care when attributes are different and there is already | 5050 // Take special care when attributes are different and there is already |
5052 // a property. | 5051 // a property. |
5053 if (it.IsFound() && it.HasProperty() && | 5052 if (it.state() == LookupIterator::ACCESSOR) { |
5054 it.property_kind() == LookupIterator::ACCESSOR) { | |
5055 // Use IgnoreAttributes version since a readonly property may be | 5053 // Use IgnoreAttributes version since a readonly property may be |
5056 // overridden and SetProperty does not allow this. | 5054 // overridden and SetProperty does not allow this. |
5057 Handle<Object> result; | 5055 Handle<Object> result; |
5058 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 5056 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
5059 isolate, result, | 5057 isolate, result, |
5060 JSObject::SetOwnPropertyIgnoreAttributes( | 5058 JSObject::SetOwnPropertyIgnoreAttributes( |
5061 js_object, name, obj_value, attr, | 5059 js_object, name, obj_value, attr, |
5062 JSObject::DONT_FORCE_FIELD)); | 5060 JSObject::DONT_FORCE_FIELD)); |
5063 return *result; | 5061 return *result; |
5064 } | 5062 } |
(...skipping 5826 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10891 return isolate->heap()->undefined_value(); | 10889 return isolate->heap()->undefined_value(); |
10892 } | 10890 } |
10893 | 10891 |
10894 | 10892 |
10895 static Handle<Object> DebugGetProperty(LookupIterator* it, | 10893 static Handle<Object> DebugGetProperty(LookupIterator* it, |
10896 bool* has_caught = NULL) { | 10894 bool* has_caught = NULL) { |
10897 for (; it->IsFound(); it->Next()) { | 10895 for (; it->IsFound(); it->Next()) { |
10898 switch (it->state()) { | 10896 switch (it->state()) { |
10899 case LookupIterator::NOT_FOUND: | 10897 case LookupIterator::NOT_FOUND: |
10900 case LookupIterator::TRANSITION: | 10898 case LookupIterator::TRANSITION: |
| 10899 case LookupIterator::UNKNOWN: |
10901 UNREACHABLE(); | 10900 UNREACHABLE(); |
10902 case LookupIterator::ACCESS_CHECK: | 10901 case LookupIterator::ACCESS_CHECK: |
10903 // Ignore access checks. | 10902 // Ignore access checks. |
10904 break; | 10903 break; |
10905 case LookupIterator::INTERCEPTOR: | 10904 case LookupIterator::INTERCEPTOR: |
10906 case LookupIterator::JSPROXY: | 10905 case LookupIterator::JSPROXY: |
10907 return it->isolate()->factory()->undefined_value(); | 10906 return it->isolate()->factory()->undefined_value(); |
10908 case LookupIterator::PROPERTY: | 10907 case LookupIterator::ACCESSOR: { |
10909 if (!it->HasProperty()) continue; | 10908 Handle<Object> accessors = it->GetAccessors(); |
10910 switch (it->property_kind()) { | 10909 if (!accessors->IsAccessorInfo()) { |
10911 case LookupIterator::ACCESSOR: { | 10910 return it->isolate()->factory()->undefined_value(); |
10912 Handle<Object> accessors = it->GetAccessors(); | |
10913 if (!accessors->IsAccessorInfo()) { | |
10914 return it->isolate()->factory()->undefined_value(); | |
10915 } | |
10916 MaybeHandle<Object> maybe_result = | |
10917 JSObject::GetPropertyWithAccessor(it->GetReceiver(), it->name(), | |
10918 it->GetHolder<JSObject>(), | |
10919 accessors); | |
10920 Handle<Object> result; | |
10921 if (!maybe_result.ToHandle(&result)) { | |
10922 result = | |
10923 handle(it->isolate()->pending_exception(), it->isolate()); | |
10924 it->isolate()->clear_pending_exception(); | |
10925 if (has_caught != NULL) *has_caught = true; | |
10926 } | |
10927 return result; | |
10928 } | |
10929 case LookupIterator::DATA: | |
10930 return it->GetDataValue(); | |
10931 } | 10911 } |
| 10912 MaybeHandle<Object> maybe_result = JSObject::GetPropertyWithAccessor( |
| 10913 it->GetReceiver(), it->name(), it->GetHolder<JSObject>(), |
| 10914 accessors); |
| 10915 Handle<Object> result; |
| 10916 if (!maybe_result.ToHandle(&result)) { |
| 10917 result = handle(it->isolate()->pending_exception(), it->isolate()); |
| 10918 it->isolate()->clear_pending_exception(); |
| 10919 if (has_caught != NULL) *has_caught = true; |
| 10920 } |
| 10921 return result; |
| 10922 } |
| 10923 |
| 10924 case LookupIterator::DATA: |
| 10925 return it->GetDataValue(); |
10932 } | 10926 } |
10933 } | 10927 } |
10934 | 10928 |
10935 return it->isolate()->factory()->undefined_value(); | 10929 return it->isolate()->factory()->undefined_value(); |
10936 } | 10930 } |
10937 | 10931 |
10938 | 10932 |
10939 // Get debugger related details for an object property, in the following format: | 10933 // Get debugger related details for an object property, in the following format: |
10940 // 0: Property value | 10934 // 0: Property value |
10941 // 1: Property details | 10935 // 1: Property details |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10976 1, PropertyDetails(NONE, NORMAL, Representation::None()).AsSmi()); | 10970 1, PropertyDetails(NONE, NORMAL, Representation::None()).AsSmi()); |
10977 return *isolate->factory()->NewJSArrayWithElements(details); | 10971 return *isolate->factory()->NewJSArrayWithElements(details); |
10978 } | 10972 } |
10979 | 10973 |
10980 LookupIterator it(obj, name, LookupIterator::HIDDEN); | 10974 LookupIterator it(obj, name, LookupIterator::HIDDEN); |
10981 bool has_caught = false; | 10975 bool has_caught = false; |
10982 Handle<Object> value = DebugGetProperty(&it, &has_caught); | 10976 Handle<Object> value = DebugGetProperty(&it, &has_caught); |
10983 if (!it.IsFound()) return isolate->heap()->undefined_value(); | 10977 if (!it.IsFound()) return isolate->heap()->undefined_value(); |
10984 | 10978 |
10985 Handle<Object> maybe_pair; | 10979 Handle<Object> maybe_pair; |
10986 if (it.state() == LookupIterator::PROPERTY && | 10980 if (it.state() == LookupIterator::ACCESSOR) { |
10987 it.property_kind() == LookupIterator::ACCESSOR) { | |
10988 maybe_pair = it.GetAccessors(); | 10981 maybe_pair = it.GetAccessors(); |
10989 } | 10982 } |
10990 | 10983 |
10991 // If the callback object is a fixed array then it contains JavaScript | 10984 // If the callback object is a fixed array then it contains JavaScript |
10992 // getter and/or setter. | 10985 // getter and/or setter. |
10993 bool has_js_accessors = !maybe_pair.is_null() && maybe_pair->IsAccessorPair(); | 10986 bool has_js_accessors = !maybe_pair.is_null() && maybe_pair->IsAccessorPair(); |
10994 Handle<FixedArray> details = | 10987 Handle<FixedArray> details = |
10995 isolate->factory()->NewFixedArray(has_js_accessors ? 6 : 3); | 10988 isolate->factory()->NewFixedArray(has_js_accessors ? 6 : 3); |
10996 details->set(0, *value); | 10989 details->set(0, *value); |
10997 // TODO(verwaest): Get rid of this random way of handling interceptors. | 10990 // TODO(verwaest): Get rid of this random way of handling interceptors. |
(...skipping 4649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15647 } | 15640 } |
15648 return NULL; | 15641 return NULL; |
15649 } | 15642 } |
15650 | 15643 |
15651 | 15644 |
15652 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { | 15645 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { |
15653 return &(kIntrinsicFunctions[static_cast<int>(id)]); | 15646 return &(kIntrinsicFunctions[static_cast<int>(id)]); |
15654 } | 15647 } |
15655 | 15648 |
15656 } } // namespace v8::internal | 15649 } } // namespace v8::internal |
OLD | NEW |