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

Side by Side Diff: src/accessors.cc

Issue 2543553002: [accessors] handle `writable` changing during ArrayLengthSetter (Closed)
Patch Set: Created 4 years 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
« no previous file with comments | « no previous file | test/mjsunit/array-length.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "src/accessors.h" 5 #include "src/accessors.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/contexts.h" 8 #include "src/contexts.h"
9 #include "src/deoptimizer.h" 9 #include "src/deoptimizer.h"
10 #include "src/execution.h" 10 #include "src/execution.h"
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 void Accessors::ArrayLengthSetter( 164 void Accessors::ArrayLengthSetter(
165 v8::Local<v8::Name> name, v8::Local<v8::Value> val, 165 v8::Local<v8::Name> name, v8::Local<v8::Value> val,
166 const v8::PropertyCallbackInfo<v8::Boolean>& info) { 166 const v8::PropertyCallbackInfo<v8::Boolean>& info) {
167 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); 167 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
168 HandleScope scope(isolate); 168 HandleScope scope(isolate);
169 169
170 Handle<JSReceiver> object = Utils::OpenHandle(*info.Holder()); 170 Handle<JSReceiver> object = Utils::OpenHandle(*info.Holder());
171 Handle<JSArray> array = Handle<JSArray>::cast(object); 171 Handle<JSArray> array = Handle<JSArray>::cast(object);
172 Handle<Object> length_obj = Utils::OpenHandle(*val); 172 Handle<Object> length_obj = Utils::OpenHandle(*val);
173 173
174 bool was_readonly;
175 {
176 LookupIterator it(object, Utils::OpenHandle(*name), LookupIterator::OWN);
177 DCHECK(it.IsFound());
178 was_readonly = it.property_details().IsReadOnly();
179 }
180
174 uint32_t length = 0; 181 uint32_t length = 0;
175 if (!JSArray::AnythingToArrayLength(isolate, length_obj, &length)) { 182 if (!JSArray::AnythingToArrayLength(isolate, length_obj, &length)) {
176 isolate->OptionalRescheduleException(false); 183 isolate->OptionalRescheduleException(false);
177 return; 184 return;
178 } 185 }
179 186
187 // AnythingToArrayLength() may have called setter re-entrantly and modified
188 // its property descriptor. Don't perform this check if "length" was
189 // previously readonly, as this may have been called during
190 // DefineOwnPropertyIgnoreAttributes().
191 LookupIterator it(object, Utils::OpenHandle(*name), LookupIterator::OWN);
Camillo Bruni 2016/11/30 12:08:27 I think you want to delay the LookupIterator creat
caitp 2016/11/30 13:17:58 Done, but I think with that condition, it gets cre
192 DCHECK(it.IsFound());
193 if (!was_readonly && V8_UNLIKELY(it.property_details().IsReadOnly()) &&
194 length != array->length()->Number()) {
195 if (info.ShouldThrowOnError()) {
196 Factory* factory = isolate->factory();
197 isolate->Throw(*factory->NewTypeError(
198 MessageTemplate::kStrictReadOnlyProperty, Utils::OpenHandle(*name),
199 i::Object::TypeOf(isolate, object), object));
200 isolate->OptionalRescheduleException(false);
201 } else {
202 info.GetReturnValue().Set(false);
203 }
204 return;
205 }
206
180 JSArray::SetLength(array, length); 207 JSArray::SetLength(array, length);
181 208
182 uint32_t actual_new_len = 0; 209 uint32_t actual_new_len = 0;
183 CHECK(array->length()->ToArrayLength(&actual_new_len)); 210 CHECK(array->length()->ToArrayLength(&actual_new_len));
184 // Fail if there were non-deletable elements. 211 // Fail if there were non-deletable elements.
185 if (actual_new_len != length) { 212 if (actual_new_len != length) {
186 if (info.ShouldThrowOnError()) { 213 if (info.ShouldThrowOnError()) {
187 Factory* factory = isolate->factory(); 214 Factory* factory = isolate->factory();
188 isolate->Throw(*factory->NewTypeError( 215 isolate->Throw(*factory->NewTypeError(
189 MessageTemplate::kStrictDeleteProperty, 216 MessageTemplate::kStrictDeleteProperty,
(...skipping 1034 matching lines...) Expand 10 before | Expand all | Expand 10 after
1224 Handle<AccessorInfo> Accessors::ErrorStackInfo(Isolate* isolate, 1251 Handle<AccessorInfo> Accessors::ErrorStackInfo(Isolate* isolate,
1225 PropertyAttributes attributes) { 1252 PropertyAttributes attributes) {
1226 Handle<AccessorInfo> info = 1253 Handle<AccessorInfo> info =
1227 MakeAccessor(isolate, isolate->factory()->stack_string(), 1254 MakeAccessor(isolate, isolate->factory()->stack_string(),
1228 &ErrorStackGetter, &ErrorStackSetter, attributes); 1255 &ErrorStackGetter, &ErrorStackSetter, attributes);
1229 return info; 1256 return info;
1230 } 1257 }
1231 1258
1232 } // namespace internal 1259 } // namespace internal
1233 } // namespace v8 1260 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/array-length.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698