| OLD | NEW | 
|---|
| 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/runtime/runtime-utils.h" | 5 #include "src/runtime/runtime-utils.h" | 
| 6 | 6 | 
| 7 #include "src/arguments.h" | 7 #include "src/arguments.h" | 
| 8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" | 
| 9 #include "src/conversions-inl.h" | 9 #include "src/conversions-inl.h" | 
| 10 #include "src/elements.h" | 10 #include "src/elements.h" | 
| (...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 623       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, element_k, | 623       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, element_k, | 
| 624                                          Object::GetProperty(&it)); | 624                                          Object::GetProperty(&it)); | 
| 625       if (search_element->StrictEquals(*element_k)) { | 625       if (search_element->StrictEquals(*element_k)) { | 
| 626         return *index_obj; | 626         return *index_obj; | 
| 627       } | 627       } | 
| 628     } | 628     } | 
| 629   } | 629   } | 
| 630   return Smi::FromInt(-1); | 630   return Smi::FromInt(-1); | 
| 631 } | 631 } | 
| 632 | 632 | 
| 633 RUNTIME_FUNCTION(Runtime_SpreadIterablePrepare) { | 633 namespace { | 
| 634   HandleScope scope(isolate); |  | 
| 635   DCHECK_EQ(1, args.length()); |  | 
| 636   CONVERT_ARG_HANDLE_CHECKED(Object, spread, 0); |  | 
| 637 | 634 | 
|  | 635 bool MustIterate(Isolate* isolate, Handle<Object> spread) { | 
| 638   if (spread->IsJSArray()) { | 636   if (spread->IsJSArray()) { | 
| 639     // Check that the spread arg has fast elements | 637     // Check that the spread arg has fast elements | 
| 640     Handle<JSArray> spread_array = Handle<JSArray>::cast(spread); | 638     Handle<JSArray> spread_array = Handle<JSArray>::cast(spread); | 
| 641     ElementsKind array_kind = spread_array->GetElementsKind(); | 639     ElementsKind array_kind = spread_array->GetElementsKind(); | 
| 642 | 640 | 
| 643     // And that it has the orignal ArrayPrototype | 641     // And that it has the orignal ArrayPrototype | 
| 644     JSObject* array_proto = JSObject::cast(spread_array->map()->prototype()); | 642     JSObject* array_proto = JSObject::cast(spread_array->map()->prototype()); | 
| 645     Map* iterator_map = isolate->initial_array_iterator_prototype()->map(); | 643     Map* iterator_map = isolate->initial_array_iterator_prototype()->map(); | 
| 646 | 644 | 
| 647     // Check that the iterator acts as expected. | 645     // Check that the iterator acts as expected. | 
| 648     // If IsArrayIteratorLookupChainIntact(), then we know that the initial | 646     // If IsArrayIteratorLookupChainIntact(), then we know that the initial | 
| 649     // ArrayIterator is being used. If the map of the prototype has changed, | 647     // ArrayIterator is being used. If the map of the prototype has changed, | 
| 650     // then take the slow path. | 648     // then take the slow path. | 
| 651 |  | 
| 652     if (isolate->is_initial_array_prototype(array_proto) && | 649     if (isolate->is_initial_array_prototype(array_proto) && | 
| 653         isolate->IsArrayIteratorLookupChainIntact() && | 650         isolate->IsArrayIteratorLookupChainIntact() && | 
| 654         isolate->is_initial_array_iterator_prototype_map(iterator_map)) { | 651         isolate->is_initial_array_iterator_prototype_map(iterator_map)) { | 
| 655       if (IsFastPackedElementsKind(array_kind)) { | 652       if (IsFastPackedElementsKind(array_kind)) { | 
| 656         return *spread; | 653         return false; | 
| 657       } | 654       } | 
| 658       if (IsFastHoleyElementsKind(array_kind) && | 655       if (IsFastHoleyElementsKind(array_kind) && | 
| 659           isolate->IsFastArrayConstructorPrototypeChainIntact()) { | 656           isolate->IsFastArrayConstructorPrototypeChainIntact()) { | 
| 660         return *spread; | 657         return false; | 
| 661       } | 658       } | 
| 662     } | 659     } | 
| 663   } | 660   } | 
|  | 661   return true; | 
|  | 662 } | 
| 664 | 663 | 
| 665   Handle<JSFunction> spread_iterable_function = isolate->spread_iterable(); | 664 }  //  namespace | 
| 666 | 665 | 
| 667   Handle<Object> spreaded; | 666 RUNTIME_FUNCTION(Runtime_SpreadIterablePrepare) { | 
| 668   ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 667   HandleScope scope(isolate); | 
| 669       isolate, spreaded, | 668   DCHECK_EQ(1, args.length()); | 
| 670       Execution::Call(isolate, spread_iterable_function, | 669   CONVERT_ARG_HANDLE_CHECKED(Object, spread, 0); | 
| 671                       isolate->factory()->undefined_value(), 1, &spread)); |  | 
| 672 | 670 | 
| 673   return *spreaded; | 671   // Iterate over the spread if we need to. | 
|  | 672   if (MustIterate(isolate, spread)) { | 
|  | 673     Handle<JSFunction> spread_iterable_function = isolate->spread_iterable(); | 
|  | 674     ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 
|  | 675         isolate, spread, | 
|  | 676         Execution::Call(isolate, spread_iterable_function, | 
|  | 677                         isolate->factory()->undefined_value(), 1, &spread)); | 
|  | 678   } | 
|  | 679 | 
|  | 680   return *spread; | 
|  | 681 } | 
|  | 682 | 
|  | 683 RUNTIME_FUNCTION(Runtime_SpreadIterablePrepareVarargs) { | 
|  | 684   HandleScope scope(isolate); | 
|  | 685   DCHECK_LE(1, args.length()); | 
|  | 686   CONVERT_ARG_HANDLE_CHECKED(Object, spread, args.length() - 1); | 
|  | 687 | 
|  | 688   // Iterate over the spread if we need to. | 
|  | 689   if (MustIterate(isolate, spread)) { | 
|  | 690     Handle<JSFunction> spread_iterable_function = isolate->spread_iterable(); | 
|  | 691     ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 
|  | 692         isolate, spread, | 
|  | 693         Execution::Call(isolate, spread_iterable_function, | 
|  | 694                         isolate->factory()->undefined_value(), 1, &spread)); | 
|  | 695   } | 
|  | 696 | 
|  | 697   if (args.length() == 1) return *spread; | 
|  | 698 | 
|  | 699   JSArray* spread_array = JSArray::cast(*spread); | 
|  | 700   uint32_t spread_length; | 
|  | 701   CHECK(spread_array->length()->ToArrayIndex(&spread_length)); | 
|  | 702 | 
|  | 703   // Append each of the individual args to the result. | 
|  | 704   int result_length = args.length() - 1 + spread_length; | 
|  | 705   Handle<FixedArray> result = isolate->factory()->NewFixedArray(result_length); | 
|  | 706   for (int i = 0; i < args.length() - 1; i++) { | 
|  | 707     result->set(i, *args.at<Object>(i)); | 
|  | 708   } | 
|  | 709 | 
|  | 710   // Append element of the spread to the result. | 
|  | 711   for (uint32_t i = 0; i < spread_length; i++) { | 
|  | 712     LookupIterator it(isolate, spread, i); | 
|  | 713     Handle<Object> element = spread_array->GetDataProperty(&it); | 
|  | 714     result->set(args.length() - 1 + i, *element); | 
|  | 715   } | 
|  | 716 | 
|  | 717   Handle<JSArray> r = isolate->factory()->NewJSArrayWithElements( | 
|  | 718       result, FAST_ELEMENTS, result_length); | 
|  | 719   return *r; | 
| 674 } | 720 } | 
| 675 | 721 | 
| 676 }  // namespace internal | 722 }  // namespace internal | 
| 677 }  // namespace v8 | 723 }  // namespace v8 | 
| OLD | NEW | 
|---|