| 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 |