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 1963 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1974 // Get AccessorPair if present. | 1974 // Get AccessorPair if present. |
1975 maybe_accessors = JSObject::GetOwnElementAccessorPair(obj, index); | 1975 maybe_accessors = JSObject::GetOwnElementAccessorPair(obj, index); |
1976 | 1976 |
1977 // Get value if not an AccessorPair. | 1977 // Get value if not an AccessorPair. |
1978 if (maybe_accessors.is_null()) { | 1978 if (maybe_accessors.is_null()) { |
1979 ASSIGN_RETURN_ON_EXCEPTION(isolate, value, | 1979 ASSIGN_RETURN_ON_EXCEPTION(isolate, value, |
1980 Runtime::GetElementOrCharAt(isolate, obj, index), Object); | 1980 Runtime::GetElementOrCharAt(isolate, obj, index), Object); |
1981 } | 1981 } |
1982 } else { | 1982 } else { |
1983 // Get attributes. | 1983 // Get attributes. |
1984 LookupIterator it(obj, name, LookupIterator::CHECK_HIDDEN); | 1984 LookupIterator it(obj, name, LookupIterator::HIDDEN); |
1985 Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(&it); | 1985 Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(&it); |
1986 if (!maybe.has_value) return MaybeHandle<Object>(); | 1986 if (!maybe.has_value) return MaybeHandle<Object>(); |
1987 attrs = maybe.value; | 1987 attrs = maybe.value; |
1988 if (attrs == ABSENT) return factory->undefined_value(); | 1988 if (attrs == ABSENT) return factory->undefined_value(); |
1989 | 1989 |
1990 // Get AccessorPair if present. | 1990 // Get AccessorPair if present. |
1991 if (it.state() == LookupIterator::PROPERTY && | 1991 if (it.state() == LookupIterator::PROPERTY && |
1992 it.property_kind() == LookupIterator::ACCESSOR && | 1992 it.property_kind() == LookupIterator::ACCESSOR && |
1993 it.GetAccessors()->IsAccessorPair()) { | 1993 it.GetAccessors()->IsAccessorPair()) { |
1994 maybe_accessors = Handle<AccessorPair>::cast(it.GetAccessors()); | 1994 maybe_accessors = Handle<AccessorPair>::cast(it.GetAccessors()); |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2172 return isolate->Throw(*error); | 2172 return isolate->Throw(*error); |
2173 } | 2173 } |
2174 | 2174 |
2175 | 2175 |
2176 // May throw a RedeclarationError. | 2176 // May throw a RedeclarationError. |
2177 static Object* DeclareGlobals(Isolate* isolate, Handle<GlobalObject> global, | 2177 static Object* DeclareGlobals(Isolate* isolate, Handle<GlobalObject> global, |
2178 Handle<String> name, Handle<Object> value, | 2178 Handle<String> name, Handle<Object> value, |
2179 PropertyAttributes attr, bool is_var, | 2179 PropertyAttributes attr, bool is_var, |
2180 bool is_const, bool is_function) { | 2180 bool is_const, bool is_function) { |
2181 // Do the lookup own properties only, see ES5 erratum. | 2181 // Do the lookup own properties only, see ES5 erratum. |
2182 LookupIterator it(global, name, LookupIterator::CHECK_HIDDEN_PROPERTY); | 2182 LookupIterator it(global, name, LookupIterator::HIDDEN_PROPERTY); |
2183 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); | 2183 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); |
2184 DCHECK(maybe.has_value); | 2184 DCHECK(maybe.has_value); |
2185 PropertyAttributes old_attributes = maybe.value; | 2185 PropertyAttributes old_attributes = maybe.value; |
2186 | 2186 |
2187 if (old_attributes != ABSENT) { | 2187 if (old_attributes != ABSENT) { |
2188 // The name was declared before; check for conflicting re-declarations. | 2188 // The name was declared before; check for conflicting re-declarations. |
2189 if (is_const) return ThrowRedeclarationError(isolate, name); | 2189 if (is_const) return ThrowRedeclarationError(isolate, name); |
2190 | 2190 |
2191 // Skip var re-declarations. | 2191 // Skip var re-declarations. |
2192 if (is_var) return isolate->heap()->undefined_value(); | 2192 if (is_var) return isolate->heap()->undefined_value(); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2302 // All constants are declared with an initial value. The name | 2302 // All constants are declared with an initial value. The name |
2303 // of the constant is the first argument and the initial value | 2303 // of the constant is the first argument and the initial value |
2304 // is the second. | 2304 // is the second. |
2305 RUNTIME_ASSERT(args.length() == 2); | 2305 RUNTIME_ASSERT(args.length() == 2); |
2306 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); | 2306 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); |
2307 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); | 2307 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); |
2308 | 2308 |
2309 Handle<GlobalObject> global = isolate->global_object(); | 2309 Handle<GlobalObject> global = isolate->global_object(); |
2310 | 2310 |
2311 // Lookup the property as own on the global object. | 2311 // Lookup the property as own on the global object. |
2312 LookupIterator it(global, name, LookupIterator::CHECK_HIDDEN_PROPERTY); | 2312 LookupIterator it(global, name, LookupIterator::HIDDEN_PROPERTY); |
2313 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); | 2313 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); |
2314 DCHECK(maybe.has_value); | 2314 DCHECK(maybe.has_value); |
2315 PropertyAttributes old_attributes = maybe.value; | 2315 PropertyAttributes old_attributes = maybe.value; |
2316 | 2316 |
2317 PropertyAttributes attr = | 2317 PropertyAttributes attr = |
2318 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); | 2318 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); |
2319 // 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 |
2320 // allow setting the value without invoking an accessor. | 2320 // allow setting the value without invoking an accessor. |
2321 if (it.IsFound()) { | 2321 if (it.IsFound()) { |
2322 // Ignore if we can't reconfigure the value. | 2322 // Ignore if we can't reconfigure the value. |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2452 DCHECK(context_arg->has_extension()); | 2452 DCHECK(context_arg->has_extension()); |
2453 if (attributes == ABSENT) { | 2453 if (attributes == ABSENT) { |
2454 holder = handle(context_arg->extension(), isolate); | 2454 holder = handle(context_arg->extension(), isolate); |
2455 } else { | 2455 } else { |
2456 // For JSContextExtensionObjects, the initializer can be run multiple times | 2456 // For JSContextExtensionObjects, the initializer can be run multiple times |
2457 // if in a for loop: for (var i = 0; i < 2; i++) { const x = i; }. Only the | 2457 // if in a for loop: for (var i = 0; i < 2; i++) { const x = i; }. Only the |
2458 // first assignment should go through. For JSGlobalObjects, additionally any | 2458 // first assignment should go through. For JSGlobalObjects, additionally any |
2459 // code can run in between that modifies the declared property. | 2459 // code can run in between that modifies the declared property. |
2460 DCHECK(holder->IsJSGlobalObject() || holder->IsJSContextExtensionObject()); | 2460 DCHECK(holder->IsJSGlobalObject() || holder->IsJSContextExtensionObject()); |
2461 | 2461 |
2462 LookupIterator it(holder, name, LookupIterator::CHECK_HIDDEN_PROPERTY); | 2462 LookupIterator it(holder, name, LookupIterator::HIDDEN_PROPERTY); |
2463 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); | 2463 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); |
2464 if (!maybe.has_value) return isolate->heap()->exception(); | 2464 if (!maybe.has_value) return isolate->heap()->exception(); |
2465 PropertyAttributes old_attributes = maybe.value; | 2465 PropertyAttributes old_attributes = maybe.value; |
2466 | 2466 |
2467 // Ignore if we can't reconfigure the value. | 2467 // Ignore if we can't reconfigure the value. |
2468 if ((old_attributes & DONT_DELETE) != 0) { | 2468 if ((old_attributes & DONT_DELETE) != 0) { |
2469 if ((old_attributes & READ_ONLY) != 0 || | 2469 if ((old_attributes & READ_ONLY) != 0 || |
2470 it.property_kind() == LookupIterator::ACCESSOR) { | 2470 it.property_kind() == LookupIterator::ACCESSOR) { |
2471 return *value; | 2471 return *value; |
2472 } | 2472 } |
(...skipping 2410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4883 Handle<Map> receiver_map(receiver->map(), isolate); | 4883 Handle<Map> receiver_map(receiver->map(), isolate); |
4884 KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache(); | 4884 KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache(); |
4885 int index = keyed_lookup_cache->Lookup(receiver_map, key); | 4885 int index = keyed_lookup_cache->Lookup(receiver_map, key); |
4886 if (index != -1) { | 4886 if (index != -1) { |
4887 // Doubles are not cached, so raw read the value. | 4887 // Doubles are not cached, so raw read the value. |
4888 return receiver->RawFastPropertyAt( | 4888 return receiver->RawFastPropertyAt( |
4889 FieldIndex::ForKeyedLookupCacheIndex(*receiver_map, index)); | 4889 FieldIndex::ForKeyedLookupCacheIndex(*receiver_map, index)); |
4890 } | 4890 } |
4891 // Lookup cache miss. Perform lookup and update the cache if | 4891 // Lookup cache miss. Perform lookup and update the cache if |
4892 // appropriate. | 4892 // appropriate. |
4893 LookupIterator it(receiver, key, LookupIterator::CHECK_OWN); | 4893 LookupIterator it(receiver, key, LookupIterator::OWN); |
4894 if (it.IsFound() && it.state() == LookupIterator::PROPERTY && | 4894 if (it.IsFound() && it.state() == LookupIterator::PROPERTY && |
4895 it.HasProperty() && it.property_details().type() == FIELD) { | 4895 it.HasProperty() && it.property_details().type() == FIELD) { |
4896 FieldIndex field_index = it.GetFieldIndex(); | 4896 FieldIndex field_index = it.GetFieldIndex(); |
4897 // Do not track double fields in the keyed lookup cache. Reading | 4897 // Do not track double fields in the keyed lookup cache. Reading |
4898 // double values requires boxing. | 4898 // double values requires boxing. |
4899 if (!it.representation().IsDouble()) { | 4899 if (!it.representation().IsDouble()) { |
4900 keyed_lookup_cache->Update(receiver_map, key, | 4900 keyed_lookup_cache->Update(receiver_map, key, |
4901 field_index.GetKeyedLookupCacheIndex()); | 4901 field_index.GetKeyedLookupCacheIndex()); |
4902 } | 4902 } |
4903 AllowHeapAllocation allow_allocation; | 4903 AllowHeapAllocation allow_allocation; |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5039 CONVERT_SMI_ARG_CHECKED(unchecked, 3); | 5039 CONVERT_SMI_ARG_CHECKED(unchecked, 3); |
5040 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 5040 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
5041 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); | 5041 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); |
5042 | 5042 |
5043 // Check access rights if needed. | 5043 // Check access rights if needed. |
5044 if (js_object->IsAccessCheckNeeded() && | 5044 if (js_object->IsAccessCheckNeeded() && |
5045 !isolate->MayNamedAccess(js_object, name, v8::ACCESS_SET)) { | 5045 !isolate->MayNamedAccess(js_object, name, v8::ACCESS_SET)) { |
5046 return isolate->heap()->undefined_value(); | 5046 return isolate->heap()->undefined_value(); |
5047 } | 5047 } |
5048 | 5048 |
5049 LookupIterator it(js_object, name, LookupIterator::CHECK_PROPERTY); | 5049 LookupIterator it(js_object, name, LookupIterator::OWN_PROPERTY); |
5050 | 5050 |
5051 // Take special care when attributes are different and there is already | 5051 // Take special care when attributes are different and there is already |
5052 // a property. | 5052 // a property. |
5053 if (it.IsFound() && it.HasProperty() && | 5053 if (it.IsFound() && it.HasProperty() && |
5054 it.property_kind() == LookupIterator::ACCESSOR) { | 5054 it.property_kind() == LookupIterator::ACCESSOR) { |
5055 // Use IgnoreAttributes version since a readonly property may be | 5055 // Use IgnoreAttributes version since a readonly property may be |
5056 // overridden and SetProperty does not allow this. | 5056 // overridden and SetProperty does not allow this. |
5057 Handle<Object> result; | 5057 Handle<Object> result; |
5058 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 5058 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
5059 isolate, result, | 5059 isolate, result, |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5287 CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3); | 5287 CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3); |
5288 RUNTIME_ASSERT( | 5288 RUNTIME_ASSERT( |
5289 (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 5289 (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
5290 // Compute attributes. | 5290 // Compute attributes. |
5291 PropertyAttributes attributes = | 5291 PropertyAttributes attributes = |
5292 static_cast<PropertyAttributes>(unchecked_attributes); | 5292 static_cast<PropertyAttributes>(unchecked_attributes); |
5293 | 5293 |
5294 #ifdef DEBUG | 5294 #ifdef DEBUG |
5295 uint32_t index = 0; | 5295 uint32_t index = 0; |
5296 DCHECK(!key->ToArrayIndex(&index)); | 5296 DCHECK(!key->ToArrayIndex(&index)); |
5297 LookupIterator it(object, key, LookupIterator::CHECK_PROPERTY); | 5297 LookupIterator it(object, key, LookupIterator::OWN_PROPERTY); |
5298 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); | 5298 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); |
5299 DCHECK(maybe.has_value); | 5299 DCHECK(maybe.has_value); |
5300 RUNTIME_ASSERT(!it.IsFound()); | 5300 RUNTIME_ASSERT(!it.IsFound()); |
5301 #endif | 5301 #endif |
5302 | 5302 |
5303 Handle<Object> result; | 5303 Handle<Object> result; |
5304 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 5304 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
5305 isolate, result, | 5305 isolate, result, |
5306 JSObject::SetOwnPropertyIgnoreAttributes(object, key, value, attributes)); | 5306 JSObject::SetOwnPropertyIgnoreAttributes(object, key, value, attributes)); |
5307 return *result; | 5307 return *result; |
(...skipping 11 matching lines...) Expand all Loading... |
5319 RUNTIME_ASSERT( | 5319 RUNTIME_ASSERT( |
5320 (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 5320 (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
5321 // Compute attributes. | 5321 // Compute attributes. |
5322 PropertyAttributes attributes = | 5322 PropertyAttributes attributes = |
5323 static_cast<PropertyAttributes>(unchecked_attributes); | 5323 static_cast<PropertyAttributes>(unchecked_attributes); |
5324 | 5324 |
5325 #ifdef DEBUG | 5325 #ifdef DEBUG |
5326 bool duplicate; | 5326 bool duplicate; |
5327 if (key->IsName()) { | 5327 if (key->IsName()) { |
5328 LookupIterator it(object, Handle<Name>::cast(key), | 5328 LookupIterator it(object, Handle<Name>::cast(key), |
5329 LookupIterator::CHECK_PROPERTY); | 5329 LookupIterator::OWN_PROPERTY); |
5330 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); | 5330 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); |
5331 DCHECK(maybe.has_value); | 5331 DCHECK(maybe.has_value); |
5332 duplicate = it.IsFound(); | 5332 duplicate = it.IsFound(); |
5333 } else { | 5333 } else { |
5334 uint32_t index = 0; | 5334 uint32_t index = 0; |
5335 RUNTIME_ASSERT(key->ToArrayIndex(&index)); | 5335 RUNTIME_ASSERT(key->ToArrayIndex(&index)); |
5336 Maybe<bool> maybe = JSReceiver::HasOwnElement(object, index); | 5336 Maybe<bool> maybe = JSReceiver::HasOwnElement(object, index); |
5337 if (!maybe.has_value) return isolate->heap()->exception(); | 5337 if (!maybe.has_value) return isolate->heap()->exception(); |
5338 duplicate = maybe.value; | 5338 duplicate = maybe.value; |
5339 } | 5339 } |
(...skipping 5633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10973 Handle<Object> element_or_char; | 10973 Handle<Object> element_or_char; |
10974 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 10974 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
10975 isolate, element_or_char, | 10975 isolate, element_or_char, |
10976 Runtime::GetElementOrCharAt(isolate, obj, index)); | 10976 Runtime::GetElementOrCharAt(isolate, obj, index)); |
10977 details->set(0, *element_or_char); | 10977 details->set(0, *element_or_char); |
10978 details->set( | 10978 details->set( |
10979 1, PropertyDetails(NONE, NORMAL, Representation::None()).AsSmi()); | 10979 1, PropertyDetails(NONE, NORMAL, Representation::None()).AsSmi()); |
10980 return *isolate->factory()->NewJSArrayWithElements(details); | 10980 return *isolate->factory()->NewJSArrayWithElements(details); |
10981 } | 10981 } |
10982 | 10982 |
10983 LookupIterator it(obj, name, LookupIterator::CHECK_HIDDEN); | 10983 LookupIterator it(obj, name, LookupIterator::HIDDEN); |
10984 bool has_caught = false; | 10984 bool has_caught = false; |
10985 Handle<Object> value = DebugGetProperty(&it, &has_caught); | 10985 Handle<Object> value = DebugGetProperty(&it, &has_caught); |
10986 if (!it.IsFound()) return isolate->heap()->undefined_value(); | 10986 if (!it.IsFound()) return isolate->heap()->undefined_value(); |
10987 | 10987 |
10988 Handle<Object> maybe_pair; | 10988 Handle<Object> maybe_pair; |
10989 if (it.state() == LookupIterator::PROPERTY && | 10989 if (it.state() == LookupIterator::PROPERTY && |
10990 it.property_kind() == LookupIterator::ACCESSOR) { | 10990 it.property_kind() == LookupIterator::ACCESSOR) { |
10991 maybe_pair = it.GetAccessors(); | 10991 maybe_pair = it.GetAccessors(); |
10992 } | 10992 } |
10993 | 10993 |
(...skipping 20 matching lines...) Expand all Loading... |
11014 | 11014 |
11015 | 11015 |
11016 RUNTIME_FUNCTION(Runtime_DebugGetProperty) { | 11016 RUNTIME_FUNCTION(Runtime_DebugGetProperty) { |
11017 HandleScope scope(isolate); | 11017 HandleScope scope(isolate); |
11018 | 11018 |
11019 DCHECK(args.length() == 2); | 11019 DCHECK(args.length() == 2); |
11020 | 11020 |
11021 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); | 11021 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); |
11022 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); | 11022 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); |
11023 | 11023 |
11024 LookupIterator it(obj, name, LookupIterator::CHECK_DERIVED); | 11024 LookupIterator it(obj, name); |
11025 return *DebugGetProperty(&it); | 11025 return *DebugGetProperty(&it); |
11026 } | 11026 } |
11027 | 11027 |
11028 | 11028 |
11029 // Return the property type calculated from the property details. | 11029 // Return the property type calculated from the property details. |
11030 // args[0]: smi with property details. | 11030 // args[0]: smi with property details. |
11031 RUNTIME_FUNCTION(Runtime_DebugPropertyTypeFromDetails) { | 11031 RUNTIME_FUNCTION(Runtime_DebugPropertyTypeFromDetails) { |
11032 SealHandleScope shs(isolate); | 11032 SealHandleScope shs(isolate); |
11033 DCHECK(args.length() == 1); | 11033 DCHECK(args.length() == 1); |
11034 CONVERT_PROPERTY_DETAILS_CHECKED(details, 0); | 11034 CONVERT_PROPERTY_DETAILS_CHECKED(details, 0); |
(...skipping 4611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15646 } | 15646 } |
15647 return NULL; | 15647 return NULL; |
15648 } | 15648 } |
15649 | 15649 |
15650 | 15650 |
15651 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { | 15651 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { |
15652 return &(kIntrinsicFunctions[static_cast<int>(id)]); | 15652 return &(kIntrinsicFunctions[static_cast<int>(id)]); |
15653 } | 15653 } |
15654 | 15654 |
15655 } } // namespace v8::internal | 15655 } } // namespace v8::internal |
OLD | NEW |