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 "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 Loading... | |
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 && length != array->length()->Number()) { | |
185 // AnythingToArrayLength() may have called setter re-entrantly and modified | |
186 // its property descriptor. Don't perform this check if "length" was | |
187 // previously readonly, as this may have been called during | |
188 // DefineOwnPropertyIgnoreAttributes(). | |
Toon Verwaest
2016/11/30 18:05:52
What about if (!was_readonly && V8_UNLIKELY(is rea
caitp
2016/11/30 18:13:36
`I think the combination of !was_readonly && lengt
| |
189 if (V8_UNLIKELY(JSArray::HasReadOnlyLength(array))) { | |
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 } | |
202 | |
180 JSArray::SetLength(array, length); | 203 JSArray::SetLength(array, length); |
181 | 204 |
182 uint32_t actual_new_len = 0; | 205 uint32_t actual_new_len = 0; |
183 CHECK(array->length()->ToArrayLength(&actual_new_len)); | 206 CHECK(array->length()->ToArrayLength(&actual_new_len)); |
184 // Fail if there were non-deletable elements. | 207 // Fail if there were non-deletable elements. |
185 if (actual_new_len != length) { | 208 if (actual_new_len != length) { |
186 if (info.ShouldThrowOnError()) { | 209 if (info.ShouldThrowOnError()) { |
187 Factory* factory = isolate->factory(); | 210 Factory* factory = isolate->factory(); |
188 isolate->Throw(*factory->NewTypeError( | 211 isolate->Throw(*factory->NewTypeError( |
189 MessageTemplate::kStrictDeleteProperty, | 212 MessageTemplate::kStrictDeleteProperty, |
(...skipping 1034 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1224 Handle<AccessorInfo> Accessors::ErrorStackInfo(Isolate* isolate, | 1247 Handle<AccessorInfo> Accessors::ErrorStackInfo(Isolate* isolate, |
1225 PropertyAttributes attributes) { | 1248 PropertyAttributes attributes) { |
1226 Handle<AccessorInfo> info = | 1249 Handle<AccessorInfo> info = |
1227 MakeAccessor(isolate, isolate->factory()->stack_string(), | 1250 MakeAccessor(isolate, isolate->factory()->stack_string(), |
1228 &ErrorStackGetter, &ErrorStackSetter, attributes); | 1251 &ErrorStackGetter, &ErrorStackSetter, attributes); |
1229 return info; | 1252 return info; |
1230 } | 1253 } |
1231 | 1254 |
1232 } // namespace internal | 1255 } // namespace internal |
1233 } // namespace v8 | 1256 } // namespace v8 |
OLD | NEW |