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_X87 | 7 #if V8_TARGET_ARCH_X87 |
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 1900 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1911 if (result_saved) { | 1911 if (result_saved) { |
1912 __ Drop(1); // literal index | 1912 __ Drop(1); // literal index |
1913 context()->PlugTOS(); | 1913 context()->PlugTOS(); |
1914 } else { | 1914 } else { |
1915 context()->Plug(eax); | 1915 context()->Plug(eax); |
1916 } | 1916 } |
1917 } | 1917 } |
1918 | 1918 |
1919 | 1919 |
1920 void FullCodeGenerator::VisitAssignment(Assignment* expr) { | 1920 void FullCodeGenerator::VisitAssignment(Assignment* expr) { |
1921 DCHECK(expr->target()->IsValidReferenceExpression()); | 1921 DCHECK(expr->target()->IsValidReferenceExpressionOrThis()); |
1922 | 1922 |
1923 Comment cmnt(masm_, "[ Assignment"); | 1923 Comment cmnt(masm_, "[ Assignment"); |
1924 SetExpressionPosition(expr, INSERT_BREAK); | 1924 SetExpressionPosition(expr, INSERT_BREAK); |
1925 | 1925 |
1926 Property* property = expr->target()->AsProperty(); | 1926 Property* property = expr->target()->AsProperty(); |
1927 LhsKind assign_type = Property::GetAssignType(property); | 1927 LhsKind assign_type = Property::GetAssignType(property); |
1928 | 1928 |
1929 // Evaluate LHS expression. | 1929 // Evaluate LHS expression. |
1930 switch (assign_type) { | 1930 switch (assign_type) { |
1931 case VARIABLE: | 1931 case VARIABLE: |
(...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2568 CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code(); | 2568 CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code(); |
2569 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 2569 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
2570 CallIC(code, expr->BinaryOperationFeedbackId()); | 2570 CallIC(code, expr->BinaryOperationFeedbackId()); |
2571 patch_site.EmitPatchInfo(); | 2571 patch_site.EmitPatchInfo(); |
2572 context()->Plug(eax); | 2572 context()->Plug(eax); |
2573 } | 2573 } |
2574 | 2574 |
2575 | 2575 |
2576 void FullCodeGenerator::EmitAssignment(Expression* expr, | 2576 void FullCodeGenerator::EmitAssignment(Expression* expr, |
2577 FeedbackVectorICSlot slot) { | 2577 FeedbackVectorICSlot slot) { |
2578 DCHECK(expr->IsValidReferenceExpression()); | 2578 DCHECK(expr->IsValidReferenceExpressionOrThis()); |
2579 | 2579 |
2580 Property* prop = expr->AsProperty(); | 2580 Property* prop = expr->AsProperty(); |
2581 LhsKind assign_type = Property::GetAssignType(prop); | 2581 LhsKind assign_type = Property::GetAssignType(prop); |
2582 | 2582 |
2583 switch (assign_type) { | 2583 switch (assign_type) { |
2584 case VARIABLE: { | 2584 case VARIABLE: { |
2585 Variable* var = expr->AsVariableProxy()->var(); | 2585 Variable* var = expr->AsVariableProxy()->var(); |
2586 EffectContext context(this); | 2586 EffectContext context(this); |
2587 EmitVariableAssignment(var, Token::ASSIGN, slot); | 2587 EmitVariableAssignment(var, Token::ASSIGN, slot); |
2588 break; | 2588 break; |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2710 Label const_error; | 2710 Label const_error; |
2711 MemOperand location = VarOperand(var, ecx); | 2711 MemOperand location = VarOperand(var, ecx); |
2712 __ mov(edx, location); | 2712 __ mov(edx, location); |
2713 __ cmp(edx, isolate()->factory()->the_hole_value()); | 2713 __ cmp(edx, isolate()->factory()->the_hole_value()); |
2714 __ j(not_equal, &const_error, Label::kNear); | 2714 __ j(not_equal, &const_error, Label::kNear); |
2715 __ push(Immediate(var->name())); | 2715 __ push(Immediate(var->name())); |
2716 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 2716 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
2717 __ bind(&const_error); | 2717 __ bind(&const_error); |
2718 __ CallRuntime(Runtime::kThrowConstAssignError, 0); | 2718 __ CallRuntime(Runtime::kThrowConstAssignError, 0); |
2719 | 2719 |
| 2720 } else if (var->is_this() && op == Token::INIT_CONST) { |
| 2721 // Initializing assignment to const {this} needs a write barrier. |
| 2722 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 2723 Label uninitialized_this; |
| 2724 MemOperand location = VarOperand(var, ecx); |
| 2725 __ mov(edx, location); |
| 2726 __ cmp(edx, isolate()->factory()->the_hole_value()); |
| 2727 __ j(equal, &uninitialized_this); |
| 2728 __ push(Immediate(var->name())); |
| 2729 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
| 2730 __ bind(&uninitialized_this); |
| 2731 EmitStoreToStackLocalOrContextSlot(var, location); |
| 2732 |
2720 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { | 2733 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { |
2721 if (var->IsLookupSlot()) { | 2734 if (var->IsLookupSlot()) { |
2722 // Assignment to var. | 2735 // Assignment to var. |
2723 __ push(eax); // Value. | 2736 __ push(eax); // Value. |
2724 __ push(esi); // Context. | 2737 __ push(esi); // Context. |
2725 __ push(Immediate(var->name())); | 2738 __ push(Immediate(var->name())); |
2726 __ push(Immediate(Smi::FromInt(language_mode()))); | 2739 __ push(Immediate(Smi::FromInt(language_mode()))); |
2727 __ CallRuntime(Runtime::kStoreLookupSlot, 4); | 2740 __ CallRuntime(Runtime::kStoreLookupSlot, 4); |
2728 } else { | 2741 } else { |
2729 // Assignment to var or initializing assignment to let/const in harmony | 2742 // Assignment to var or initializing assignment to let/const in harmony |
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3052 __ push(Immediate(Smi::FromInt(language_mode()))); | 3065 __ push(Immediate(Smi::FromInt(language_mode()))); |
3053 | 3066 |
3054 // Push the start position of the scope the calls resides in. | 3067 // Push the start position of the scope the calls resides in. |
3055 __ push(Immediate(Smi::FromInt(scope()->start_position()))); | 3068 __ push(Immediate(Smi::FromInt(scope()->start_position()))); |
3056 | 3069 |
3057 // Do the runtime call. | 3070 // Do the runtime call. |
3058 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); | 3071 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); |
3059 } | 3072 } |
3060 | 3073 |
3061 | 3074 |
3062 void FullCodeGenerator::EmitInitializeThisAfterSuper( | |
3063 SuperCallReference* super_call_ref, FeedbackVectorICSlot slot) { | |
3064 Variable* this_var = super_call_ref->this_var()->var(); | |
3065 GetVar(ecx, this_var); | |
3066 __ cmp(ecx, isolate()->factory()->the_hole_value()); | |
3067 | |
3068 Label uninitialized_this; | |
3069 __ j(equal, &uninitialized_this); | |
3070 __ push(Immediate(this_var->name())); | |
3071 __ CallRuntime(Runtime::kThrowReferenceError, 1); | |
3072 __ bind(&uninitialized_this); | |
3073 | |
3074 EmitVariableAssignment(this_var, Token::INIT_CONST, slot); | |
3075 } | |
3076 | |
3077 | |
3078 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls. | 3075 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls. |
3079 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { | 3076 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { |
3080 VariableProxy* callee = expr->expression()->AsVariableProxy(); | 3077 VariableProxy* callee = expr->expression()->AsVariableProxy(); |
3081 if (callee->var()->IsLookupSlot()) { | 3078 if (callee->var()->IsLookupSlot()) { |
3082 Label slow, done; | 3079 Label slow, done; |
3083 SetExpressionPosition(callee); | 3080 SetExpressionPosition(callee); |
3084 // Generate code for loading from variables potentially shadowed by | 3081 // Generate code for loading from variables potentially shadowed by |
3085 // eval-introduced variables. | 3082 // eval-introduced variables. |
3086 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); | 3083 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); |
3087 | 3084 |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3283 } | 3280 } |
3284 | 3281 |
3285 __ LoadHeapObject(ebx, FeedbackVector()); | 3282 __ LoadHeapObject(ebx, FeedbackVector()); |
3286 __ mov(edx, Immediate(SmiFromSlot(expr->CallFeedbackSlot()))); | 3283 __ mov(edx, Immediate(SmiFromSlot(expr->CallFeedbackSlot()))); |
3287 | 3284 |
3288 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); | 3285 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); |
3289 __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 3286 __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |
3290 | 3287 |
3291 RecordJSReturnSite(expr); | 3288 RecordJSReturnSite(expr); |
3292 | 3289 |
3293 EmitInitializeThisAfterSuper(super_call_ref, expr->CallFeedbackICSlot()); | |
3294 context()->Plug(eax); | 3290 context()->Plug(eax); |
3295 } | 3291 } |
3296 | 3292 |
3297 | 3293 |
3298 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 3294 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
3299 ZoneList<Expression*>* args = expr->arguments(); | 3295 ZoneList<Expression*>* args = expr->arguments(); |
3300 DCHECK(args->length() == 1); | 3296 DCHECK(args->length() == 1); |
3301 | 3297 |
3302 VisitForAccumulatorValue(args->at(0)); | 3298 VisitForAccumulatorValue(args->at(0)); |
3303 | 3299 |
(...skipping 1354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4658 | 4654 |
4659 // Push NewTarget | 4655 // Push NewTarget |
4660 DCHECK(args->at(2)->IsVariableProxy()); | 4656 DCHECK(args->at(2)->IsVariableProxy()); |
4661 VisitForStackValue(args->at(2)); | 4657 VisitForStackValue(args->at(2)); |
4662 | 4658 |
4663 EmitCallJSRuntimeFunction(call); | 4659 EmitCallJSRuntimeFunction(call); |
4664 | 4660 |
4665 // Restore context register. | 4661 // Restore context register. |
4666 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 4662 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
4667 context()->DropAndPlug(1, eax); | 4663 context()->DropAndPlug(1, eax); |
4668 | |
4669 // TODO(mvstanton): with FLAG_vector_stores this needs a slot id. | |
4670 EmitInitializeThisAfterSuper(super_call_ref); | |
4671 } | 4664 } |
4672 | 4665 |
4673 | 4666 |
4674 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { | 4667 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { |
4675 // Push the builtins object as receiver. | 4668 // Push the builtins object as receiver. |
4676 __ mov(eax, GlobalObjectOperand()); | 4669 __ mov(eax, GlobalObjectOperand()); |
4677 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); | 4670 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); |
4678 | 4671 |
4679 // Load the function from the receiver. | 4672 // Load the function from the receiver. |
4680 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); | 4673 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4859 break; | 4852 break; |
4860 } | 4853 } |
4861 | 4854 |
4862 default: | 4855 default: |
4863 UNREACHABLE(); | 4856 UNREACHABLE(); |
4864 } | 4857 } |
4865 } | 4858 } |
4866 | 4859 |
4867 | 4860 |
4868 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 4861 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
4869 DCHECK(expr->expression()->IsValidReferenceExpression()); | 4862 DCHECK(expr->expression()->IsValidReferenceExpressionOrThis()); |
4870 | 4863 |
4871 Comment cmnt(masm_, "[ CountOperation"); | 4864 Comment cmnt(masm_, "[ CountOperation"); |
4872 | 4865 |
4873 Property* prop = expr->expression()->AsProperty(); | 4866 Property* prop = expr->expression()->AsProperty(); |
4874 LhsKind assign_type = Property::GetAssignType(prop); | 4867 LhsKind assign_type = Property::GetAssignType(prop); |
4875 | 4868 |
4876 // Evaluate expression and get value. | 4869 // Evaluate expression and get value. |
4877 if (assign_type == VARIABLE) { | 4870 if (assign_type == VARIABLE) { |
4878 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); | 4871 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); |
4879 AccumulatorValueContext context(this); | 4872 AccumulatorValueContext context(this); |
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5491 Assembler::target_address_at(call_target_address, | 5484 Assembler::target_address_at(call_target_address, |
5492 unoptimized_code)); | 5485 unoptimized_code)); |
5493 return OSR_AFTER_STACK_CHECK; | 5486 return OSR_AFTER_STACK_CHECK; |
5494 } | 5487 } |
5495 | 5488 |
5496 | 5489 |
5497 } // namespace internal | 5490 } // namespace internal |
5498 } // namespace v8 | 5491 } // namespace v8 |
5499 | 5492 |
5500 #endif // V8_TARGET_ARCH_X87 | 5493 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |