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