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_ARM | 7 #if V8_TARGET_ARCH_ARM |
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 1982 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1993 if (result_saved) { | 1993 if (result_saved) { |
1994 __ pop(); // literal index | 1994 __ pop(); // literal index |
1995 context()->PlugTOS(); | 1995 context()->PlugTOS(); |
1996 } else { | 1996 } else { |
1997 context()->Plug(r0); | 1997 context()->Plug(r0); |
1998 } | 1998 } |
1999 } | 1999 } |
2000 | 2000 |
2001 | 2001 |
2002 void FullCodeGenerator::VisitAssignment(Assignment* expr) { | 2002 void FullCodeGenerator::VisitAssignment(Assignment* expr) { |
2003 DCHECK(expr->target()->IsValidReferenceExpression()); | 2003 DCHECK(expr->target()->IsValidReferenceExpressionOrThis()); |
2004 | 2004 |
2005 Comment cmnt(masm_, "[ Assignment"); | 2005 Comment cmnt(masm_, "[ Assignment"); |
2006 SetExpressionPosition(expr, INSERT_BREAK); | 2006 SetExpressionPosition(expr, INSERT_BREAK); |
2007 | 2007 |
2008 Property* property = expr->target()->AsProperty(); | 2008 Property* property = expr->target()->AsProperty(); |
2009 LhsKind assign_type = Property::GetAssignType(property); | 2009 LhsKind assign_type = Property::GetAssignType(property); |
2010 | 2010 |
2011 // Evaluate LHS expression. | 2011 // Evaluate LHS expression. |
2012 switch (assign_type) { | 2012 switch (assign_type) { |
2013 case VARIABLE: | 2013 case VARIABLE: |
(...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2670 CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code(); | 2670 CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code(); |
2671 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 2671 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
2672 CallIC(code, expr->BinaryOperationFeedbackId()); | 2672 CallIC(code, expr->BinaryOperationFeedbackId()); |
2673 patch_site.EmitPatchInfo(); | 2673 patch_site.EmitPatchInfo(); |
2674 context()->Plug(r0); | 2674 context()->Plug(r0); |
2675 } | 2675 } |
2676 | 2676 |
2677 | 2677 |
2678 void FullCodeGenerator::EmitAssignment(Expression* expr, | 2678 void FullCodeGenerator::EmitAssignment(Expression* expr, |
2679 FeedbackVectorICSlot slot) { | 2679 FeedbackVectorICSlot slot) { |
2680 DCHECK(expr->IsValidReferenceExpression()); | 2680 DCHECK(expr->IsValidReferenceExpressionOrThis()); |
2681 | 2681 |
2682 Property* prop = expr->AsProperty(); | 2682 Property* prop = expr->AsProperty(); |
2683 LhsKind assign_type = Property::GetAssignType(prop); | 2683 LhsKind assign_type = Property::GetAssignType(prop); |
2684 | 2684 |
2685 switch (assign_type) { | 2685 switch (assign_type) { |
2686 case VARIABLE: { | 2686 case VARIABLE: { |
2687 Variable* var = expr->AsVariableProxy()->var(); | 2687 Variable* var = expr->AsVariableProxy()->var(); |
2688 EffectContext context(this); | 2688 EffectContext context(this); |
2689 EmitVariableAssignment(var, Token::ASSIGN, slot); | 2689 EmitVariableAssignment(var, Token::ASSIGN, slot); |
2690 break; | 2690 break; |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2818 MemOperand location = VarOperand(var, r1); | 2818 MemOperand location = VarOperand(var, r1); |
2819 __ ldr(r3, location); | 2819 __ ldr(r3, location); |
2820 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); | 2820 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); |
2821 __ b(ne, &const_error); | 2821 __ b(ne, &const_error); |
2822 __ mov(r3, Operand(var->name())); | 2822 __ mov(r3, Operand(var->name())); |
2823 __ push(r3); | 2823 __ push(r3); |
2824 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 2824 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
2825 __ bind(&const_error); | 2825 __ bind(&const_error); |
2826 __ CallRuntime(Runtime::kThrowConstAssignError, 0); | 2826 __ CallRuntime(Runtime::kThrowConstAssignError, 0); |
2827 | 2827 |
| 2828 } else if (var->is_this() && op == Token::INIT_CONST) { |
| 2829 // Initializing assignment to const {this} needs a write barrier. |
| 2830 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 2831 Label uninitialized_this; |
| 2832 MemOperand location = VarOperand(var, r1); |
| 2833 __ ldr(r3, location); |
| 2834 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); |
| 2835 __ b(eq, &uninitialized_this); |
| 2836 __ mov(r0, Operand(var->name())); |
| 2837 __ Push(r0); |
| 2838 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
| 2839 __ bind(&uninitialized_this); |
| 2840 EmitStoreToStackLocalOrContextSlot(var, location); |
| 2841 |
2828 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { | 2842 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { |
2829 if (var->IsLookupSlot()) { | 2843 if (var->IsLookupSlot()) { |
2830 // Assignment to var. | 2844 // Assignment to var. |
2831 __ push(r0); // Value. | 2845 __ push(r0); // Value. |
2832 __ mov(r1, Operand(var->name())); | 2846 __ mov(r1, Operand(var->name())); |
2833 __ mov(r0, Operand(Smi::FromInt(language_mode()))); | 2847 __ mov(r0, Operand(Smi::FromInt(language_mode()))); |
2834 __ Push(cp, r1, r0); // Context, name, language mode. | 2848 __ Push(cp, r1, r0); // Context, name, language mode. |
2835 __ CallRuntime(Runtime::kStoreLookupSlot, 4); | 2849 __ CallRuntime(Runtime::kStoreLookupSlot, 4); |
2836 } else { | 2850 } else { |
2837 // Assignment to var or initializing assignment to let/const in harmony | 2851 // Assignment to var or initializing assignment to let/const in harmony |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3169 | 3183 |
3170 // r1: the start position of the scope the calls resides in. | 3184 // r1: the start position of the scope the calls resides in. |
3171 __ mov(r1, Operand(Smi::FromInt(scope()->start_position()))); | 3185 __ mov(r1, Operand(Smi::FromInt(scope()->start_position()))); |
3172 | 3186 |
3173 // Do the runtime call. | 3187 // Do the runtime call. |
3174 __ Push(r4, r3, r2, r1); | 3188 __ Push(r4, r3, r2, r1); |
3175 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); | 3189 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); |
3176 } | 3190 } |
3177 | 3191 |
3178 | 3192 |
3179 void FullCodeGenerator::EmitInitializeThisAfterSuper( | |
3180 SuperCallReference* super_ref, FeedbackVectorICSlot slot) { | |
3181 Variable* this_var = super_ref->this_var()->var(); | |
3182 GetVar(r1, this_var); | |
3183 __ CompareRoot(r1, Heap::kTheHoleValueRootIndex); | |
3184 Label uninitialized_this; | |
3185 __ b(eq, &uninitialized_this); | |
3186 __ mov(r0, Operand(this_var->name())); | |
3187 __ Push(r0); | |
3188 __ CallRuntime(Runtime::kThrowReferenceError, 1); | |
3189 __ bind(&uninitialized_this); | |
3190 | |
3191 EmitVariableAssignment(this_var, Token::INIT_CONST, slot); | |
3192 } | |
3193 | |
3194 | |
3195 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls. | 3193 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls. |
3196 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { | 3194 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { |
3197 VariableProxy* callee = expr->expression()->AsVariableProxy(); | 3195 VariableProxy* callee = expr->expression()->AsVariableProxy(); |
3198 if (callee->var()->IsLookupSlot()) { | 3196 if (callee->var()->IsLookupSlot()) { |
3199 Label slow, done; | 3197 Label slow, done; |
3200 SetExpressionPosition(callee); | 3198 SetExpressionPosition(callee); |
3201 // Generate code for loading from variables potentially shadowed | 3199 // Generate code for loading from variables potentially shadowed |
3202 // by eval-introduced variables. | 3200 // by eval-introduced variables. |
3203 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); | 3201 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); |
3204 | 3202 |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3406 } | 3404 } |
3407 | 3405 |
3408 __ Move(r2, FeedbackVector()); | 3406 __ Move(r2, FeedbackVector()); |
3409 __ mov(r3, Operand(SmiFromSlot(expr->CallFeedbackSlot()))); | 3407 __ mov(r3, Operand(SmiFromSlot(expr->CallFeedbackSlot()))); |
3410 | 3408 |
3411 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); | 3409 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); |
3412 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 3410 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |
3413 | 3411 |
3414 RecordJSReturnSite(expr); | 3412 RecordJSReturnSite(expr); |
3415 | 3413 |
3416 EmitInitializeThisAfterSuper(super_call_ref, expr->CallFeedbackICSlot()); | |
3417 context()->Plug(r0); | 3414 context()->Plug(r0); |
3418 } | 3415 } |
3419 | 3416 |
3420 | 3417 |
3421 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 3418 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
3422 ZoneList<Expression*>* args = expr->arguments(); | 3419 ZoneList<Expression*>* args = expr->arguments(); |
3423 DCHECK(args->length() == 1); | 3420 DCHECK(args->length() == 1); |
3424 | 3421 |
3425 VisitForAccumulatorValue(args->at(0)); | 3422 VisitForAccumulatorValue(args->at(0)); |
3426 | 3423 |
(...skipping 1310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4737 | 4734 |
4738 // Push NewTarget | 4735 // Push NewTarget |
4739 DCHECK(args->at(2)->IsVariableProxy()); | 4736 DCHECK(args->at(2)->IsVariableProxy()); |
4740 VisitForStackValue(args->at(2)); | 4737 VisitForStackValue(args->at(2)); |
4741 | 4738 |
4742 EmitCallJSRuntimeFunction(call); | 4739 EmitCallJSRuntimeFunction(call); |
4743 | 4740 |
4744 // Restore context register. | 4741 // Restore context register. |
4745 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 4742 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
4746 context()->DropAndPlug(1, r0); | 4743 context()->DropAndPlug(1, r0); |
4747 | |
4748 // TODO(mvstanton): with FLAG_vector_stores this needs a slot id. | |
4749 EmitInitializeThisAfterSuper(super_call_ref); | |
4750 } | 4744 } |
4751 | 4745 |
4752 | 4746 |
4753 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { | 4747 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { |
4754 // Push the builtins object as the receiver. | 4748 // Push the builtins object as the receiver. |
4755 Register receiver = LoadDescriptor::ReceiverRegister(); | 4749 Register receiver = LoadDescriptor::ReceiverRegister(); |
4756 __ ldr(receiver, GlobalObjectOperand()); | 4750 __ ldr(receiver, GlobalObjectOperand()); |
4757 __ ldr(receiver, FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset)); | 4751 __ ldr(receiver, FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset)); |
4758 __ push(receiver); | 4752 __ push(receiver); |
4759 | 4753 |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4937 break; | 4931 break; |
4938 } | 4932 } |
4939 | 4933 |
4940 default: | 4934 default: |
4941 UNREACHABLE(); | 4935 UNREACHABLE(); |
4942 } | 4936 } |
4943 } | 4937 } |
4944 | 4938 |
4945 | 4939 |
4946 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 4940 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
4947 DCHECK(expr->expression()->IsValidReferenceExpression()); | 4941 DCHECK(expr->expression()->IsValidReferenceExpressionOrThis()); |
4948 | 4942 |
4949 Comment cmnt(masm_, "[ CountOperation"); | 4943 Comment cmnt(masm_, "[ CountOperation"); |
4950 | 4944 |
4951 Property* prop = expr->expression()->AsProperty(); | 4945 Property* prop = expr->expression()->AsProperty(); |
4952 LhsKind assign_type = Property::GetAssignType(prop); | 4946 LhsKind assign_type = Property::GetAssignType(prop); |
4953 | 4947 |
4954 // Evaluate expression and get value. | 4948 // Evaluate expression and get value. |
4955 if (assign_type == VARIABLE) { | 4949 if (assign_type == VARIABLE) { |
4956 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); | 4950 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); |
4957 AccumulatorValueContext context(this); | 4951 AccumulatorValueContext context(this); |
(...skipping 674 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5632 DCHECK(interrupt_address == | 5626 DCHECK(interrupt_address == |
5633 isolate->builtins()->OsrAfterStackCheck()->entry()); | 5627 isolate->builtins()->OsrAfterStackCheck()->entry()); |
5634 return OSR_AFTER_STACK_CHECK; | 5628 return OSR_AFTER_STACK_CHECK; |
5635 } | 5629 } |
5636 | 5630 |
5637 | 5631 |
5638 } // namespace internal | 5632 } // namespace internal |
5639 } // namespace v8 | 5633 } // namespace v8 |
5640 | 5634 |
5641 #endif // V8_TARGET_ARCH_ARM | 5635 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |