Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(499)

Side by Side Diff: src/ia32/full-codegen-ia32.cc

Issue 1226123010: Represent implicit 'this' binding by 'super' in AST. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Addressed comments. Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/full-codegen.h ('k') | src/mips/full-codegen-mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/full-codegen.h ('k') | src/mips/full-codegen-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698