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_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
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 1909 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1920 if (result_saved) { | 1920 if (result_saved) { |
1921 __ Drop(1); // literal index | 1921 __ Drop(1); // literal index |
1922 context()->PlugTOS(); | 1922 context()->PlugTOS(); |
1923 } else { | 1923 } else { |
1924 context()->Plug(eax); | 1924 context()->Plug(eax); |
1925 } | 1925 } |
1926 } | 1926 } |
1927 | 1927 |
1928 | 1928 |
1929 void FullCodeGenerator::VisitAssignment(Assignment* expr) { | 1929 void FullCodeGenerator::VisitAssignment(Assignment* expr) { |
1930 DCHECK(expr->target()->IsValidReferenceExpression()); | 1930 DCHECK(expr->target()->IsValidReferenceExpressionOrThis()); |
1931 | 1931 |
1932 Comment cmnt(masm_, "[ Assignment"); | 1932 Comment cmnt(masm_, "[ Assignment"); |
1933 SetExpressionPosition(expr, INSERT_BREAK); | 1933 SetExpressionPosition(expr, INSERT_BREAK); |
1934 | 1934 |
1935 Property* property = expr->target()->AsProperty(); | 1935 Property* property = expr->target()->AsProperty(); |
1936 LhsKind assign_type = Property::GetAssignType(property); | 1936 LhsKind assign_type = Property::GetAssignType(property); |
1937 | 1937 |
1938 // Evaluate LHS expression. | 1938 // Evaluate LHS expression. |
1939 switch (assign_type) { | 1939 switch (assign_type) { |
1940 case VARIABLE: | 1940 case VARIABLE: |
(...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2577 CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code(); | 2577 CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code(); |
2578 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 2578 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
2579 CallIC(code, expr->BinaryOperationFeedbackId()); | 2579 CallIC(code, expr->BinaryOperationFeedbackId()); |
2580 patch_site.EmitPatchInfo(); | 2580 patch_site.EmitPatchInfo(); |
2581 context()->Plug(eax); | 2581 context()->Plug(eax); |
2582 } | 2582 } |
2583 | 2583 |
2584 | 2584 |
2585 void FullCodeGenerator::EmitAssignment(Expression* expr, | 2585 void FullCodeGenerator::EmitAssignment(Expression* expr, |
2586 FeedbackVectorICSlot slot) { | 2586 FeedbackVectorICSlot slot) { |
2587 DCHECK(expr->IsValidReferenceExpression()); | 2587 DCHECK(expr->IsValidReferenceExpressionOrThis()); |
2588 | 2588 |
2589 Property* prop = expr->AsProperty(); | 2589 Property* prop = expr->AsProperty(); |
2590 LhsKind assign_type = Property::GetAssignType(prop); | 2590 LhsKind assign_type = Property::GetAssignType(prop); |
2591 | 2591 |
2592 switch (assign_type) { | 2592 switch (assign_type) { |
2593 case VARIABLE: { | 2593 case VARIABLE: { |
2594 Variable* var = expr->AsVariableProxy()->var(); | 2594 Variable* var = expr->AsVariableProxy()->var(); |
2595 EffectContext context(this); | 2595 EffectContext context(this); |
2596 EmitVariableAssignment(var, Token::ASSIGN, slot); | 2596 EmitVariableAssignment(var, Token::ASSIGN, slot); |
2597 break; | 2597 break; |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2719 Label const_error; | 2719 Label const_error; |
2720 MemOperand location = VarOperand(var, ecx); | 2720 MemOperand location = VarOperand(var, ecx); |
2721 __ mov(edx, location); | 2721 __ mov(edx, location); |
2722 __ cmp(edx, isolate()->factory()->the_hole_value()); | 2722 __ cmp(edx, isolate()->factory()->the_hole_value()); |
2723 __ j(not_equal, &const_error, Label::kNear); | 2723 __ j(not_equal, &const_error, Label::kNear); |
2724 __ push(Immediate(var->name())); | 2724 __ push(Immediate(var->name())); |
2725 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 2725 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
2726 __ bind(&const_error); | 2726 __ bind(&const_error); |
2727 __ CallRuntime(Runtime::kThrowConstAssignError, 0); | 2727 __ CallRuntime(Runtime::kThrowConstAssignError, 0); |
2728 | 2728 |
| 2729 } else if (var->is_this() && op == Token::INIT_CONST) { |
| 2730 // Initializing assignment to const {this} needs a write barrier. |
| 2731 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 2732 Label uninitialized_this; |
| 2733 MemOperand location = VarOperand(var, ecx); |
| 2734 __ mov(edx, location); |
| 2735 __ cmp(edx, isolate()->factory()->the_hole_value()); |
| 2736 __ j(equal, &uninitialized_this); |
| 2737 __ push(Immediate(var->name())); |
| 2738 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
| 2739 __ bind(&uninitialized_this); |
| 2740 EmitStoreToStackLocalOrContextSlot(var, location); |
| 2741 |
2729 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { | 2742 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { |
2730 if (var->IsLookupSlot()) { | 2743 if (var->IsLookupSlot()) { |
2731 // Assignment to var. | 2744 // Assignment to var. |
2732 __ push(eax); // Value. | 2745 __ push(eax); // Value. |
2733 __ push(esi); // Context. | 2746 __ push(esi); // Context. |
2734 __ push(Immediate(var->name())); | 2747 __ push(Immediate(var->name())); |
2735 __ push(Immediate(Smi::FromInt(language_mode()))); | 2748 __ push(Immediate(Smi::FromInt(language_mode()))); |
2736 __ CallRuntime(Runtime::kStoreLookupSlot, 4); | 2749 __ CallRuntime(Runtime::kStoreLookupSlot, 4); |
2737 } else { | 2750 } else { |
2738 // Assignment to var or initializing assignment to let/const in harmony | 2751 // Assignment to var or initializing assignment to let/const in harmony |
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3061 __ push(Immediate(Smi::FromInt(language_mode()))); | 3074 __ push(Immediate(Smi::FromInt(language_mode()))); |
3062 | 3075 |
3063 // Push the start position of the scope the calls resides in. | 3076 // Push the start position of the scope the calls resides in. |
3064 __ push(Immediate(Smi::FromInt(scope()->start_position()))); | 3077 __ push(Immediate(Smi::FromInt(scope()->start_position()))); |
3065 | 3078 |
3066 // Do the runtime call. | 3079 // Do the runtime call. |
3067 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); | 3080 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); |
3068 } | 3081 } |
3069 | 3082 |
3070 | 3083 |
3071 void FullCodeGenerator::EmitInitializeThisAfterSuper( | |
3072 SuperCallReference* super_call_ref, FeedbackVectorICSlot slot) { | |
3073 Variable* this_var = super_call_ref->this_var()->var(); | |
3074 GetVar(ecx, this_var); | |
3075 __ cmp(ecx, isolate()->factory()->the_hole_value()); | |
3076 | |
3077 Label uninitialized_this; | |
3078 __ j(equal, &uninitialized_this); | |
3079 __ push(Immediate(this_var->name())); | |
3080 __ CallRuntime(Runtime::kThrowReferenceError, 1); | |
3081 __ bind(&uninitialized_this); | |
3082 | |
3083 EmitVariableAssignment(this_var, Token::INIT_CONST, slot); | |
3084 } | |
3085 | |
3086 | |
3087 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls. | 3084 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls. |
3088 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { | 3085 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { |
3089 VariableProxy* callee = expr->expression()->AsVariableProxy(); | 3086 VariableProxy* callee = expr->expression()->AsVariableProxy(); |
3090 if (callee->var()->IsLookupSlot()) { | 3087 if (callee->var()->IsLookupSlot()) { |
3091 Label slow, done; | 3088 Label slow, done; |
3092 SetExpressionPosition(callee); | 3089 SetExpressionPosition(callee); |
3093 // Generate code for loading from variables potentially shadowed by | 3090 // Generate code for loading from variables potentially shadowed by |
3094 // eval-introduced variables. | 3091 // eval-introduced variables. |
3095 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); | 3092 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); |
3096 | 3093 |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3292 } | 3289 } |
3293 | 3290 |
3294 __ LoadHeapObject(ebx, FeedbackVector()); | 3291 __ LoadHeapObject(ebx, FeedbackVector()); |
3295 __ mov(edx, Immediate(SmiFromSlot(expr->CallFeedbackSlot()))); | 3292 __ mov(edx, Immediate(SmiFromSlot(expr->CallFeedbackSlot()))); |
3296 | 3293 |
3297 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); | 3294 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); |
3298 __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 3295 __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |
3299 | 3296 |
3300 RecordJSReturnSite(expr); | 3297 RecordJSReturnSite(expr); |
3301 | 3298 |
3302 EmitInitializeThisAfterSuper(super_call_ref, expr->CallFeedbackICSlot()); | |
3303 context()->Plug(eax); | 3299 context()->Plug(eax); |
3304 } | 3300 } |
3305 | 3301 |
3306 | 3302 |
3307 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 3303 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
3308 ZoneList<Expression*>* args = expr->arguments(); | 3304 ZoneList<Expression*>* args = expr->arguments(); |
3309 DCHECK(args->length() == 1); | 3305 DCHECK(args->length() == 1); |
3310 | 3306 |
3311 VisitForAccumulatorValue(args->at(0)); | 3307 VisitForAccumulatorValue(args->at(0)); |
3312 | 3308 |
(...skipping 1355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4668 | 4664 |
4669 // Push NewTarget | 4665 // Push NewTarget |
4670 DCHECK(args->at(2)->IsVariableProxy()); | 4666 DCHECK(args->at(2)->IsVariableProxy()); |
4671 VisitForStackValue(args->at(2)); | 4667 VisitForStackValue(args->at(2)); |
4672 | 4668 |
4673 EmitCallJSRuntimeFunction(call); | 4669 EmitCallJSRuntimeFunction(call); |
4674 | 4670 |
4675 // Restore context register. | 4671 // Restore context register. |
4676 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 4672 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
4677 context()->DropAndPlug(1, eax); | 4673 context()->DropAndPlug(1, eax); |
4678 | |
4679 // TODO(mvstanton): with FLAG_vector_stores this needs a slot id. | |
4680 EmitInitializeThisAfterSuper(super_call_ref); | |
4681 } | 4674 } |
4682 | 4675 |
4683 | 4676 |
4684 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { | 4677 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { |
4685 // Push the builtins object as receiver. | 4678 // Push the builtins object as receiver. |
4686 __ mov(eax, GlobalObjectOperand()); | 4679 __ mov(eax, GlobalObjectOperand()); |
4687 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); | 4680 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); |
4688 | 4681 |
4689 // Load the function from the receiver. | 4682 // Load the function from the receiver. |
4690 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); | 4683 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4869 break; | 4862 break; |
4870 } | 4863 } |
4871 | 4864 |
4872 default: | 4865 default: |
4873 UNREACHABLE(); | 4866 UNREACHABLE(); |
4874 } | 4867 } |
4875 } | 4868 } |
4876 | 4869 |
4877 | 4870 |
4878 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 4871 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
4879 DCHECK(expr->expression()->IsValidReferenceExpression()); | 4872 DCHECK(expr->expression()->IsValidReferenceExpressionOrThis()); |
4880 | 4873 |
4881 Comment cmnt(masm_, "[ CountOperation"); | 4874 Comment cmnt(masm_, "[ CountOperation"); |
4882 | 4875 |
4883 Property* prop = expr->expression()->AsProperty(); | 4876 Property* prop = expr->expression()->AsProperty(); |
4884 LhsKind assign_type = Property::GetAssignType(prop); | 4877 LhsKind assign_type = Property::GetAssignType(prop); |
4885 | 4878 |
4886 // Evaluate expression and get value. | 4879 // Evaluate expression and get value. |
4887 if (assign_type == VARIABLE) { | 4880 if (assign_type == VARIABLE) { |
4888 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); | 4881 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); |
4889 AccumulatorValueContext context(this); | 4882 AccumulatorValueContext context(this); |
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5501 Assembler::target_address_at(call_target_address, | 5494 Assembler::target_address_at(call_target_address, |
5502 unoptimized_code)); | 5495 unoptimized_code)); |
5503 return OSR_AFTER_STACK_CHECK; | 5496 return OSR_AFTER_STACK_CHECK; |
5504 } | 5497 } |
5505 | 5498 |
5506 | 5499 |
5507 } // namespace internal | 5500 } // namespace internal |
5508 } // namespace v8 | 5501 } // namespace v8 |
5509 | 5502 |
5510 #endif // V8_TARGET_ARCH_IA32 | 5503 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |