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

Side by Side Diff: src/runtime/runtime-array.cc

Issue 1270403002: Fix Array.prototype.concat for arguments object with getter. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 4 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 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/arguments.h" 7 #include "src/arguments.h"
8 #include "src/elements.h" 8 #include "src/elements.h"
9 #include "src/messages.h" 9 #include "src/messages.h"
10 #include "src/runtime/runtime-utils.h" 10 #include "src/runtime/runtime-utils.h"
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 355
356 356
357 // Used for sorting indices in a List<uint32_t>. 357 // Used for sorting indices in a List<uint32_t>.
358 static int compareUInt32(const uint32_t* ap, const uint32_t* bp) { 358 static int compareUInt32(const uint32_t* ap, const uint32_t* bp) {
359 uint32_t a = *ap; 359 uint32_t a = *ap;
360 uint32_t b = *bp; 360 uint32_t b = *bp;
361 return (a == b) ? 0 : (a < b) ? -1 : 1; 361 return (a == b) ? 0 : (a < b) ? -1 : 1;
362 } 362 }
363 363
364 364
365 static void CollectElementIndices(Handle<JSObject> object, uint32_t range, 365 // Return false on exception.
366 static bool CollectElementIndices(Handle<JSObject> object, uint32_t range,
366 List<uint32_t>* indices) { 367 List<uint32_t>* indices) {
367 Isolate* isolate = object->GetIsolate(); 368 Isolate* isolate = object->GetIsolate();
368 ElementsKind kind = object->GetElementsKind(); 369 ElementsKind kind = object->GetElementsKind();
369 switch (kind) { 370 switch (kind) {
370 case FAST_SMI_ELEMENTS: 371 case FAST_SMI_ELEMENTS:
371 case FAST_ELEMENTS: 372 case FAST_ELEMENTS:
372 case FAST_HOLEY_SMI_ELEMENTS: 373 case FAST_HOLEY_SMI_ELEMENTS:
373 case FAST_HOLEY_ELEMENTS: { 374 case FAST_HOLEY_ELEMENTS: {
374 Handle<FixedArray> elements(FixedArray::cast(object->elements())); 375 Handle<FixedArray> elements(FixedArray::cast(object->elements()));
375 uint32_t length = static_cast<uint32_t>(elements->length()); 376 uint32_t length = static_cast<uint32_t>(elements->length());
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 FixedArrayBase::cast(object->elements())->length()); 426 FixedArrayBase::cast(object->elements())->length());
426 if (range <= length) { 427 if (range <= length) {
427 length = range; 428 length = range;
428 // We will add all indices, so we might as well clear it first 429 // We will add all indices, so we might as well clear it first
429 // and avoid duplicates. 430 // and avoid duplicates.
430 indices->Clear(); 431 indices->Clear();
431 } 432 }
432 for (uint32_t i = 0; i < length; i++) { 433 for (uint32_t i = 0; i < length; i++) {
433 indices->Add(i); 434 indices->Add(i);
434 } 435 }
435 if (length == range) return; // All indices accounted for already. 436 if (length == range) return true; // All indices accounted for already.
436 break; 437 break;
437 } 438 }
438 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: 439 case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
439 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: { 440 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: {
440 MaybeHandle<Object> length_obj = 441 Handle<Object> length_obj;
441 Object::GetProperty(object, isolate->factory()->length_string()); 442 // See ES6 22.1.3.1 step 7-a-ii
adamk 2015/08/05 18:05:53 I think you mean 7-d-ii?
442 double length_num = length_obj.ToHandleChecked()->Number(); 443 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
444 isolate, length_obj,
445 Object::GetProperty(object, isolate->factory()->length_string()),
446 false);
447 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
448 isolate, length_obj, Execution::ToLength(isolate, length_obj), false);
449 double length_num = length_obj->Number();
443 uint32_t length = static_cast<uint32_t>(DoubleToInt32(length_num)); 450 uint32_t length = static_cast<uint32_t>(DoubleToInt32(length_num));
444 ElementsAccessor* accessor = object->GetElementsAccessor(); 451 ElementsAccessor* accessor = object->GetElementsAccessor();
445 for (uint32_t i = 0; i < length; i++) { 452 for (uint32_t i = 0; i < length; i++) {
446 if (accessor->HasElement(object, i)) { 453 if (accessor->HasElement(object, i)) {
447 indices->Add(i); 454 indices->Add(i);
448 } 455 }
449 } 456 }
450 break; 457 break;
451 } 458 }
452 } 459 }
453 460
454 PrototypeIterator iter(isolate, object); 461 PrototypeIterator iter(isolate, object);
455 if (!iter.IsAtEnd()) { 462 if (!iter.IsAtEnd()) {
456 // The prototype will usually have no inherited element indices, 463 // The prototype will usually have no inherited element indices,
457 // but we have to check. 464 // but we have to check.
458 CollectElementIndices( 465 return CollectElementIndices(
459 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), range, 466 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), range,
460 indices); 467 indices);
461 } 468 }
469 return true;
462 } 470 }
463 471
464 472
465 static bool IterateElementsSlow(Isolate* isolate, Handle<JSObject> receiver, 473 static bool IterateElementsSlow(Isolate* isolate, Handle<JSObject> receiver,
466 uint32_t length, ArrayConcatVisitor* visitor) { 474 uint32_t length, ArrayConcatVisitor* visitor) {
467 for (uint32_t i = 0; i < length; ++i) { 475 for (uint32_t i = 0; i < length; ++i) {
468 HandleScope loop_scope(isolate); 476 HandleScope loop_scope(isolate);
469 Maybe<bool> maybe = JSReceiver::HasElement(receiver, i); 477 Maybe<bool> maybe = JSReceiver::HasElement(receiver, i);
470 if (!maybe.IsJust()) return false; 478 if (!maybe.IsJust()) return false;
471 if (maybe.FromJust()) { 479 if (maybe.FromJust()) {
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
582 } 590 }
583 } 591 }
584 } 592 }
585 break; 593 break;
586 } 594 }
587 case DICTIONARY_ELEMENTS: { 595 case DICTIONARY_ELEMENTS: {
588 Handle<SeededNumberDictionary> dict(receiver->element_dictionary()); 596 Handle<SeededNumberDictionary> dict(receiver->element_dictionary());
589 List<uint32_t> indices(dict->Capacity() / 2); 597 List<uint32_t> indices(dict->Capacity() / 2);
590 // Collect all indices in the object and the prototypes less 598 // Collect all indices in the object and the prototypes less
591 // than length. This might introduce duplicates in the indices list. 599 // than length. This might introduce duplicates in the indices list.
592 CollectElementIndices(receiver, length, &indices); 600 if (!CollectElementIndices(receiver, length, &indices)) return false;
593 indices.Sort(&compareUInt32); 601 indices.Sort(&compareUInt32);
594 int j = 0; 602 int j = 0;
595 int n = indices.length(); 603 int n = indices.length();
596 while (j < n) { 604 while (j < n) {
597 HandleScope loop_scope(isolate); 605 HandleScope loop_scope(isolate);
598 uint32_t index = indices[j]; 606 uint32_t index = indices[j];
599 Handle<Object> element; 607 Handle<Object> element;
600 ASSIGN_RETURN_ON_EXCEPTION_VALUE( 608 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
601 isolate, element, Object::GetElement(isolate, receiver, index), 609 isolate, element, Object::GetElement(isolate, receiver, index),
602 false); 610 false);
(...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after
1268 1276
1269 RUNTIME_FUNCTION(Runtime_FastOneByteArrayJoin) { 1277 RUNTIME_FUNCTION(Runtime_FastOneByteArrayJoin) {
1270 SealHandleScope shs(isolate); 1278 SealHandleScope shs(isolate);
1271 DCHECK(args.length() == 2); 1279 DCHECK(args.length() == 2);
1272 // Returning undefined means that this fast path fails and one has to resort 1280 // Returning undefined means that this fast path fails and one has to resort
1273 // to a slow path. 1281 // to a slow path.
1274 return isolate->heap()->undefined_value(); 1282 return isolate->heap()->undefined_value();
1275 } 1283 }
1276 } // namespace internal 1284 } // namespace internal
1277 } // namespace v8 1285 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/regress/regress-crbug-516775.js » ('j') | test/mjsunit/regress/regress-crbug-516775.js » ('J')

Powered by Google App Engine
This is Rietveld 408576698