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

Side by Side Diff: src/x87/full-codegen-x87.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/x64/full-codegen-x64.cc ('k') | test/mjsunit/harmony/super.js » ('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_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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/x64/full-codegen-x64.cc ('k') | test/mjsunit/harmony/super.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698