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

Side by Side Diff: src/accessors.cc

Issue 2543553002: [accessors] handle `writable` changing during ArrayLengthSetter (Closed)
Patch Set: refactor branch conditions for unlikely case 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 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 Object* result = holder->length(); 160 Object* result = holder->length();
161 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate))); 161 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
162 } 162 }
163 163
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 DCHECK(Utils::OpenHandle(*name)->SameValue(isolate->heap()->length_string()));
171
170 Handle<JSReceiver> object = Utils::OpenHandle(*info.Holder()); 172 Handle<JSReceiver> object = Utils::OpenHandle(*info.Holder());
171 Handle<JSArray> array = Handle<JSArray>::cast(object); 173 Handle<JSArray> array = Handle<JSArray>::cast(object);
172 Handle<Object> length_obj = Utils::OpenHandle(*val); 174 Handle<Object> length_obj = Utils::OpenHandle(*val);
173 175
176 bool was_readonly = JSArray::HasReadOnlyLength(array);
177
174 uint32_t length = 0; 178 uint32_t length = 0;
175 if (!JSArray::AnythingToArrayLength(isolate, length_obj, &length)) { 179 if (!JSArray::AnythingToArrayLength(isolate, length_obj, &length)) {
176 isolate->OptionalRescheduleException(false); 180 isolate->OptionalRescheduleException(false);
177 return; 181 return;
178 } 182 }
179 183
184 if (!was_readonly && V8_UNLIKELY(JSArray::HasReadOnlyLength(array)) &&
185 length != array->length()->Number()) {
186 // AnythingToArrayLength() may have called setter re-entrantly and modified
187 // its property descriptor. Don't perform this check if "length" was
188 // previously readonly, as this may have been called during
189 // DefineOwnPropertyIgnoreAttributes().
190 if (info.ShouldThrowOnError()) {
191 Factory* factory = isolate->factory();
192 isolate->Throw(*factory->NewTypeError(
193 MessageTemplate::kStrictReadOnlyProperty, Utils::OpenHandle(*name),
194 i::Object::TypeOf(isolate, object), object));
195 isolate->OptionalRescheduleException(false);
196 } else {
197 info.GetReturnValue().Set(false);
198 }
199 return;
200 }
201
180 JSArray::SetLength(array, length); 202 JSArray::SetLength(array, length);
181 203
182 uint32_t actual_new_len = 0; 204 uint32_t actual_new_len = 0;
183 CHECK(array->length()->ToArrayLength(&actual_new_len)); 205 CHECK(array->length()->ToArrayLength(&actual_new_len));
184 // Fail if there were non-deletable elements. 206 // Fail if there were non-deletable elements.
185 if (actual_new_len != length) { 207 if (actual_new_len != length) {
186 if (info.ShouldThrowOnError()) { 208 if (info.ShouldThrowOnError()) {
187 Factory* factory = isolate->factory(); 209 Factory* factory = isolate->factory();
188 isolate->Throw(*factory->NewTypeError( 210 isolate->Throw(*factory->NewTypeError(
189 MessageTemplate::kStrictDeleteProperty, 211 MessageTemplate::kStrictDeleteProperty,
(...skipping 1034 matching lines...) Expand 10 before | Expand all | Expand 10 after
1224 Handle<AccessorInfo> Accessors::ErrorStackInfo(Isolate* isolate, 1246 Handle<AccessorInfo> Accessors::ErrorStackInfo(Isolate* isolate,
1225 PropertyAttributes attributes) { 1247 PropertyAttributes attributes) {
1226 Handle<AccessorInfo> info = 1248 Handle<AccessorInfo> info =
1227 MakeAccessor(isolate, isolate->factory()->stack_string(), 1249 MakeAccessor(isolate, isolate->factory()->stack_string(),
1228 &ErrorStackGetter, &ErrorStackSetter, attributes); 1250 &ErrorStackGetter, &ErrorStackSetter, attributes);
1229 return info; 1251 return info;
1230 } 1252 }
1231 1253
1232 } // namespace internal 1254 } // namespace internal
1233 } // namespace v8 1255 } // 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