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

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

Issue 2709773002: [builtins] (Re-)implement Array.prototype.every/some with the CSA (Closed)
Patch Set: Rebase Created 3 years, 9 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
« no previous file with comments | « src/builtins/builtins.h ('k') | src/debug/debug-evaluate.cc » ('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 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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/builtins/builtins.h" 5 #include "src/builtins/builtins.h"
6 #include "src/builtins/builtins-utils.h" 6 #include "src/builtins/builtins-utils.h"
7 7
8 #include "src/code-factory.h" 8 #include "src/code-factory.h"
9 #include "src/code-stub-assembler.h" 9 #include "src/code-stub-assembler.h"
10 #include "src/contexts.h" 10 #include "src/contexts.h"
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 408
409 if (JSArray::HasReadOnlyLength(array)) { 409 if (JSArray::HasReadOnlyLength(array)) {
410 return CallJsIntrinsic(isolate, isolate->array_unshift(), args); 410 return CallJsIntrinsic(isolate, isolate->array_unshift(), args);
411 } 411 }
412 412
413 ElementsAccessor* accessor = array->GetElementsAccessor(); 413 ElementsAccessor* accessor = array->GetElementsAccessor();
414 int new_length = accessor->Unshift(array, &args, to_add); 414 int new_length = accessor->Unshift(array, &args, to_add);
415 return Smi::FromInt(new_length); 415 return Smi::FromInt(new_length);
416 } 416 }
417 417
418 class ForEachCodeStubAssembler : public CodeStubAssembler { 418 class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler {
419 public: 419 public:
420 explicit ForEachCodeStubAssembler(compiler::CodeAssemblerState* state) 420 explicit ArrayBuiltinCodeStubAssembler(compiler::CodeAssemblerState* state)
421 : CodeStubAssembler(state) {} 421 : CodeStubAssembler(state) {}
422 422
423 void VisitOneElement(Node* context, Node* this_arg, Node* o, Node* k, 423 typedef std::function<Node*(Node* o, Node* len)> BuiltinResultGenerator;
424 Node* callbackfn) { 424 typedef std::function<void(Node* a, Node* pK, Node* value)>
425 Comment("begin VisitOneElement"); 425 CallResultProcessor;
426 426
427 // a. Let Pk be ToString(k). 427 void GenerateArrayIteratingBuiltinBody(
428 Node* p_k = ToString(context, k); 428 const char* name, Node* receiver, Node* callbackfn, Node* this_arg,
429 Node* context, const BuiltinResultGenerator& generator,
430 const CallResultProcessor& processor) {
431 Variable k(this, MachineRepresentation::kTagged, SmiConstant(0));
432 Label non_array(this), slow(this, &k), array_changes(this, &k);
429 433
430 // b. Let kPresent be HasProperty(O, Pk). 434 // TODO(danno): Seriously? Do we really need to throw the exact error
431 // c. ReturnIfAbrupt(kPresent). 435 // message on null and undefined so that the webkit tests pass?
432 Node* k_present = 436 Label throw_null_undefined_exception(this, Label::kDeferred);
433 CallStub(CodeFactory::HasProperty(isolate()), context, p_k, o); 437 GotoIf(WordEqual(receiver, NullConstant()),
438 &throw_null_undefined_exception);
439 GotoIf(WordEqual(receiver, UndefinedConstant()),
440 &throw_null_undefined_exception);
434 441
435 // d. If kPresent is true, then 442 // By the book: taken directly from the ECMAScript 2015 specification
436 Label not_present(this);
437 GotoIf(WordNotEqual(k_present, TrueConstant()), &not_present);
438 443
439 // i. Let kValue be Get(O, Pk). 444 // 1. Let O be ToObject(this value).
440 // ii. ReturnIfAbrupt(kValue). 445 // 2. ReturnIfAbrupt(O)
441 Node* k_value = 446 Node* o = CallStub(CodeFactory::ToObject(isolate()), context, receiver);
442 CallStub(CodeFactory::GetProperty(isolate()), context, o, k);
443 447
444 // iii. Let funcResult be Call(callbackfn, T, «kValue, k, O»). 448 // 3. Let len be ToLength(Get(O, "length")).
445 // iv. ReturnIfAbrupt(funcResult). 449 // 4. ReturnIfAbrupt(len).
446 CallJS(CodeFactory::Call(isolate()), context, callbackfn, this_arg, k_value, 450 Variable merged_length(this, MachineRepresentation::kTagged);
447 k, o); 451 Label has_length(this, &merged_length), not_js_array(this);
452 GotoIf(DoesntHaveInstanceType(o, JS_ARRAY_TYPE), &not_js_array);
453 merged_length.Bind(LoadJSArrayLength(o));
454 Goto(&has_length);
455 Bind(&not_js_array);
456 Node* len_property =
457 CallStub(CodeFactory::GetProperty(isolate()), context, o,
458 HeapConstant(isolate()->factory()->length_string()));
459 merged_length.Bind(
460 CallStub(CodeFactory::ToLength(isolate()), context, len_property));
461 Goto(&has_length);
462 Bind(&has_length);
463 Node* len = merged_length.value();
448 464
449 Goto(&not_present); 465 // 5. If IsCallable(callbackfn) is false, throw a TypeError exception.
450 Bind(&not_present); 466 Label type_exception(this, Label::kDeferred);
451 Comment("end VisitOneElement"); 467 Label done(this);
468 GotoIf(TaggedIsSmi(callbackfn), &type_exception);
469 Branch(IsCallableMap(LoadMap(callbackfn)), &done, &type_exception);
470
471 Bind(&throw_null_undefined_exception);
472 {
473 CallRuntime(
474 Runtime::kThrowTypeError, context,
475 SmiConstant(MessageTemplate::kCalledOnNullOrUndefined),
476 HeapConstant(isolate()->factory()->NewStringFromAsciiChecked(name)));
477 Unreachable();
478 }
479
480 Bind(&type_exception);
481 {
482 CallRuntime(Runtime::kThrowTypeError, context,
483 SmiConstant(MessageTemplate::kCalledNonCallable), callbackfn);
484 Unreachable();
485 }
486
487 Bind(&done);
488
489 Node* a = generator(o, len);
490
491 // 6. If thisArg was supplied, let T be thisArg; else let T be undefined.
492 // [Already done by the arguments adapter]
493
494 HandleFastElements(context, this_arg, o, len, callbackfn, processor, a, k,
495 &slow);
496
497 // 7. Let k be 0.
498 // Already done above in initialization of the Variable k
499
500 Bind(&slow);
501 {
502 // 8. Repeat, while k < len
503 Label loop(this, &k);
504 Label after_loop(this);
505 Goto(&loop);
506 Bind(&loop);
507 {
508 GotoUnlessNumberLessThan(k.value(), len, &after_loop);
509
510 Label done_element(this);
511 // a. Let Pk be ToString(k).
512 Node* p_k = ToString(context, k.value());
513
514 // b. Let kPresent be HasProperty(O, Pk).
515 // c. ReturnIfAbrupt(kPresent).
516 Node* k_present =
517 CallStub(CodeFactory::HasProperty(isolate()), context, p_k, o);
518
519 // d. If kPresent is true, then
520 GotoIf(WordNotEqual(k_present, TrueConstant()), &done_element);
521
522 // i. Let kValue be Get(O, Pk).
523 // ii. ReturnIfAbrupt(kValue).
524 Node* k_value = CallStub(CodeFactory::GetProperty(isolate()), context,
525 o, k.value());
526
527 // iii. Let funcResult be Call(callbackfn, T, «kValue, k, O»).
528 // iv. ReturnIfAbrupt(funcResult).
529 Node* result = CallJS(CodeFactory::Call(isolate()), context, callbackfn,
530 this_arg, k_value, k.value(), o);
531
532 processor(a, p_k, result);
533 Goto(&done_element);
534 Bind(&done_element);
535
536 // e. Increase k by 1.
537 k.Bind(NumberInc(k.value()));
538 Goto(&loop);
539 }
540 Bind(&after_loop);
541 Return(a);
542 }
452 } 543 }
453 544
454 void VisitAllFastElements(Node* context, ElementsKind kind, Node* this_arg, 545 private:
455 Node* o, Node* len, Node* callbackfn, 546 Node* VisitAllFastElementsOneKind(Node* context, ElementsKind kind,
456 ParameterMode mode) { 547 Node* this_arg, Node* o, Node* len,
457 Comment("begin VisitAllFastElements"); 548 Node* callbackfn,
549 const CallResultProcessor& processor,
550 Node* a, Label* array_changed,
551 ParameterMode mode) {
552 Comment("begin VisitAllFastElementsOneKind");
458 Variable original_map(this, MachineRepresentation::kTagged); 553 Variable original_map(this, MachineRepresentation::kTagged);
459 original_map.Bind(LoadMap(o)); 554 original_map.Bind(LoadMap(o));
460 VariableList list({&original_map}, zone()); 555 VariableList list({&original_map}, zone());
556 Node* last_index = nullptr;
461 BuildFastLoop( 557 BuildFastLoop(
462 list, IntPtrOrSmiConstant(0, mode), TaggedToParameter(len, mode), 558 list, IntPtrOrSmiConstant(0, mode), TaggedToParameter(len, mode),
463 [context, kind, this, o, &original_map, callbackfn, this_arg, 559 [=, &original_map, &last_index](Node* index) {
464 mode](Node* index) { 560 last_index = index;
465 Label one_element_done(this), array_changed(this, Label::kDeferred), 561 Label one_element_done(this), hole_element(this);
466 hole_element(this);
467 562
468 // Check if o's map has changed during the callback. If so, we have to 563 // Check if o's map has changed during the callback. If so, we have to
469 // fall back to the slower spec implementation for the rest of the 564 // fall back to the slower spec implementation for the rest of the
470 // iteration. 565 // iteration.
471 Node* o_map = LoadMap(o); 566 Node* o_map = LoadMap(o);
472 GotoIf(WordNotEqual(o_map, original_map.value()), &array_changed); 567 GotoIf(WordNotEqual(o_map, original_map.value()), array_changed);
473 568
474 // Check if o's length has changed during the callback and if the 569 // Check if o's length has changed during the callback and if the
475 // index is now out of range of the new length. 570 // index is now out of range of the new length.
476 Node* tagged_index = ParameterToTagged(index, mode); 571 Node* tagged_index = ParameterToTagged(index, mode);
477 GotoIf(SmiGreaterThanOrEqual(tagged_index, LoadJSArrayLength(o)), 572 GotoIf(SmiGreaterThanOrEqual(tagged_index, LoadJSArrayLength(o)),
478 &array_changed); 573 array_changed);
479 574
480 // Re-load the elements array. If may have been resized. 575 // Re-load the elements array. If may have been resized.
481 Node* elements = LoadElements(o); 576 Node* elements = LoadElements(o);
482 577
483 // Fast case: load the element directly from the elements FixedArray 578 // Fast case: load the element directly from the elements FixedArray
484 // and call the callback if the element is not the hole. 579 // and call the callback if the element is not the hole.
485 DCHECK(kind == FAST_ELEMENTS || kind == FAST_DOUBLE_ELEMENTS); 580 DCHECK(kind == FAST_ELEMENTS || kind == FAST_DOUBLE_ELEMENTS);
486 int base_size = kind == FAST_ELEMENTS 581 int base_size = kind == FAST_ELEMENTS
487 ? FixedArray::kHeaderSize 582 ? FixedArray::kHeaderSize
488 : (FixedArray::kHeaderSize - kHeapObjectTag); 583 : (FixedArray::kHeaderSize - kHeapObjectTag);
489 Node* offset = ElementOffsetFromIndex(index, kind, mode, base_size); 584 Node* offset = ElementOffsetFromIndex(index, kind, mode, base_size);
490 Node* value = nullptr; 585 Node* value = nullptr;
491 if (kind == FAST_ELEMENTS) { 586 if (kind == FAST_ELEMENTS) {
492 value = LoadObjectField(elements, offset); 587 value = LoadObjectField(elements, offset);
493 GotoIf(WordEqual(value, TheHoleConstant()), &hole_element); 588 GotoIf(WordEqual(value, TheHoleConstant()), &hole_element);
494 } else { 589 } else {
495 Node* double_value = 590 Node* double_value =
496 LoadDoubleWithHoleCheck(elements, offset, &hole_element); 591 LoadDoubleWithHoleCheck(elements, offset, &hole_element);
497 value = AllocateHeapNumberWithValue(double_value); 592 value = AllocateHeapNumberWithValue(double_value);
498 } 593 }
499 CallJS(CodeFactory::Call(isolate()), context, callbackfn, this_arg, 594 Node* result = CallJS(CodeFactory::Call(isolate()), context,
500 value, tagged_index, o); 595 callbackfn, this_arg, value, tagged_index, o);
596 processor(a, tagged_index, result);
501 Goto(&one_element_done); 597 Goto(&one_element_done);
502 598
503 Bind(&hole_element); 599 Bind(&hole_element);
600 // Check if o's prototype change unexpectedly has elements after the
601 // callback in the case of a hole.
504 BranchIfPrototypesHaveNoElements(o_map, &one_element_done, 602 BranchIfPrototypesHaveNoElements(o_map, &one_element_done,
505 &array_changed); 603 array_changed);
506
507 // O's changed during the forEach. Use the implementation precisely
508 // specified in the spec for the rest of the iteration, also making
509 // the failed original_map sticky in case of a subseuent change that
510 // goes back to the original map.
511 Bind(&array_changed);
512 VisitOneElement(context, this_arg, o, ParameterToTagged(index, mode),
513 callbackfn);
514 original_map.Bind(UndefinedConstant());
515 Goto(&one_element_done);
516 604
517 Bind(&one_element_done); 605 Bind(&one_element_done);
518 }, 606 },
519 1, mode, IndexAdvanceMode::kPost); 607 1, mode, IndexAdvanceMode::kPost);
520 Comment("end VisitAllFastElements"); 608 Comment("end VisitAllFastElementsOneKind");
609 return last_index;
610 }
611
612 void HandleFastElements(Node* context, Node* this_arg, Node* o, Node* len,
613 Node* callbackfn, CallResultProcessor processor,
614 Node* a, Variable& k, Label* slow) {
615 Label switch_on_elements_kind(this), fast_elements(this),
616 maybe_double_elements(this), fast_double_elements(this);
617
618 Comment("begin HandleFastElements");
619 // Non-smi lengths must use the slow path.
620 GotoIf(TaggedIsNotSmi(len), slow);
621
622 BranchIfFastJSArray(o, context,
623 CodeStubAssembler::FastJSArrayAccessMode::INBOUNDS_READ,
624 &switch_on_elements_kind, slow);
625
626 Bind(&switch_on_elements_kind);
627 // Select by ElementsKind
628 Node* o_map = LoadMap(o);
629 Node* bit_field2 = LoadMapBitField2(o_map);
630 Node* kind = DecodeWord32<Map::ElementsKindBits>(bit_field2);
631 Branch(Int32GreaterThan(kind, Int32Constant(FAST_HOLEY_ELEMENTS)),
632 &maybe_double_elements, &fast_elements);
633
634 ParameterMode mode = OptimalParameterMode();
635 Bind(&fast_elements);
636 {
637 Label array_changed(this, Label::kDeferred);
638 Node* last_index = VisitAllFastElementsOneKind(
639 context, FAST_ELEMENTS, this_arg, o, len, callbackfn, processor, a,
640 &array_changed, mode);
641
642 // No exception, return success
643 Return(a);
644
645 Bind(&array_changed);
646 k.Bind(ParameterToTagged(last_index, mode));
647 Goto(slow);
648 }
649
650 Bind(&maybe_double_elements);
651 Branch(Int32GreaterThan(kind, Int32Constant(FAST_HOLEY_DOUBLE_ELEMENTS)),
652 slow, &fast_double_elements);
653
654 Bind(&fast_double_elements);
655 {
656 Label array_changed(this, Label::kDeferred);
657 Node* last_index = VisitAllFastElementsOneKind(
658 context, FAST_DOUBLE_ELEMENTS, this_arg, o, len, callbackfn,
659 processor, a, &array_changed, mode);
660
661 // No exception, return success
662 Return(a);
663
664 Bind(&array_changed);
665 k.Bind(ParameterToTagged(last_index, mode));
666 Goto(slow);
667 }
521 } 668 }
522 }; 669 };
523 670
524 TF_BUILTIN(ArrayForEach, ForEachCodeStubAssembler) { 671 TF_BUILTIN(ArrayForEach, ArrayBuiltinCodeStubAssembler) {
525 Label non_array(this), examine_elements(this), fast_elements(this),
526 slow(this), maybe_double_elements(this), fast_double_elements(this);
527
528 Node* receiver = Parameter(ForEachDescriptor::kReceiver); 672 Node* receiver = Parameter(ForEachDescriptor::kReceiver);
529 Node* callbackfn = Parameter(ForEachDescriptor::kCallback); 673 Node* callbackfn = Parameter(ForEachDescriptor::kCallback);
530 Node* this_arg = Parameter(ForEachDescriptor::kThisArg); 674 Node* this_arg = Parameter(ForEachDescriptor::kThisArg);
531 Node* context = Parameter(ForEachDescriptor::kContext); 675 Node* context = Parameter(ForEachDescriptor::kContext);
532 676
533 // TODO(danno): Seriously? Do we really need to throw the exact error message 677 GenerateArrayIteratingBuiltinBody(
534 // on null and undefined so that the webkit tests pass? 678 "Array.prototype.forEach", receiver, callbackfn, this_arg, context,
535 Label throw_null_undefined_exception(this, Label::kDeferred); 679 [=](Node*, Node*) { return UndefinedConstant(); },
536 GotoIf(WordEqual(receiver, NullConstant()), &throw_null_undefined_exception); 680 [](Node* a, Node* p_k, Node* value) {});
537 GotoIf(WordEqual(receiver, UndefinedConstant()), 681 }
538 &throw_null_undefined_exception);
539 682
540 // By the book: taken directly from the ECMAScript 2015 specification 683 TF_BUILTIN(ArrayEvery, ArrayBuiltinCodeStubAssembler) {
684 Node* receiver = Parameter(ForEachDescriptor::kReceiver);
685 Node* callbackfn = Parameter(ForEachDescriptor::kCallback);
686 Node* this_arg = Parameter(ForEachDescriptor::kThisArg);
687 Node* context = Parameter(ForEachDescriptor::kContext);
541 688
542 // 1. Let O be ToObject(this value). 689 GenerateArrayIteratingBuiltinBody(
543 // 2. ReturnIfAbrupt(O) 690 "Array.prototype.every", receiver, callbackfn, this_arg, context,
544 Node* o = CallStub(CodeFactory::ToObject(isolate()), context, receiver); 691 [=](Node*, Node*) { return TrueConstant(); },
692 [=](Node* a, Node* p_k, Node* value) {
693 Label true_continue(this), return_false(this);
694 BranchIfToBooleanIsTrue(value, &true_continue, &return_false);
695 Bind(&return_false);
696 Return(FalseConstant());
697 Bind(&true_continue);
698 });
699 }
545 700
546 // 3. Let len be ToLength(Get(O, "length")). 701 TF_BUILTIN(ArraySome, ArrayBuiltinCodeStubAssembler) {
547 // 4. ReturnIfAbrupt(len). 702 Node* receiver = Parameter(ForEachDescriptor::kReceiver);
548 Variable merged_length(this, MachineRepresentation::kTagged); 703 Node* callbackfn = Parameter(ForEachDescriptor::kCallback);
549 Label has_length(this, &merged_length), not_js_array(this); 704 Node* this_arg = Parameter(ForEachDescriptor::kThisArg);
550 GotoIf(DoesntHaveInstanceType(o, JS_ARRAY_TYPE), &not_js_array); 705 Node* context = Parameter(ForEachDescriptor::kContext);
551 merged_length.Bind(LoadJSArrayLength(o));
552 Goto(&has_length);
553 Bind(&not_js_array);
554 Node* len_property =
555 CallStub(CodeFactory::GetProperty(isolate()), context, o,
556 HeapConstant(isolate()->factory()->length_string()));
557 merged_length.Bind(
558 CallStub(CodeFactory::ToLength(isolate()), context, len_property));
559 Goto(&has_length);
560 Bind(&has_length);
561 Node* len = merged_length.value();
562 706
563 // 5. If IsCallable(callbackfn) is false, throw a TypeError exception. 707 GenerateArrayIteratingBuiltinBody(
564 Label type_exception(this, Label::kDeferred); 708 "Array.prototype.some", receiver, callbackfn, this_arg, context,
565 GotoIf(TaggedIsSmi(callbackfn), &type_exception); 709 [=](Node*, Node*) { return FalseConstant(); },
566 GotoIfNot(IsCallableMap(LoadMap(callbackfn)), &type_exception); 710 [=](Node* a, Node* p_k, Node* value) {
567 711 Label false_continue(this), return_true(this);
568 // 6. If thisArg was supplied, let T be thisArg; else let T be undefined. 712 BranchIfToBooleanIsTrue(value, &return_true, &false_continue);
569 // [Already done by the arguments adapter] 713 Bind(&return_true);
570 714 Return(TrueConstant());
571 // Non-smi lengths must use the slow path. 715 Bind(&false_continue);
572 GotoIf(TaggedIsNotSmi(len), &slow); 716 });
573
574 BranchIfFastJSArray(o, context,
575 CodeStubAssembler::FastJSArrayAccessMode::INBOUNDS_READ,
576 &examine_elements, &slow);
577
578 Bind(&examine_elements);
579
580 ParameterMode mode = OptimalParameterMode();
581
582 // Select by ElementsKind
583 Node* o_map = LoadMap(o);
584 Node* bit_field2 = LoadMapBitField2(o_map);
585 Node* kind = DecodeWord32<Map::ElementsKindBits>(bit_field2);
586 Branch(Int32GreaterThan(kind, Int32Constant(FAST_HOLEY_ELEMENTS)),
587 &maybe_double_elements, &fast_elements);
588
589 Bind(&fast_elements);
590 {
591 VisitAllFastElements(context, FAST_ELEMENTS, this_arg, o, len, callbackfn,
592 mode);
593
594 // No exception, return success
595 Return(UndefinedConstant());
596 }
597
598 Bind(&maybe_double_elements);
599 Branch(Int32GreaterThan(kind, Int32Constant(FAST_HOLEY_DOUBLE_ELEMENTS)),
600 &slow, &fast_double_elements);
601
602 Bind(&fast_double_elements);
603 {
604 VisitAllFastElements(context, FAST_DOUBLE_ELEMENTS, this_arg, o, len,
605 callbackfn, mode);
606
607 // No exception, return success
608 Return(UndefinedConstant());
609 }
610
611 Bind(&slow);
612 {
613 // By the book: taken from the ECMAScript 2015 specification (cont.)
614
615 // 7. Let k be 0.
616 Variable k(this, MachineRepresentation::kTagged);
617 k.Bind(SmiConstant(0));
618
619 // 8. Repeat, while k < len
620 Label loop(this, &k);
621 Label after_loop(this);
622 Goto(&loop);
623 Bind(&loop);
624 {
625 GotoUnlessNumberLessThan(k.value(), len, &after_loop);
626
627 VisitOneElement(context, this_arg, o, k.value(), callbackfn);
628
629 // e. Increase k by 1.
630 k.Bind(NumberInc(k.value()));
631 Goto(&loop);
632 }
633 Bind(&after_loop);
634 Return(UndefinedConstant());
635 }
636
637 Bind(&throw_null_undefined_exception);
638 {
639 CallRuntime(Runtime::kThrowTypeError, context,
640 SmiConstant(MessageTemplate::kCalledOnNullOrUndefined),
641 HeapConstant(isolate()->factory()->NewStringFromAsciiChecked(
642 "Array.prototype.forEach")));
643 Unreachable();
644 }
645
646 Bind(&type_exception);
647 {
648 CallRuntime(Runtime::kThrowTypeError, context,
649 SmiConstant(MessageTemplate::kCalledNonCallable), callbackfn);
650 Unreachable();
651 }
652 } 717 }
653 718
654 BUILTIN(ArraySlice) { 719 BUILTIN(ArraySlice) {
655 HandleScope scope(isolate); 720 HandleScope scope(isolate);
656 Handle<Object> receiver = args.receiver(); 721 Handle<Object> receiver = args.receiver();
657 int len = -1; 722 int len = -1;
658 int relative_start = 0; 723 int relative_start = 0;
659 int relative_end = 0; 724 int relative_end = 0;
660 725
661 if (receiver->IsJSArray()) { 726 if (receiver->IsJSArray()) {
(...skipping 2021 matching lines...) Expand 10 before | Expand all | Expand 10 after
2683 { 2748 {
2684 Node* message = SmiConstant(MessageTemplate::kDetachedOperation); 2749 Node* message = SmiConstant(MessageTemplate::kDetachedOperation);
2685 CallRuntime(Runtime::kThrowTypeError, context, message, 2750 CallRuntime(Runtime::kThrowTypeError, context, message,
2686 HeapConstant(operation)); 2751 HeapConstant(operation));
2687 Unreachable(); 2752 Unreachable();
2688 } 2753 }
2689 } 2754 }
2690 2755
2691 } // namespace internal 2756 } // namespace internal
2692 } // namespace v8 2757 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/builtins.h ('k') | src/debug/debug-evaluate.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698