Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/objects.h" | 5 #include "src/objects.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 #include <iomanip> | 8 #include <iomanip> |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <sstream> | 10 #include <sstream> |
| (...skipping 1985 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1996 if (!iter.AdvanceFollowingProxies()) return Nothing<bool>(); | 1996 if (!iter.AdvanceFollowingProxies()) return Nothing<bool>(); |
| 1997 if (iter.IsAtEnd()) return Just(false); | 1997 if (iter.IsAtEnd()) return Just(false); |
| 1998 if (PrototypeIterator::GetCurrent(iter).is_identical_to(proto)) { | 1998 if (PrototypeIterator::GetCurrent(iter).is_identical_to(proto)) { |
| 1999 return Just(true); | 1999 return Just(true); |
| 2000 } | 2000 } |
| 2001 } | 2001 } |
| 2002 } | 2002 } |
| 2003 | 2003 |
| 2004 namespace { | 2004 namespace { |
| 2005 | 2005 |
| 2006 bool HasElementInArguments(Arguments* arguments, | |
| 2007 Handle<Object> search_element) { | |
| 2008 // TODO(gsathya): Maybe optimize this to be a hashtable. | |
| 2009 for (int i = 0; i < arguments->length(); i++) { | |
| 2010 if (*search_element == (*arguments)[i]) { | |
|
adamk
2017/01/12 22:43:08
Pointer equality isn't sufficient for strings. Use
gsathya
2017/01/17 19:28:59
Done.
| |
| 2011 return true; | |
| 2012 } | |
| 2013 } | |
| 2014 | |
| 2015 return false; | |
| 2016 } | |
| 2017 | |
| 2006 MUST_USE_RESULT Maybe<bool> FastAssign(Handle<JSReceiver> target, | 2018 MUST_USE_RESULT Maybe<bool> FastAssign(Handle<JSReceiver> target, |
| 2007 Handle<Object> source, bool use_set) { | 2019 Handle<Object> source, |
| 2020 Arguments* excluded_properties, | |
| 2021 bool use_set) { | |
| 2008 // Non-empty strings are the only non-JSReceivers that need to be handled | 2022 // Non-empty strings are the only non-JSReceivers that need to be handled |
| 2009 // explicitly by Object.assign. | 2023 // explicitly by Object.assign. |
| 2010 if (!source->IsJSReceiver()) { | 2024 if (!source->IsJSReceiver()) { |
| 2011 return Just(!source->IsString() || String::cast(*source)->length() == 0); | 2025 return Just(!source->IsString() || String::cast(*source)->length() == 0); |
| 2012 } | 2026 } |
| 2013 | 2027 |
| 2014 // If the target is deprecated, the object will be updated on first store. If | 2028 // If the target is deprecated, the object will be updated on first store. If |
| 2015 // the source for that store equals the target, this will invalidate the | 2029 // the source for that store equals the target, this will invalidate the |
| 2016 // cached representation of the source. Preventively upgrade the target. | 2030 // cached representation of the source. Preventively upgrade the target. |
| 2017 // Do this on each iteration since any property load could cause deprecation. | 2031 // Do this on each iteration since any property load could cause deprecation. |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2070 } | 2084 } |
| 2071 | 2085 |
| 2072 if (use_set) { | 2086 if (use_set) { |
| 2073 LookupIterator it(target, next_key, target); | 2087 LookupIterator it(target, next_key, target); |
| 2074 bool call_to_js = it.IsFound() && it.state() != LookupIterator::DATA; | 2088 bool call_to_js = it.IsFound() && it.state() != LookupIterator::DATA; |
| 2075 Maybe<bool> result = Object::SetProperty( | 2089 Maybe<bool> result = Object::SetProperty( |
| 2076 &it, prop_value, STRICT, Object::CERTAINLY_NOT_STORE_FROM_KEYED); | 2090 &it, prop_value, STRICT, Object::CERTAINLY_NOT_STORE_FROM_KEYED); |
| 2077 if (result.IsNothing()) return result; | 2091 if (result.IsNothing()) return result; |
| 2078 if (stable && call_to_js) stable = from->map() == *map; | 2092 if (stable && call_to_js) stable = from->map() == *map; |
| 2079 } else { | 2093 } else { |
| 2094 if (excluded_properties != nullptr && | |
| 2095 HasElementInArguments(excluded_properties, next_key)) { | |
| 2096 continue; | |
| 2097 } | |
| 2098 | |
| 2080 // 4a ii 2. Perform ? CreateDataProperty(target, nextKey, propValue). | 2099 // 4a ii 2. Perform ? CreateDataProperty(target, nextKey, propValue). |
| 2081 bool success; | 2100 bool success; |
| 2082 LookupIterator it = LookupIterator::PropertyOrElement( | 2101 LookupIterator it = LookupIterator::PropertyOrElement( |
| 2083 isolate, target, next_key, &success, LookupIterator::OWN); | 2102 isolate, target, next_key, &success, LookupIterator::OWN); |
| 2084 CHECK(success); | 2103 CHECK(success); |
| 2085 CHECK( | 2104 CHECK( |
| 2086 JSObject::CreateDataProperty(&it, prop_value, Object::THROW_ON_ERROR) | 2105 JSObject::CreateDataProperty(&it, prop_value, Object::THROW_ON_ERROR) |
| 2087 .FromJust()); | 2106 .FromJust()); |
| 2088 } | 2107 } |
| 2089 } | 2108 } |
| 2090 | 2109 |
| 2091 return Just(true); | 2110 return Just(true); |
| 2092 } | 2111 } |
| 2093 | |
| 2094 } // namespace | 2112 } // namespace |
| 2095 | 2113 |
| 2096 // static | 2114 // static |
| 2097 Maybe<bool> JSReceiver::SetOrCopyDataProperties(Isolate* isolate, | 2115 Maybe<bool> JSReceiver::SetOrCopyDataProperties(Isolate* isolate, |
| 2098 Handle<JSReceiver> target, | 2116 Handle<JSReceiver> target, |
| 2099 Handle<Object> source, | 2117 Handle<Object> source, |
| 2118 Arguments* excluded_properties, | |
| 2100 bool use_set) { | 2119 bool use_set) { |
| 2101 Maybe<bool> fast_assign = FastAssign(target, source, use_set); | 2120 Maybe<bool> fast_assign = |
| 2121 FastAssign(target, source, excluded_properties, use_set); | |
| 2102 if (fast_assign.IsNothing()) return Nothing<bool>(); | 2122 if (fast_assign.IsNothing()) return Nothing<bool>(); |
| 2103 if (fast_assign.FromJust()) return Just(true); | 2123 if (fast_assign.FromJust()) return Just(true); |
| 2104 | 2124 |
| 2105 Handle<JSReceiver> from = Object::ToObject(isolate, source).ToHandleChecked(); | 2125 Handle<JSReceiver> from = Object::ToObject(isolate, source).ToHandleChecked(); |
| 2106 // 3b. Let keys be ? from.[[OwnPropertyKeys]](). | 2126 // 3b. Let keys be ? from.[[OwnPropertyKeys]](). |
| 2107 Handle<FixedArray> keys; | 2127 Handle<FixedArray> keys; |
| 2108 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 2128 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 2109 isolate, keys, | 2129 isolate, keys, |
| 2110 KeyAccumulator::GetKeys(from, KeyCollectionMode::kOwnOnly, ALL_PROPERTIES, | 2130 KeyAccumulator::GetKeys(from, KeyCollectionMode::kOwnOnly, ALL_PROPERTIES, |
| 2111 GetKeysConversion::kKeepNumbers), | 2131 GetKeysConversion::kKeepNumbers), |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 2128 Runtime::GetObjectProperty(isolate, from, next_key), Nothing<bool>()); | 2148 Runtime::GetObjectProperty(isolate, from, next_key), Nothing<bool>()); |
| 2129 | 2149 |
| 2130 if (use_set) { | 2150 if (use_set) { |
| 2131 // 4c ii 2. Let status be ? Set(to, nextKey, propValue, true). | 2151 // 4c ii 2. Let status be ? Set(to, nextKey, propValue, true). |
| 2132 Handle<Object> status; | 2152 Handle<Object> status; |
| 2133 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 2153 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 2134 isolate, status, Runtime::SetObjectProperty( | 2154 isolate, status, Runtime::SetObjectProperty( |
| 2135 isolate, target, next_key, prop_value, STRICT), | 2155 isolate, target, next_key, prop_value, STRICT), |
| 2136 Nothing<bool>()); | 2156 Nothing<bool>()); |
| 2137 } else { | 2157 } else { |
| 2158 if (excluded_properties != nullptr && | |
| 2159 HasElementInArguments(excluded_properties, next_key)) { | |
| 2160 continue; | |
| 2161 } | |
| 2162 | |
| 2138 // 4a ii 2. Perform ! CreateDataProperty(target, nextKey, propValue). | 2163 // 4a ii 2. Perform ! CreateDataProperty(target, nextKey, propValue). |
| 2139 bool success; | 2164 bool success; |
| 2140 LookupIterator it = LookupIterator::PropertyOrElement( | 2165 LookupIterator it = LookupIterator::PropertyOrElement( |
| 2141 isolate, target, next_key, &success, LookupIterator::OWN); | 2166 isolate, target, next_key, &success, LookupIterator::OWN); |
| 2142 CHECK(success); | 2167 CHECK(success); |
| 2143 CHECK(JSObject::CreateDataProperty(&it, prop_value, | 2168 CHECK(JSObject::CreateDataProperty(&it, prop_value, |
| 2144 Object::THROW_ON_ERROR) | 2169 Object::THROW_ON_ERROR) |
| 2145 .FromJust()); | 2170 .FromJust()); |
| 2146 } | 2171 } |
| 2147 } | 2172 } |
| (...skipping 17745 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 19893 // depend on this. | 19918 // depend on this. |
| 19894 return DICTIONARY_ELEMENTS; | 19919 return DICTIONARY_ELEMENTS; |
| 19895 } | 19920 } |
| 19896 DCHECK_LE(kind, LAST_ELEMENTS_KIND); | 19921 DCHECK_LE(kind, LAST_ELEMENTS_KIND); |
| 19897 return kind; | 19922 return kind; |
| 19898 } | 19923 } |
| 19899 } | 19924 } |
| 19900 | 19925 |
| 19901 } // namespace internal | 19926 } // namespace internal |
| 19902 } // namespace v8 | 19927 } // namespace v8 |
| OLD | NEW |