Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(363)

Side by Side Diff: src/objects.cc

Issue 2620943002: [ESnext] Implement Object Rest (Closed)
Patch Set: Remove comment Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 1984 matching lines...) Expand 10 before | Expand all | Expand 10 after
1995 if (!iter.AdvanceFollowingProxies()) return Nothing<bool>(); 1995 if (!iter.AdvanceFollowingProxies()) return Nothing<bool>();
1996 if (iter.IsAtEnd()) return Just(false); 1996 if (iter.IsAtEnd()) return Just(false);
1997 if (PrototypeIterator::GetCurrent(iter).is_identical_to(proto)) { 1997 if (PrototypeIterator::GetCurrent(iter).is_identical_to(proto)) {
1998 return Just(true); 1998 return Just(true);
1999 } 1999 }
2000 } 2000 }
2001 } 2001 }
2002 2002
2003 namespace { 2003 namespace {
2004 2004
2005 MUST_USE_RESULT Maybe<bool> FastAssign(Handle<JSReceiver> target, 2005 bool HasElementInJSArray(Isolate* isolate, Handle<JSArray> array,
2006 Handle<Object> source, bool use_set) { 2006 Handle<Object> search_element) {
2007 uint32_t len = 0;
2008 bool success = array->length()->ToArrayLength(&len);
2009 DCHECK(success);
2010
2011 if (len == 0) return false;
2012
2013 int32_t start = 0;
2014 ElementsAccessor* elements = array->GetElementsAccessor();
2015 Maybe<bool> result =
2016 elements->IncludesValue(isolate, array, search_element, start, len);
2017 return result.FromJust();
2018 }
2019
2020 MUST_USE_RESULT Maybe<bool> FastAssign(
2021 Handle<JSReceiver> target, Handle<Object> source,
2022 MaybeHandle<JSArray> maybe_excluded_properties, bool use_set) {
2007 // Non-empty strings are the only non-JSReceivers that need to be handled 2023 // Non-empty strings are the only non-JSReceivers that need to be handled
2008 // explicitly by Object.assign. 2024 // explicitly by Object.assign.
2009 if (!source->IsJSReceiver()) { 2025 if (!source->IsJSReceiver()) {
2010 return Just(!source->IsString() || String::cast(*source)->length() == 0); 2026 return Just(!source->IsString() || String::cast(*source)->length() == 0);
2011 } 2027 }
2012 2028
2013 // If the target is deprecated, the object will be updated on first store. If 2029 // If the target is deprecated, the object will be updated on first store. If
2014 // the source for that store equals the target, this will invalidate the 2030 // the source for that store equals the target, this will invalidate the
2015 // cached representation of the source. Preventively upgrade the target. 2031 // cached representation of the source. Preventively upgrade the target.
2016 // Do this on each iteration since any property load could cause deprecation. 2032 // Do this on each iteration since any property load could cause deprecation.
2017 if (target->map()->is_deprecated()) { 2033 if (target->map()->is_deprecated()) {
2018 JSObject::MigrateInstance(Handle<JSObject>::cast(target)); 2034 JSObject::MigrateInstance(Handle<JSObject>::cast(target));
2019 } 2035 }
2020 2036
2021 Isolate* isolate = target->GetIsolate(); 2037 Isolate* isolate = target->GetIsolate();
2022 Handle<Map> map(JSReceiver::cast(*source)->map(), isolate); 2038 Handle<Map> map(JSReceiver::cast(*source)->map(), isolate);
2023 2039
2024 if (!map->IsJSObjectMap()) return Just(false); 2040 if (!map->IsJSObjectMap()) return Just(false);
2025 if (!map->OnlyHasSimpleProperties()) return Just(false); 2041 if (!map->OnlyHasSimpleProperties()) return Just(false);
2026 2042
2027 Handle<JSObject> from = Handle<JSObject>::cast(source); 2043 Handle<JSObject> from = Handle<JSObject>::cast(source);
2028 if (from->elements() != isolate->heap()->empty_fixed_array()) { 2044 if (from->elements() != isolate->heap()->empty_fixed_array()) {
2029 return Just(false); 2045 return Just(false);
2030 } 2046 }
2031 2047
2032 Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate); 2048 Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate);
2033 int length = map->NumberOfOwnDescriptors(); 2049 int length = map->NumberOfOwnDescriptors();
2034 2050
2035 bool stable = true; 2051 bool stable = true;
2052 Handle<JSArray> excluded_properties;
2053 if (!maybe_excluded_properties.is_null()) {
2054 excluded_properties = maybe_excluded_properties.ToHandleChecked();
adamk 2017/01/10 23:22:56 Pattern for this is: const bool has_excluded_prop
2055 }
2036 2056
2037 for (int i = 0; i < length; i++) { 2057 for (int i = 0; i < length; i++) {
2038 Handle<Name> next_key(descriptors->GetKey(i), isolate); 2058 Handle<Name> next_key(descriptors->GetKey(i), isolate);
2039 Handle<Object> prop_value; 2059 Handle<Object> prop_value;
2040 // Directly decode from the descriptor array if |from| did not change shape. 2060 // Directly decode from the descriptor array if |from| did not change shape.
2041 if (stable) { 2061 if (stable) {
2042 PropertyDetails details = descriptors->GetDetails(i); 2062 PropertyDetails details = descriptors->GetDetails(i);
2043 if (!details.IsEnumerable()) continue; 2063 if (!details.IsEnumerable()) continue;
2044 if (details.kind() == kData) { 2064 if (details.kind() == kData) {
2045 if (details.location() == kDescriptor) { 2065 if (details.location() == kDescriptor) {
(...skipping 23 matching lines...) Expand all
2069 } 2089 }
2070 2090
2071 if (use_set) { 2091 if (use_set) {
2072 LookupIterator it(target, next_key, target); 2092 LookupIterator it(target, next_key, target);
2073 bool call_to_js = it.IsFound() && it.state() != LookupIterator::DATA; 2093 bool call_to_js = it.IsFound() && it.state() != LookupIterator::DATA;
2074 Maybe<bool> result = Object::SetProperty( 2094 Maybe<bool> result = Object::SetProperty(
2075 &it, prop_value, STRICT, Object::CERTAINLY_NOT_STORE_FROM_KEYED); 2095 &it, prop_value, STRICT, Object::CERTAINLY_NOT_STORE_FROM_KEYED);
2076 if (result.IsNothing()) return result; 2096 if (result.IsNothing()) return result;
2077 if (stable && call_to_js) stable = from->map() == *map; 2097 if (stable && call_to_js) stable = from->map() == *map;
2078 } else { 2098 } else {
2099 if (!maybe_excluded_properties.is_null() &&
adamk 2017/01/10 23:22:56 and then this would be if (has_excluded_propertie
2100 HasElementInJSArray(isolate, excluded_properties, next_key)) {
2101 continue;
2102 }
2103
2079 // 4a ii 2. Perform ? CreateDataProperty(target, nextKey, propValue). 2104 // 4a ii 2. Perform ? CreateDataProperty(target, nextKey, propValue).
2080 bool success; 2105 bool success;
2081 LookupIterator it = LookupIterator::PropertyOrElement( 2106 LookupIterator it = LookupIterator::PropertyOrElement(
2082 isolate, target, next_key, &success, LookupIterator::OWN); 2107 isolate, target, next_key, &success, LookupIterator::OWN);
2083 CHECK(success); 2108 CHECK(success);
2084 CHECK( 2109 CHECK(
2085 JSObject::CreateDataProperty(&it, prop_value, Object::THROW_ON_ERROR) 2110 JSObject::CreateDataProperty(&it, prop_value, Object::THROW_ON_ERROR)
2086 .FromJust()); 2111 .FromJust());
2087 } 2112 }
2088 } 2113 }
2089 2114
2090 return Just(true); 2115 return Just(true);
2091 } 2116 }
2092
2093 } // namespace 2117 } // namespace
2094 2118
2095 // static 2119 // static
2096 Maybe<bool> JSReceiver::SetOrCopyDataProperties(Isolate* isolate, 2120 Maybe<bool> JSReceiver::SetOrCopyDataProperties(
2097 Handle<JSReceiver> target, 2121 Isolate* isolate, Handle<JSReceiver> target, Handle<Object> source,
2098 Handle<Object> source, 2122 MaybeHandle<JSArray> maybe_excluded_properties, bool use_set) {
2099 bool use_set) { 2123 Maybe<bool> fast_assign =
2100 Maybe<bool> fast_assign = FastAssign(target, source, use_set); 2124 FastAssign(target, source, maybe_excluded_properties, use_set);
2101 if (fast_assign.IsNothing()) return Nothing<bool>(); 2125 if (fast_assign.IsNothing()) return Nothing<bool>();
2102 if (fast_assign.FromJust()) return Just(true); 2126 if (fast_assign.FromJust()) return Just(true);
2103 2127
2104 Handle<JSReceiver> from = Object::ToObject(isolate, source).ToHandleChecked(); 2128 Handle<JSReceiver> from = Object::ToObject(isolate, source).ToHandleChecked();
2105 // 3b. Let keys be ? from.[[OwnPropertyKeys]](). 2129 // 3b. Let keys be ? from.[[OwnPropertyKeys]]().
2106 Handle<FixedArray> keys; 2130 Handle<FixedArray> keys;
2107 ASSIGN_RETURN_ON_EXCEPTION_VALUE( 2131 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
2108 isolate, keys, 2132 isolate, keys,
2109 KeyAccumulator::GetKeys(from, KeyCollectionMode::kOwnOnly, ALL_PROPERTIES, 2133 KeyAccumulator::GetKeys(from, KeyCollectionMode::kOwnOnly, ALL_PROPERTIES,
2110 GetKeysConversion::kKeepNumbers), 2134 GetKeysConversion::kKeepNumbers),
2111 Nothing<bool>()); 2135 Nothing<bool>());
2112 2136
2137 Handle<JSArray> excluded_properties;
2138 if (!maybe_excluded_properties.is_null()) {
2139 excluded_properties = maybe_excluded_properties.ToHandleChecked();
adamk 2017/01/10 23:22:56 Same here as above
2140 }
2141
2113 // 4. Repeat for each element nextKey of keys in List order, 2142 // 4. Repeat for each element nextKey of keys in List order,
2114 for (int j = 0; j < keys->length(); ++j) { 2143 for (int j = 0; j < keys->length(); ++j) {
2115 Handle<Object> next_key(keys->get(j), isolate); 2144 Handle<Object> next_key(keys->get(j), isolate);
2116 // 4a i. Let desc be ? from.[[GetOwnProperty]](nextKey). 2145 // 4a i. Let desc be ? from.[[GetOwnProperty]](nextKey).
2117 PropertyDescriptor desc; 2146 PropertyDescriptor desc;
2118 Maybe<bool> found = 2147 Maybe<bool> found =
2119 JSReceiver::GetOwnPropertyDescriptor(isolate, from, next_key, &desc); 2148 JSReceiver::GetOwnPropertyDescriptor(isolate, from, next_key, &desc);
2120 if (found.IsNothing()) return Nothing<bool>(); 2149 if (found.IsNothing()) return Nothing<bool>();
2121 // 4a ii. If desc is not undefined and desc.[[Enumerable]] is true, then 2150 // 4a ii. If desc is not undefined and desc.[[Enumerable]] is true, then
2122 if (found.FromJust() && desc.enumerable()) { 2151 if (found.FromJust() && desc.enumerable()) {
2123 // 4a ii 1. Let propValue be ? Get(from, nextKey). 2152 // 4a ii 1. Let propValue be ? Get(from, nextKey).
2124 Handle<Object> prop_value; 2153 Handle<Object> prop_value;
2125 ASSIGN_RETURN_ON_EXCEPTION_VALUE( 2154 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
2126 isolate, prop_value, 2155 isolate, prop_value,
2127 Runtime::GetObjectProperty(isolate, from, next_key), Nothing<bool>()); 2156 Runtime::GetObjectProperty(isolate, from, next_key), Nothing<bool>());
2128 2157
2129 if (use_set) { 2158 if (use_set) {
2130 // 4c ii 2. Let status be ? Set(to, nextKey, propValue, true). 2159 // 4c ii 2. Let status be ? Set(to, nextKey, propValue, true).
2131 Handle<Object> status; 2160 Handle<Object> status;
2132 ASSIGN_RETURN_ON_EXCEPTION_VALUE( 2161 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
2133 isolate, status, Runtime::SetObjectProperty( 2162 isolate, status, Runtime::SetObjectProperty(
2134 isolate, target, next_key, prop_value, STRICT), 2163 isolate, target, next_key, prop_value, STRICT),
2135 Nothing<bool>()); 2164 Nothing<bool>());
2136 } else { 2165 } else {
2166 if (!maybe_excluded_properties.is_null() &&
adamk 2017/01/10 23:22:55 And here.
2167 HasElementInJSArray(isolate, excluded_properties, next_key)) {
2168 continue;
2169 }
2170
2137 // 4a ii 2. Perform ! CreateDataProperty(target, nextKey, propValue). 2171 // 4a ii 2. Perform ! CreateDataProperty(target, nextKey, propValue).
2138 bool success; 2172 bool success;
2139 LookupIterator it = LookupIterator::PropertyOrElement( 2173 LookupIterator it = LookupIterator::PropertyOrElement(
2140 isolate, target, next_key, &success, LookupIterator::OWN); 2174 isolate, target, next_key, &success, LookupIterator::OWN);
2141 CHECK(success); 2175 CHECK(success);
2142 CHECK(JSObject::CreateDataProperty(&it, prop_value, 2176 CHECK(JSObject::CreateDataProperty(&it, prop_value,
2143 Object::THROW_ON_ERROR) 2177 Object::THROW_ON_ERROR)
2144 .FromJust()); 2178 .FromJust());
2145 } 2179 }
2146 } 2180 }
(...skipping 17806 matching lines...) Expand 10 before | Expand all | Expand 10 after
19953 // depend on this. 19987 // depend on this.
19954 return DICTIONARY_ELEMENTS; 19988 return DICTIONARY_ELEMENTS;
19955 } 19989 }
19956 DCHECK_LE(kind, LAST_ELEMENTS_KIND); 19990 DCHECK_LE(kind, LAST_ELEMENTS_KIND);
19957 return kind; 19991 return kind;
19958 } 19992 }
19959 } 19993 }
19960 19994
19961 } // namespace internal 19995 } // namespace internal
19962 } // namespace v8 19996 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698