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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_PPC | 7 #if V8_TARGET_ARCH_PPC |
8 | 8 |
9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 1962 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1973 if (result_saved) { | 1973 if (result_saved) { |
1974 __ Drop(1); // literal index | 1974 __ Drop(1); // literal index |
1975 context()->PlugTOS(); | 1975 context()->PlugTOS(); |
1976 } else { | 1976 } else { |
1977 context()->Plug(r3); | 1977 context()->Plug(r3); |
1978 } | 1978 } |
1979 } | 1979 } |
1980 | 1980 |
1981 | 1981 |
1982 void FullCodeGenerator::VisitAssignment(Assignment* expr) { | 1982 void FullCodeGenerator::VisitAssignment(Assignment* expr) { |
1983 DCHECK(expr->target()->IsValidReferenceExpression()); | 1983 DCHECK(expr->target()->IsValidReferenceExpressionOrThis()); |
1984 | 1984 |
1985 Comment cmnt(masm_, "[ Assignment"); | 1985 Comment cmnt(masm_, "[ Assignment"); |
1986 SetExpressionPosition(expr, INSERT_BREAK); | 1986 SetExpressionPosition(expr, INSERT_BREAK); |
1987 | 1987 |
1988 Property* property = expr->target()->AsProperty(); | 1988 Property* property = expr->target()->AsProperty(); |
1989 LhsKind assign_type = Property::GetAssignType(property); | 1989 LhsKind assign_type = Property::GetAssignType(property); |
1990 | 1990 |
1991 // Evaluate LHS expression. | 1991 // Evaluate LHS expression. |
1992 switch (assign_type) { | 1992 switch (assign_type) { |
1993 case VARIABLE: | 1993 case VARIABLE: |
(...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2690 CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code(); | 2690 CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code(); |
2691 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 2691 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
2692 CallIC(code, expr->BinaryOperationFeedbackId()); | 2692 CallIC(code, expr->BinaryOperationFeedbackId()); |
2693 patch_site.EmitPatchInfo(); | 2693 patch_site.EmitPatchInfo(); |
2694 context()->Plug(r3); | 2694 context()->Plug(r3); |
2695 } | 2695 } |
2696 | 2696 |
2697 | 2697 |
2698 void FullCodeGenerator::EmitAssignment(Expression* expr, | 2698 void FullCodeGenerator::EmitAssignment(Expression* expr, |
2699 FeedbackVectorICSlot slot) { | 2699 FeedbackVectorICSlot slot) { |
2700 DCHECK(expr->IsValidReferenceExpression()); | 2700 DCHECK(expr->IsValidReferenceExpressionOrThis()); |
2701 | 2701 |
2702 Property* prop = expr->AsProperty(); | 2702 Property* prop = expr->AsProperty(); |
2703 LhsKind assign_type = Property::GetAssignType(prop); | 2703 LhsKind assign_type = Property::GetAssignType(prop); |
2704 | 2704 |
2705 switch (assign_type) { | 2705 switch (assign_type) { |
2706 case VARIABLE: { | 2706 case VARIABLE: { |
2707 Variable* var = expr->AsVariableProxy()->var(); | 2707 Variable* var = expr->AsVariableProxy()->var(); |
2708 EffectContext context(this); | 2708 EffectContext context(this); |
2709 EmitVariableAssignment(var, Token::ASSIGN, slot); | 2709 EmitVariableAssignment(var, Token::ASSIGN, slot); |
2710 break; | 2710 break; |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2838 MemOperand location = VarOperand(var, r4); | 2838 MemOperand location = VarOperand(var, r4); |
2839 __ LoadP(r6, location); | 2839 __ LoadP(r6, location); |
2840 __ CompareRoot(r6, Heap::kTheHoleValueRootIndex); | 2840 __ CompareRoot(r6, Heap::kTheHoleValueRootIndex); |
2841 __ bne(&const_error); | 2841 __ bne(&const_error); |
2842 __ mov(r6, Operand(var->name())); | 2842 __ mov(r6, Operand(var->name())); |
2843 __ push(r6); | 2843 __ push(r6); |
2844 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 2844 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
2845 __ bind(&const_error); | 2845 __ bind(&const_error); |
2846 __ CallRuntime(Runtime::kThrowConstAssignError, 0); | 2846 __ CallRuntime(Runtime::kThrowConstAssignError, 0); |
2847 | 2847 |
| 2848 } else if (var->is_this() && op == Token::INIT_CONST) { |
| 2849 // Initializing assignment to const {this} needs a write barrier. |
| 2850 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 2851 Label uninitialized_this; |
| 2852 MemOperand location = VarOperand(var, r4); |
| 2853 __ LoadP(r6, location); |
| 2854 __ CompareRoot(r6, Heap::kTheHoleValueRootIndex); |
| 2855 __ beq(&uninitialized_this); |
| 2856 __ mov(r4, Operand(var->name())); |
| 2857 __ push(r4); |
| 2858 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
| 2859 __ bind(&uninitialized_this); |
| 2860 EmitStoreToStackLocalOrContextSlot(var, location); |
| 2861 |
2848 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { | 2862 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { |
2849 if (var->IsLookupSlot()) { | 2863 if (var->IsLookupSlot()) { |
2850 // Assignment to var. | 2864 // Assignment to var. |
2851 __ push(r3); // Value. | 2865 __ push(r3); // Value. |
2852 __ mov(r4, Operand(var->name())); | 2866 __ mov(r4, Operand(var->name())); |
2853 __ mov(r3, Operand(Smi::FromInt(language_mode()))); | 2867 __ mov(r3, Operand(Smi::FromInt(language_mode()))); |
2854 __ Push(cp, r4, r3); // Context, name, language mode. | 2868 __ Push(cp, r4, r3); // Context, name, language mode. |
2855 __ CallRuntime(Runtime::kStoreLookupSlot, 4); | 2869 __ CallRuntime(Runtime::kStoreLookupSlot, 4); |
2856 } else { | 2870 } else { |
2857 // Assignment to var or initializing assignment to let/const in harmony | 2871 // Assignment to var or initializing assignment to let/const in harmony |
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3180 | 3194 |
3181 // r4: the start position of the scope the calls resides in. | 3195 // r4: the start position of the scope the calls resides in. |
3182 __ LoadSmiLiteral(r4, Smi::FromInt(scope()->start_position())); | 3196 __ LoadSmiLiteral(r4, Smi::FromInt(scope()->start_position())); |
3183 | 3197 |
3184 // Do the runtime call. | 3198 // Do the runtime call. |
3185 __ Push(r7, r6, r5, r4); | 3199 __ Push(r7, r6, r5, r4); |
3186 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); | 3200 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); |
3187 } | 3201 } |
3188 | 3202 |
3189 | 3203 |
3190 void FullCodeGenerator::EmitInitializeThisAfterSuper( | |
3191 SuperCallReference* super_ref, FeedbackVectorICSlot slot) { | |
3192 Variable* this_var = super_ref->this_var()->var(); | |
3193 GetVar(r4, this_var); | |
3194 __ CompareRoot(r4, Heap::kTheHoleValueRootIndex); | |
3195 Label uninitialized_this; | |
3196 __ beq(&uninitialized_this); | |
3197 __ mov(r4, Operand(this_var->name())); | |
3198 __ push(r4); | |
3199 __ CallRuntime(Runtime::kThrowReferenceError, 1); | |
3200 __ bind(&uninitialized_this); | |
3201 | |
3202 EmitVariableAssignment(this_var, Token::INIT_CONST, slot); | |
3203 } | |
3204 | |
3205 | |
3206 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls. | 3204 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls. |
3207 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { | 3205 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { |
3208 VariableProxy* callee = expr->expression()->AsVariableProxy(); | 3206 VariableProxy* callee = expr->expression()->AsVariableProxy(); |
3209 if (callee->var()->IsLookupSlot()) { | 3207 if (callee->var()->IsLookupSlot()) { |
3210 Label slow, done; | 3208 Label slow, done; |
3211 SetExpressionPosition(callee); | 3209 SetExpressionPosition(callee); |
3212 // Generate code for loading from variables potentially shadowed by | 3210 // Generate code for loading from variables potentially shadowed by |
3213 // eval-introduced variables. | 3211 // eval-introduced variables. |
3214 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); | 3212 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); |
3215 | 3213 |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3418 __ Move(r5, FeedbackVector()); | 3416 __ Move(r5, FeedbackVector()); |
3419 __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallFeedbackSlot())); | 3417 __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallFeedbackSlot())); |
3420 | 3418 |
3421 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); | 3419 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); |
3422 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 3420 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |
3423 | 3421 |
3424 __ Drop(1); | 3422 __ Drop(1); |
3425 | 3423 |
3426 RecordJSReturnSite(expr); | 3424 RecordJSReturnSite(expr); |
3427 | 3425 |
3428 EmitInitializeThisAfterSuper(super_call_ref, expr->CallFeedbackICSlot()); | |
3429 context()->Plug(r3); | 3426 context()->Plug(r3); |
3430 } | 3427 } |
3431 | 3428 |
3432 | 3429 |
3433 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 3430 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
3434 ZoneList<Expression*>* args = expr->arguments(); | 3431 ZoneList<Expression*>* args = expr->arguments(); |
3435 DCHECK(args->length() == 1); | 3432 DCHECK(args->length() == 1); |
3436 | 3433 |
3437 VisitForAccumulatorValue(args->at(0)); | 3434 VisitForAccumulatorValue(args->at(0)); |
3438 | 3435 |
(...skipping 1337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4776 | 4773 |
4777 // Push NewTarget | 4774 // Push NewTarget |
4778 DCHECK(args->at(2)->IsVariableProxy()); | 4775 DCHECK(args->at(2)->IsVariableProxy()); |
4779 VisitForStackValue(args->at(2)); | 4776 VisitForStackValue(args->at(2)); |
4780 | 4777 |
4781 EmitCallJSRuntimeFunction(call); | 4778 EmitCallJSRuntimeFunction(call); |
4782 | 4779 |
4783 // Restore context register. | 4780 // Restore context register. |
4784 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 4781 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
4785 context()->DropAndPlug(1, r3); | 4782 context()->DropAndPlug(1, r3); |
4786 | |
4787 // TODO(mvstanton): with FLAG_vector_stores this needs a slot id. | |
4788 EmitInitializeThisAfterSuper(super_call_ref); | |
4789 } | 4783 } |
4790 | 4784 |
4791 | 4785 |
4792 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { | 4786 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { |
4793 // Push the builtins object as the receiver. | 4787 // Push the builtins object as the receiver. |
4794 Register receiver = LoadDescriptor::ReceiverRegister(); | 4788 Register receiver = LoadDescriptor::ReceiverRegister(); |
4795 __ LoadP(receiver, GlobalObjectOperand()); | 4789 __ LoadP(receiver, GlobalObjectOperand()); |
4796 __ LoadP(receiver, FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset)); | 4790 __ LoadP(receiver, FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset)); |
4797 __ push(receiver); | 4791 __ push(receiver); |
4798 | 4792 |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4972 break; | 4966 break; |
4973 } | 4967 } |
4974 | 4968 |
4975 default: | 4969 default: |
4976 UNREACHABLE(); | 4970 UNREACHABLE(); |
4977 } | 4971 } |
4978 } | 4972 } |
4979 | 4973 |
4980 | 4974 |
4981 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 4975 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
4982 DCHECK(expr->expression()->IsValidReferenceExpression()); | 4976 DCHECK(expr->expression()->IsValidReferenceExpressionOrThis()); |
4983 | 4977 |
4984 Comment cmnt(masm_, "[ CountOperation"); | 4978 Comment cmnt(masm_, "[ CountOperation"); |
4985 | 4979 |
4986 Property* prop = expr->expression()->AsProperty(); | 4980 Property* prop = expr->expression()->AsProperty(); |
4987 LhsKind assign_type = Property::GetAssignType(prop); | 4981 LhsKind assign_type = Property::GetAssignType(prop); |
4988 | 4982 |
4989 // Evaluate expression and get value. | 4983 // Evaluate expression and get value. |
4990 if (assign_type == VARIABLE) { | 4984 if (assign_type == VARIABLE) { |
4991 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); | 4985 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); |
4992 AccumulatorValueContext context(this); | 4986 AccumulatorValueContext context(this); |
(...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5599 return ON_STACK_REPLACEMENT; | 5593 return ON_STACK_REPLACEMENT; |
5600 } | 5594 } |
5601 | 5595 |
5602 DCHECK(interrupt_address == | 5596 DCHECK(interrupt_address == |
5603 isolate->builtins()->OsrAfterStackCheck()->entry()); | 5597 isolate->builtins()->OsrAfterStackCheck()->entry()); |
5604 return OSR_AFTER_STACK_CHECK; | 5598 return OSR_AFTER_STACK_CHECK; |
5605 } | 5599 } |
5606 } // namespace internal | 5600 } // namespace internal |
5607 } // namespace v8 | 5601 } // namespace v8 |
5608 #endif // V8_TARGET_ARCH_PPC | 5602 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |