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 && 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 Loading... |
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 |
OLD | NEW |