OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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_MIPS | 7 #if V8_TARGET_ARCH_MIPS |
8 | 8 |
9 // Note on Mips implementation: | 9 // Note on Mips implementation: |
10 // | 10 // |
(...skipping 1975 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1986 if (result_saved) { | 1986 if (result_saved) { |
1987 __ Pop(); // literal index | 1987 __ Pop(); // literal index |
1988 context()->PlugTOS(); | 1988 context()->PlugTOS(); |
1989 } else { | 1989 } else { |
1990 context()->Plug(v0); | 1990 context()->Plug(v0); |
1991 } | 1991 } |
1992 } | 1992 } |
1993 | 1993 |
1994 | 1994 |
1995 void FullCodeGenerator::VisitAssignment(Assignment* expr) { | 1995 void FullCodeGenerator::VisitAssignment(Assignment* expr) { |
1996 DCHECK(expr->target()->IsValidReferenceExpression()); | 1996 DCHECK(expr->target()->IsValidReferenceExpressionOrThis()); |
1997 | 1997 |
1998 Comment cmnt(masm_, "[ Assignment"); | 1998 Comment cmnt(masm_, "[ Assignment"); |
1999 SetExpressionPosition(expr, INSERT_BREAK); | 1999 SetExpressionPosition(expr, INSERT_BREAK); |
2000 | 2000 |
2001 Property* property = expr->target()->AsProperty(); | 2001 Property* property = expr->target()->AsProperty(); |
2002 LhsKind assign_type = Property::GetAssignType(property); | 2002 LhsKind assign_type = Property::GetAssignType(property); |
2003 | 2003 |
2004 // Evaluate LHS expression. | 2004 // Evaluate LHS expression. |
2005 switch (assign_type) { | 2005 switch (assign_type) { |
2006 case VARIABLE: | 2006 case VARIABLE: |
(...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2655 CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code(); | 2655 CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code(); |
2656 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 2656 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
2657 CallIC(code, expr->BinaryOperationFeedbackId()); | 2657 CallIC(code, expr->BinaryOperationFeedbackId()); |
2658 patch_site.EmitPatchInfo(); | 2658 patch_site.EmitPatchInfo(); |
2659 context()->Plug(v0); | 2659 context()->Plug(v0); |
2660 } | 2660 } |
2661 | 2661 |
2662 | 2662 |
2663 void FullCodeGenerator::EmitAssignment(Expression* expr, | 2663 void FullCodeGenerator::EmitAssignment(Expression* expr, |
2664 FeedbackVectorICSlot slot) { | 2664 FeedbackVectorICSlot slot) { |
2665 DCHECK(expr->IsValidReferenceExpression()); | 2665 DCHECK(expr->IsValidReferenceExpressionOrThis()); |
2666 | 2666 |
2667 Property* prop = expr->AsProperty(); | 2667 Property* prop = expr->AsProperty(); |
2668 LhsKind assign_type = Property::GetAssignType(prop); | 2668 LhsKind assign_type = Property::GetAssignType(prop); |
2669 | 2669 |
2670 switch (assign_type) { | 2670 switch (assign_type) { |
2671 case VARIABLE: { | 2671 case VARIABLE: { |
2672 Variable* var = expr->AsVariableProxy()->var(); | 2672 Variable* var = expr->AsVariableProxy()->var(); |
2673 EffectContext context(this); | 2673 EffectContext context(this); |
2674 EmitVariableAssignment(var, Token::ASSIGN, slot); | 2674 EmitVariableAssignment(var, Token::ASSIGN, slot); |
2675 break; | 2675 break; |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2804 MemOperand location = VarOperand(var, a1); | 2804 MemOperand location = VarOperand(var, a1); |
2805 __ lw(a3, location); | 2805 __ lw(a3, location); |
2806 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 2806 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); |
2807 __ Branch(&const_error, ne, a3, Operand(at)); | 2807 __ Branch(&const_error, ne, a3, Operand(at)); |
2808 __ li(a3, Operand(var->name())); | 2808 __ li(a3, Operand(var->name())); |
2809 __ push(a3); | 2809 __ push(a3); |
2810 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 2810 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
2811 __ bind(&const_error); | 2811 __ bind(&const_error); |
2812 __ CallRuntime(Runtime::kThrowConstAssignError, 0); | 2812 __ CallRuntime(Runtime::kThrowConstAssignError, 0); |
2813 | 2813 |
| 2814 } else if (var->is_this() && op == Token::INIT_CONST) { |
| 2815 // Initializing assignment to const {this} needs a write barrier. |
| 2816 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 2817 Label uninitialized_this; |
| 2818 MemOperand location = VarOperand(var, a1); |
| 2819 __ lw(a3, location); |
| 2820 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); |
| 2821 __ Branch(&uninitialized_this, eq, a3, Operand(at)); |
| 2822 __ li(a0, Operand(var->name())); |
| 2823 __ Push(a0); |
| 2824 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
| 2825 __ bind(&uninitialized_this); |
| 2826 EmitStoreToStackLocalOrContextSlot(var, location); |
| 2827 |
2814 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { | 2828 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { |
2815 if (var->IsLookupSlot()) { | 2829 if (var->IsLookupSlot()) { |
2816 // Assignment to var. | 2830 // Assignment to var. |
2817 __ li(a1, Operand(var->name())); | 2831 __ li(a1, Operand(var->name())); |
2818 __ li(a0, Operand(Smi::FromInt(language_mode()))); | 2832 __ li(a0, Operand(Smi::FromInt(language_mode()))); |
2819 __ Push(v0, cp, a1, a0); // Value, context, name, language mode. | 2833 __ Push(v0, cp, a1, a0); // Value, context, name, language mode. |
2820 __ CallRuntime(Runtime::kStoreLookupSlot, 4); | 2834 __ CallRuntime(Runtime::kStoreLookupSlot, 4); |
2821 } else { | 2835 } else { |
2822 // Assignment to var or initializing assignment to let/const in harmony | 2836 // Assignment to var or initializing assignment to let/const in harmony |
2823 // mode. | 2837 // mode. |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3153 | 3167 |
3154 // t0: the start position of the scope the calls resides in. | 3168 // t0: the start position of the scope the calls resides in. |
3155 __ li(t0, Operand(Smi::FromInt(scope()->start_position()))); | 3169 __ li(t0, Operand(Smi::FromInt(scope()->start_position()))); |
3156 | 3170 |
3157 // Do the runtime call. | 3171 // Do the runtime call. |
3158 __ Push(t3, t2, t1, t0); | 3172 __ Push(t3, t2, t1, t0); |
3159 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); | 3173 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); |
3160 } | 3174 } |
3161 | 3175 |
3162 | 3176 |
3163 void FullCodeGenerator::EmitInitializeThisAfterSuper( | |
3164 SuperCallReference* super_ref, FeedbackVectorICSlot slot) { | |
3165 Variable* this_var = super_ref->this_var()->var(); | |
3166 GetVar(a1, this_var); | |
3167 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | |
3168 Label uninitialized_this; | |
3169 __ Branch(&uninitialized_this, eq, a1, Operand(at)); | |
3170 __ li(a0, Operand(this_var->name())); | |
3171 __ Push(a0); | |
3172 __ CallRuntime(Runtime::kThrowReferenceError, 1); | |
3173 __ bind(&uninitialized_this); | |
3174 | |
3175 EmitVariableAssignment(this_var, Token::INIT_CONST, slot); | |
3176 } | |
3177 | |
3178 | |
3179 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls. | 3177 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls. |
3180 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { | 3178 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { |
3181 VariableProxy* callee = expr->expression()->AsVariableProxy(); | 3179 VariableProxy* callee = expr->expression()->AsVariableProxy(); |
3182 if (callee->var()->IsLookupSlot()) { | 3180 if (callee->var()->IsLookupSlot()) { |
3183 Label slow, done; | 3181 Label slow, done; |
3184 | 3182 |
3185 SetExpressionPosition(callee); | 3183 SetExpressionPosition(callee); |
3186 // Generate code for loading from variables potentially shadowed by | 3184 // Generate code for loading from variables potentially shadowed by |
3187 // eval-introduced variables. | 3185 // eval-introduced variables. |
3188 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); | 3186 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3388 } | 3386 } |
3389 | 3387 |
3390 __ li(a2, FeedbackVector()); | 3388 __ li(a2, FeedbackVector()); |
3391 __ li(a3, Operand(SmiFromSlot(expr->CallFeedbackSlot()))); | 3389 __ li(a3, Operand(SmiFromSlot(expr->CallFeedbackSlot()))); |
3392 | 3390 |
3393 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); | 3391 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); |
3394 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 3392 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |
3395 | 3393 |
3396 RecordJSReturnSite(expr); | 3394 RecordJSReturnSite(expr); |
3397 | 3395 |
3398 EmitInitializeThisAfterSuper(super_call_ref, expr->CallFeedbackICSlot()); | |
3399 context()->Plug(v0); | 3396 context()->Plug(v0); |
3400 } | 3397 } |
3401 | 3398 |
3402 | 3399 |
3403 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 3400 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
3404 ZoneList<Expression*>* args = expr->arguments(); | 3401 ZoneList<Expression*>* args = expr->arguments(); |
3405 DCHECK(args->length() == 1); | 3402 DCHECK(args->length() == 1); |
3406 | 3403 |
3407 VisitForAccumulatorValue(args->at(0)); | 3404 VisitForAccumulatorValue(args->at(0)); |
3408 | 3405 |
(...skipping 1345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4754 | 4751 |
4755 // Push NewTarget | 4752 // Push NewTarget |
4756 DCHECK(args->at(2)->IsVariableProxy()); | 4753 DCHECK(args->at(2)->IsVariableProxy()); |
4757 VisitForStackValue(args->at(2)); | 4754 VisitForStackValue(args->at(2)); |
4758 | 4755 |
4759 EmitCallJSRuntimeFunction(call); | 4756 EmitCallJSRuntimeFunction(call); |
4760 | 4757 |
4761 // Restore context register. | 4758 // Restore context register. |
4762 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 4759 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
4763 context()->DropAndPlug(1, v0); | 4760 context()->DropAndPlug(1, v0); |
4764 | |
4765 // TODO(mvstanton): with FLAG_vector_stores this needs a slot id. | |
4766 EmitInitializeThisAfterSuper(super_call_ref); | |
4767 } | 4761 } |
4768 | 4762 |
4769 | 4763 |
4770 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { | 4764 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { |
4771 // Push the builtins object as the receiver. | 4765 // Push the builtins object as the receiver. |
4772 Register receiver = LoadDescriptor::ReceiverRegister(); | 4766 Register receiver = LoadDescriptor::ReceiverRegister(); |
4773 __ lw(receiver, GlobalObjectOperand()); | 4767 __ lw(receiver, GlobalObjectOperand()); |
4774 __ lw(receiver, FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset)); | 4768 __ lw(receiver, FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset)); |
4775 __ push(receiver); | 4769 __ push(receiver); |
4776 | 4770 |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4954 break; | 4948 break; |
4955 } | 4949 } |
4956 | 4950 |
4957 default: | 4951 default: |
4958 UNREACHABLE(); | 4952 UNREACHABLE(); |
4959 } | 4953 } |
4960 } | 4954 } |
4961 | 4955 |
4962 | 4956 |
4963 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 4957 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
4964 DCHECK(expr->expression()->IsValidReferenceExpression()); | 4958 DCHECK(expr->expression()->IsValidReferenceExpressionOrThis()); |
4965 | 4959 |
4966 Comment cmnt(masm_, "[ CountOperation"); | 4960 Comment cmnt(masm_, "[ CountOperation"); |
4967 | 4961 |
4968 Property* prop = expr->expression()->AsProperty(); | 4962 Property* prop = expr->expression()->AsProperty(); |
4969 LhsKind assign_type = Property::GetAssignType(prop); | 4963 LhsKind assign_type = Property::GetAssignType(prop); |
4970 | 4964 |
4971 // Evaluate expression and get value. | 4965 // Evaluate expression and get value. |
4972 if (assign_type == VARIABLE) { | 4966 if (assign_type == VARIABLE) { |
4973 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); | 4967 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); |
4974 AccumulatorValueContext context(this); | 4968 AccumulatorValueContext context(this); |
(...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5589 reinterpret_cast<uint32_t>( | 5583 reinterpret_cast<uint32_t>( |
5590 isolate->builtins()->OsrAfterStackCheck()->entry())); | 5584 isolate->builtins()->OsrAfterStackCheck()->entry())); |
5591 return OSR_AFTER_STACK_CHECK; | 5585 return OSR_AFTER_STACK_CHECK; |
5592 } | 5586 } |
5593 | 5587 |
5594 | 5588 |
5595 } // namespace internal | 5589 } // namespace internal |
5596 } // namespace v8 | 5590 } // namespace v8 |
5597 | 5591 |
5598 #endif // V8_TARGET_ARCH_MIPS | 5592 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |