| 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 #if V8_TARGET_ARCH_PPC | 5 #if V8_TARGET_ARCH_PPC |
| 6 | 6 |
| 7 #include "src/codegen.h" | 7 #include "src/codegen.h" |
| 8 #include "src/debug/debug.h" | 8 #include "src/debug/debug.h" |
| 9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
| 10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
| (...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 441 GenerateTailCallToReturnedCode(masm, Runtime::kTryInstallOptimizedCode); | 441 GenerateTailCallToReturnedCode(masm, Runtime::kTryInstallOptimizedCode); |
| 442 | 442 |
| 443 __ bind(&ok); | 443 __ bind(&ok); |
| 444 GenerateTailCallToSharedCode(masm); | 444 GenerateTailCallToSharedCode(masm); |
| 445 } | 445 } |
| 446 | 446 |
| 447 namespace { | 447 namespace { |
| 448 | 448 |
| 449 void Generate_JSConstructStubHelper(MacroAssembler* masm, bool is_api_function, | 449 void Generate_JSConstructStubHelper(MacroAssembler* masm, bool is_api_function, |
| 450 bool create_implicit_receiver, | 450 bool create_implicit_receiver, |
| 451 bool check_derived_construct) { | 451 bool disallow_non_object_return) { |
| 452 Label post_instantiation_deopt_entry; | 452 Label post_instantiation_deopt_entry; |
| 453 // ----------- S t a t e ------------- | 453 // ----------- S t a t e ------------- |
| 454 // -- r3 : number of arguments | 454 // -- r3 : number of arguments |
| 455 // -- r4 : constructor function | 455 // -- r4 : constructor function |
| 456 // -- r6 : new target | 456 // -- r6 : new target |
| 457 // -- cp : context | 457 // -- cp : context |
| 458 // -- lr : return address | 458 // -- lr : return address |
| 459 // -- sp[...]: constructor arguments | 459 // -- sp[...]: constructor arguments |
| 460 // ----------------------------------- | 460 // ----------------------------------- |
| 461 | 461 |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 530 // r4: constructor function | 530 // r4: constructor function |
| 531 // r6: new target | 531 // r6: new target |
| 532 { | 532 { |
| 533 ConstantPoolUnavailableScope constant_pool_unavailable(masm); | 533 ConstantPoolUnavailableScope constant_pool_unavailable(masm); |
| 534 ParameterCount actual(r3); | 534 ParameterCount actual(r3); |
| 535 __ InvokeFunction(r4, r6, actual, CALL_FUNCTION, | 535 __ InvokeFunction(r4, r6, actual, CALL_FUNCTION, |
| 536 CheckDebugStepCallWrapper()); | 536 CheckDebugStepCallWrapper()); |
| 537 } | 537 } |
| 538 | 538 |
| 539 // Store offset of return address for deoptimizer. | 539 // Store offset of return address for deoptimizer. |
| 540 if (create_implicit_receiver && !is_api_function) { | 540 if (create_implicit_receiver && !disallow_non_object_return && |
| 541 !is_api_function) { |
| 541 masm->isolate()->heap()->SetConstructStubInvokeDeoptPCOffset( | 542 masm->isolate()->heap()->SetConstructStubInvokeDeoptPCOffset( |
| 542 masm->pc_offset()); | 543 masm->pc_offset()); |
| 543 } | 544 } |
| 544 | 545 |
| 545 // Restore context from the frame. | 546 // Restore context from the frame. |
| 546 // r3: result | 547 // r3: result |
| 547 // sp[0]: receiver | 548 // sp[0]: receiver |
| 548 // sp[1]: number of arguments (smi-tagged) | 549 // sp[1]: number of arguments (smi-tagged) |
| 549 __ LoadP(cp, MemOperand(fp, ConstructFrameConstants::kContextOffset)); | 550 __ LoadP(cp, MemOperand(fp, ConstructFrameConstants::kContextOffset)); |
| 550 | 551 |
| 551 if (create_implicit_receiver) { | 552 if (create_implicit_receiver) { |
| 552 // If the result is an object (in the ECMA sense), we should get rid | 553 // If the result is an object (in the ECMA sense), we should get rid |
| 553 // of the receiver and use the result; see ECMA-262 section 13.2.2-7 | 554 // of the receiver and use the result; see ECMA-262 section 13.2.2-7 |
| 554 // on page 74. | 555 // on page 74. |
| 555 Label use_receiver, exit; | 556 Label use_receiver, return_value, do_throw; |
| 556 | 557 |
| 557 // If the result is a smi, it is *not* an object in the ECMA sense. | 558 // If the result is a smi, it is *not* an object in the ECMA sense. |
| 558 // r3: result | 559 // r3: result |
| 559 // sp[0]: receiver | 560 // sp[0]: receiver |
| 560 // sp[1]: number of arguments (smi-tagged) | 561 // sp[1]: number of arguments (smi-tagged) |
| 561 __ JumpIfSmi(r3, &use_receiver); | 562 // If the result is undefined, we jump out to using the implicit |
| 563 // receiver, otherwise we do a smi check and fall through to |
| 564 // check if the return value is a valid receiver. |
| 565 if (disallow_non_object_return) { |
| 566 __ CompareRoot(r3, Heap::kUndefinedValueRootIndex); |
| 567 __ beq(&use_receiver); |
| 568 __ JumpIfSmi(r3, &do_throw); |
| 569 } else { |
| 570 __ JumpIfSmi(r3, &use_receiver); |
| 571 } |
| 562 | 572 |
| 563 // If the type of the result (stored in its map) is less than | 573 // If the type of the result (stored in its map) is less than |
| 564 // FIRST_JS_RECEIVER_TYPE, it is not an object in the ECMA sense. | 574 // FIRST_JS_RECEIVER_TYPE, it is not an object in the ECMA sense. |
| 565 __ CompareObjectType(r3, r4, r6, FIRST_JS_RECEIVER_TYPE); | 575 __ CompareObjectType(r3, r4, r6, FIRST_JS_RECEIVER_TYPE); |
| 566 __ bge(&exit); | 576 __ bge(&return_value); |
| 577 |
| 578 if (disallow_non_object_return) { |
| 579 __ bind(&do_throw); |
| 580 __ CallRuntime(Runtime::kThrowConstructorReturnedNonObject); |
| 581 } |
| 567 | 582 |
| 568 // Throw away the result of the constructor invocation and use the | 583 // Throw away the result of the constructor invocation and use the |
| 569 // on-stack receiver as the result. | 584 // on-stack receiver as the result. |
| 570 __ bind(&use_receiver); | 585 __ bind(&use_receiver); |
| 571 __ LoadP(r3, MemOperand(sp)); | 586 __ LoadP(r3, MemOperand(sp)); |
| 572 | 587 |
| 573 // Remove receiver from the stack, remove caller arguments, and | 588 // Remove receiver from the stack, remove caller arguments, and |
| 574 // return. | 589 // return. |
| 575 __ bind(&exit); | 590 __ bind(&return_value); |
| 576 // r3: result | 591 // r3: result |
| 577 // sp[0]: receiver (newly allocated object) | 592 // sp[0]: receiver (newly allocated object) |
| 578 // sp[1]: number of arguments (smi-tagged) | 593 // sp[1]: number of arguments (smi-tagged) |
| 579 __ LoadP(r4, MemOperand(sp, 1 * kPointerSize)); | 594 __ LoadP(r4, MemOperand(sp, 1 * kPointerSize)); |
| 580 } else { | 595 } else { |
| 581 __ LoadP(r4, MemOperand(sp)); | 596 __ LoadP(r4, MemOperand(sp)); |
| 582 } | 597 } |
| 583 | 598 |
| 584 // Leave construct frame. | 599 // Leave construct frame. |
| 585 } | 600 } |
| 586 | 601 |
| 587 // ES6 9.2.2. Step 13+ | 602 // ES6 9.2.2. Step 13+ |
| 588 // Check that the result is not a Smi, indicating that the constructor result | 603 // For derived class constructors, throw a TypeError here if the result |
| 589 // from a derived class is neither undefined nor an Object. | 604 // is not a JSReceiver. For the base constructor, we've already checked |
| 590 if (check_derived_construct) { | 605 // the result, so we omit the check. |
| 606 if (disallow_non_object_return && !create_implicit_receiver) { |
| 591 Label do_throw, dont_throw; | 607 Label do_throw, dont_throw; |
| 592 __ JumpIfSmi(r3, &do_throw); | 608 __ JumpIfSmi(r3, &do_throw); |
| 593 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); | 609 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); |
| 594 __ CompareObjectType(r3, r6, r6, FIRST_JS_RECEIVER_TYPE); | 610 __ CompareObjectType(r3, r6, r6, FIRST_JS_RECEIVER_TYPE); |
| 595 __ bge(&dont_throw); | 611 __ bge(&dont_throw); |
| 596 __ bind(&do_throw); | 612 __ bind(&do_throw); |
| 597 { | 613 { |
| 598 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 614 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 599 __ CallRuntime(Runtime::kThrowDerivedConstructorReturnedNonObject); | 615 __ CallRuntime(Runtime::kThrowConstructorReturnedNonObject); |
| 600 } | 616 } |
| 601 __ bind(&dont_throw); | 617 __ bind(&dont_throw); |
| 602 } | 618 } |
| 603 | 619 |
| 604 __ SmiToPtrArrayOffset(r4, r4); | 620 __ SmiToPtrArrayOffset(r4, r4); |
| 605 __ add(sp, sp, r4); | 621 __ add(sp, sp, r4); |
| 606 __ addi(sp, sp, Operand(kPointerSize)); | 622 __ addi(sp, sp, Operand(kPointerSize)); |
| 607 if (create_implicit_receiver) { | 623 if (create_implicit_receiver) { |
| 608 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, r4, r5); | 624 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, r4, r5); |
| 609 } | 625 } |
| 610 __ blr(); | 626 __ blr(); |
| 611 // Store offset of trampoline address for deoptimizer. This is the bailout | 627 // Store offset of trampoline address for deoptimizer. This is the bailout |
| 612 // point after the receiver instantiation but before the function invocation. | 628 // point after the receiver instantiation but before the function invocation. |
| 613 // We need to restore some registers in order to continue the above code. | 629 // We need to restore some registers in order to continue the above code. |
| 614 if (create_implicit_receiver && !is_api_function) { | 630 if (create_implicit_receiver && !disallow_non_object_return && |
| 631 !is_api_function) { |
| 615 masm->isolate()->heap()->SetConstructStubCreateDeoptPCOffset( | 632 masm->isolate()->heap()->SetConstructStubCreateDeoptPCOffset( |
| 616 masm->pc_offset()); | 633 masm->pc_offset()); |
| 617 | 634 |
| 618 // ----------- S t a t e ------------- | 635 // ----------- S t a t e ------------- |
| 619 // -- r3 : newly allocated object | 636 // -- r3 : newly allocated object |
| 620 // -- sp[0] : constructor function | 637 // -- sp[0] : constructor function |
| 621 // ----------------------------------- | 638 // ----------------------------------- |
| 622 | 639 |
| 623 __ pop(r4); | 640 __ pop(r4); |
| 624 __ Push(r3, r3); | 641 __ Push(r3, r3); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 645 } | 662 } |
| 646 | 663 |
| 647 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { | 664 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { |
| 648 Generate_JSConstructStubHelper(masm, true, false, false); | 665 Generate_JSConstructStubHelper(masm, true, false, false); |
| 649 } | 666 } |
| 650 | 667 |
| 651 void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) { | 668 void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) { |
| 652 Generate_JSConstructStubHelper(masm, false, false, false); | 669 Generate_JSConstructStubHelper(masm, false, false, false); |
| 653 } | 670 } |
| 654 | 671 |
| 672 void Builtins::Generate_JSBuiltinsConstructStubForBase(MacroAssembler* masm) { |
| 673 Generate_JSConstructStubHelper(masm, false, true, true); |
| 674 } |
| 675 |
| 655 void Builtins::Generate_JSBuiltinsConstructStubForDerived( | 676 void Builtins::Generate_JSBuiltinsConstructStubForDerived( |
| 656 MacroAssembler* masm) { | 677 MacroAssembler* masm) { |
| 657 Generate_JSConstructStubHelper(masm, false, false, true); | 678 Generate_JSConstructStubHelper(masm, false, false, true); |
| 658 } | 679 } |
| 659 | 680 |
| 660 // static | 681 // static |
| 661 void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) { | 682 void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) { |
| 662 // ----------- S t a t e ------------- | 683 // ----------- S t a t e ------------- |
| 663 // -- r3 : the value to pass to the generator | 684 // -- r3 : the value to pass to the generator |
| 664 // -- r4 : the JSGeneratorObject to resume | 685 // -- r4 : the JSGeneratorObject to resume |
| (...skipping 2422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3087 } | 3108 } |
| 3088 // Now jump to the instructions of the returned code object. | 3109 // Now jump to the instructions of the returned code object. |
| 3089 __ Jump(r11); | 3110 __ Jump(r11); |
| 3090 } | 3111 } |
| 3091 | 3112 |
| 3092 #undef __ | 3113 #undef __ |
| 3093 } // namespace internal | 3114 } // namespace internal |
| 3094 } // namespace v8 | 3115 } // namespace v8 |
| 3095 | 3116 |
| 3096 #endif // V8_TARGET_ARCH_PPC | 3117 #endif // V8_TARGET_ARCH_PPC |
| OLD | NEW |