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

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

Issue 3432022: Clean up some messiness in Scopes. (Closed)
Patch Set: Created 10 years, 3 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/codegen-x64.cc ('k') | src/x64/virtual-frame-x64.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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 __ CallRuntime(Runtime::kNewContext, 1); 93 __ CallRuntime(Runtime::kNewContext, 1);
94 } 94 }
95 function_in_register = false; 95 function_in_register = false;
96 // Context is returned in both rax and rsi. It replaces the context 96 // Context is returned in both rax and rsi. It replaces the context
97 // passed to us. It's saved in the stack and kept live in rsi. 97 // passed to us. It's saved in the stack and kept live in rsi.
98 __ movq(Operand(rbp, StandardFrameConstants::kContextOffset), rsi); 98 __ movq(Operand(rbp, StandardFrameConstants::kContextOffset), rsi);
99 99
100 // Copy any necessary parameters into the context. 100 // Copy any necessary parameters into the context.
101 int num_parameters = scope()->num_parameters(); 101 int num_parameters = scope()->num_parameters();
102 for (int i = 0; i < num_parameters; i++) { 102 for (int i = 0; i < num_parameters; i++) {
103 Slot* slot = scope()->parameter(i)->slot(); 103 Slot* slot = scope()->parameter(i)->AsSlot();
104 if (slot != NULL && slot->type() == Slot::CONTEXT) { 104 if (slot != NULL && slot->type() == Slot::CONTEXT) {
105 int parameter_offset = StandardFrameConstants::kCallerSPOffset + 105 int parameter_offset = StandardFrameConstants::kCallerSPOffset +
106 (num_parameters - 1 - i) * kPointerSize; 106 (num_parameters - 1 - i) * kPointerSize;
107 // Load parameter from stack. 107 // Load parameter from stack.
108 __ movq(rax, Operand(rbp, parameter_offset)); 108 __ movq(rax, Operand(rbp, parameter_offset));
109 // Store it in the context. 109 // Store it in the context.
110 int context_offset = Context::SlotOffset(slot->index()); 110 int context_offset = Context::SlotOffset(slot->index());
111 __ movq(Operand(rsi, context_offset), rax); 111 __ movq(Operand(rsi, context_offset), rax);
112 // Update the write barrier. This clobbers all involved 112 // Update the write barrier. This clobbers all involved
113 // registers, so we have use a third register to avoid 113 // registers, so we have use a third register to avoid
114 // clobbering rsi. 114 // clobbering rsi.
115 __ movq(rcx, rsi); 115 __ movq(rcx, rsi);
116 __ RecordWrite(rcx, context_offset, rax, rbx); 116 __ RecordWrite(rcx, context_offset, rax, rbx);
117 } 117 }
118 } 118 }
119 } 119 }
120 120
121 // Possibly allocate an arguments object. 121 // Possibly allocate an arguments object.
122 Variable* arguments = scope()->arguments()->AsVariable(); 122 Variable* arguments = scope()->arguments();
123 if (arguments != NULL) { 123 if (arguments != NULL) {
124 // Arguments object must be allocated after the context object, in 124 // Arguments object must be allocated after the context object, in
125 // case the "arguments" or ".arguments" variables are in the context. 125 // case the "arguments" or ".arguments" variables are in the context.
126 Comment cmnt(masm_, "[ Allocate arguments object"); 126 Comment cmnt(masm_, "[ Allocate arguments object");
127 if (function_in_register) { 127 if (function_in_register) {
128 __ push(rdi); 128 __ push(rdi);
129 } else { 129 } else {
130 __ push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 130 __ push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
131 } 131 }
132 // The receiver is just before the parameters on the caller's stack. 132 // The receiver is just before the parameters on the caller's stack.
133 int offset = scope()->num_parameters() * kPointerSize; 133 int offset = scope()->num_parameters() * kPointerSize;
134 __ lea(rdx, 134 __ lea(rdx,
135 Operand(rbp, StandardFrameConstants::kCallerSPOffset + offset)); 135 Operand(rbp, StandardFrameConstants::kCallerSPOffset + offset));
136 __ push(rdx); 136 __ push(rdx);
137 __ Push(Smi::FromInt(scope()->num_parameters())); 137 __ Push(Smi::FromInt(scope()->num_parameters()));
138 // Arguments to ArgumentsAccessStub: 138 // Arguments to ArgumentsAccessStub:
139 // function, receiver address, parameter count. 139 // function, receiver address, parameter count.
140 // The stub will rewrite receiver and parameter count if the previous 140 // The stub will rewrite receiver and parameter count if the previous
141 // stack frame was an arguments adapter frame. 141 // stack frame was an arguments adapter frame.
142 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT); 142 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT);
143 __ CallStub(&stub); 143 __ CallStub(&stub);
144 // Store new arguments object in both "arguments" and ".arguments" slots. 144 // Store new arguments object in both "arguments" and ".arguments" slots.
145 __ movq(rcx, rax); 145 __ movq(rcx, rax);
146 Move(arguments->slot(), rax, rbx, rdx); 146 Move(arguments->AsSlot(), rax, rbx, rdx);
147 Slot* dot_arguments_slot = 147 Slot* dot_arguments_slot = scope()->arguments_shadow()->AsSlot();
148 scope()->arguments_shadow()->AsVariable()->slot();
149 Move(dot_arguments_slot, rcx, rbx, rdx); 148 Move(dot_arguments_slot, rcx, rbx, rdx);
150 } 149 }
151 150
152 { Comment cmnt(masm_, "[ Declarations"); 151 { Comment cmnt(masm_, "[ Declarations");
153 // For named function expressions, declare the function name as a 152 // For named function expressions, declare the function name as a
154 // constant. 153 // constant.
155 if (scope()->is_function_scope() && scope()->function() != NULL) { 154 if (scope()->is_function_scope() && scope()->function() != NULL) {
156 EmitDeclaration(scope()->function(), Variable::CONST, NULL); 155 EmitDeclaration(scope()->function(), Variable::CONST, NULL);
157 } 156 }
158 // Visit all the explicit declarations unless there is an illegal 157 // Visit all the explicit declarations unless there is an illegal
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 __ RecordWrite(scratch1, offset, src, scratch2); 511 __ RecordWrite(scratch1, offset, src, scratch2);
513 } 512 }
514 } 513 }
515 514
516 515
517 void FullCodeGenerator::EmitDeclaration(Variable* variable, 516 void FullCodeGenerator::EmitDeclaration(Variable* variable,
518 Variable::Mode mode, 517 Variable::Mode mode,
519 FunctionLiteral* function) { 518 FunctionLiteral* function) {
520 Comment cmnt(masm_, "[ Declaration"); 519 Comment cmnt(masm_, "[ Declaration");
521 ASSERT(variable != NULL); // Must have been resolved. 520 ASSERT(variable != NULL); // Must have been resolved.
522 Slot* slot = variable->slot(); 521 Slot* slot = variable->AsSlot();
523 Property* prop = variable->AsProperty(); 522 Property* prop = variable->AsProperty();
524 523
525 if (slot != NULL) { 524 if (slot != NULL) {
526 switch (slot->type()) { 525 switch (slot->type()) {
527 case Slot::PARAMETER: 526 case Slot::PARAMETER:
528 case Slot::LOCAL: 527 case Slot::LOCAL:
529 if (mode == Variable::CONST) { 528 if (mode == Variable::CONST) {
530 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex); 529 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
531 __ movq(Operand(rbp, SlotOffset(slot)), kScratchRegister); 530 __ movq(Operand(rbp, SlotOffset(slot)), kScratchRegister);
532 } else if (function != NULL) { 531 } else if (function != NULL) {
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after
953 Label* done) { 952 Label* done) {
954 // Generate fast-case code for variables that might be shadowed by 953 // Generate fast-case code for variables that might be shadowed by
955 // eval-introduced variables. Eval is used a lot without 954 // eval-introduced variables. Eval is used a lot without
956 // introducing variables. In those cases, we do not want to 955 // introducing variables. In those cases, we do not want to
957 // perform a runtime call for all variables in the scope 956 // perform a runtime call for all variables in the scope
958 // containing the eval. 957 // containing the eval.
959 if (slot->var()->mode() == Variable::DYNAMIC_GLOBAL) { 958 if (slot->var()->mode() == Variable::DYNAMIC_GLOBAL) {
960 EmitLoadGlobalSlotCheckExtensions(slot, typeof_state, slow); 959 EmitLoadGlobalSlotCheckExtensions(slot, typeof_state, slow);
961 __ jmp(done); 960 __ jmp(done);
962 } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) { 961 } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) {
963 Slot* potential_slot = slot->var()->local_if_not_shadowed()->slot(); 962 Slot* potential_slot = slot->var()->local_if_not_shadowed()->AsSlot();
964 Expression* rewrite = slot->var()->local_if_not_shadowed()->rewrite(); 963 Expression* rewrite = slot->var()->local_if_not_shadowed()->rewrite();
965 if (potential_slot != NULL) { 964 if (potential_slot != NULL) {
966 // Generate fast case for locals that rewrite to slots. 965 // Generate fast case for locals that rewrite to slots.
967 __ movq(rax, 966 __ movq(rax,
968 ContextSlotOperandCheckExtensions(potential_slot, slow)); 967 ContextSlotOperandCheckExtensions(potential_slot, slow));
969 if (potential_slot->var()->mode() == Variable::CONST) { 968 if (potential_slot->var()->mode() == Variable::CONST) {
970 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex); 969 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex);
971 __ j(not_equal, done); 970 __ j(not_equal, done);
972 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 971 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
973 } 972 }
974 __ jmp(done); 973 __ jmp(done);
975 } else if (rewrite != NULL) { 974 } else if (rewrite != NULL) {
976 // Generate fast case for calls of an argument function. 975 // Generate fast case for calls of an argument function.
977 Property* property = rewrite->AsProperty(); 976 Property* property = rewrite->AsProperty();
978 if (property != NULL) { 977 if (property != NULL) {
979 VariableProxy* obj_proxy = property->obj()->AsVariableProxy(); 978 VariableProxy* obj_proxy = property->obj()->AsVariableProxy();
980 Literal* key_literal = property->key()->AsLiteral(); 979 Literal* key_literal = property->key()->AsLiteral();
981 if (obj_proxy != NULL && 980 if (obj_proxy != NULL &&
982 key_literal != NULL && 981 key_literal != NULL &&
983 obj_proxy->IsArguments() && 982 obj_proxy->IsArguments() &&
984 key_literal->handle()->IsSmi()) { 983 key_literal->handle()->IsSmi()) {
985 // Load arguments object if there are no eval-introduced 984 // Load arguments object if there are no eval-introduced
986 // variables. Then load the argument from the arguments 985 // variables. Then load the argument from the arguments
987 // object using keyed load. 986 // object using keyed load.
988 __ movq(rdx, 987 __ movq(rdx,
989 ContextSlotOperandCheckExtensions(obj_proxy->var()->slot(), 988 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(),
990 slow)); 989 slow));
991 __ Move(rax, key_literal->handle()); 990 __ Move(rax, key_literal->handle());
992 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 991 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
993 EmitCallIC(ic, RelocInfo::CODE_TARGET); 992 EmitCallIC(ic, RelocInfo::CODE_TARGET);
994 __ jmp(done); 993 __ jmp(done);
995 } 994 }
996 } 995 }
997 } 996 }
998 } 997 }
999 } 998 }
1000 999
1001 1000
1002 void FullCodeGenerator::EmitVariableLoad(Variable* var) { 1001 void FullCodeGenerator::EmitVariableLoad(Variable* var) {
1003 // Four cases: non-this global variables, lookup slots, all other 1002 // Four cases: non-this global variables, lookup slots, all other
1004 // types of slots, and parameters that rewrite to explicit property 1003 // types of slots, and parameters that rewrite to explicit property
1005 // accesses on the arguments object. 1004 // accesses on the arguments object.
1006 Slot* slot = var->slot(); 1005 Slot* slot = var->AsSlot();
1007 Property* property = var->AsProperty(); 1006 Property* property = var->AsProperty();
1008 1007
1009 if (var->is_global() && !var->is_this()) { 1008 if (var->is_global() && !var->is_this()) {
1010 Comment cmnt(masm_, "Global variable"); 1009 Comment cmnt(masm_, "Global variable");
1011 // Use inline caching. Variable name is passed in rcx and the global 1010 // Use inline caching. Variable name is passed in rcx and the global
1012 // object on the stack. 1011 // object on the stack.
1013 __ Move(rcx, var->name()); 1012 __ Move(rcx, var->name());
1014 __ movq(rax, CodeGenerator::GlobalObject()); 1013 __ movq(rax, CodeGenerator::GlobalObject());
1015 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 1014 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
1016 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); 1015 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1052 } 1051 }
1053 1052
1054 } else { 1053 } else {
1055 Comment cmnt(masm_, "Rewritten parameter"); 1054 Comment cmnt(masm_, "Rewritten parameter");
1056 ASSERT_NOT_NULL(property); 1055 ASSERT_NOT_NULL(property);
1057 // Rewritten parameter accesses are of the form "slot[literal]". 1056 // Rewritten parameter accesses are of the form "slot[literal]".
1058 1057
1059 // Assert that the object is in a slot. 1058 // Assert that the object is in a slot.
1060 Variable* object_var = property->obj()->AsVariableProxy()->AsVariable(); 1059 Variable* object_var = property->obj()->AsVariableProxy()->AsVariable();
1061 ASSERT_NOT_NULL(object_var); 1060 ASSERT_NOT_NULL(object_var);
1062 Slot* object_slot = object_var->slot(); 1061 Slot* object_slot = object_var->AsSlot();
1063 ASSERT_NOT_NULL(object_slot); 1062 ASSERT_NOT_NULL(object_slot);
1064 1063
1065 // Load the object. 1064 // Load the object.
1066 MemOperand object_loc = EmitSlotSearch(object_slot, rax); 1065 MemOperand object_loc = EmitSlotSearch(object_slot, rax);
1067 __ movq(rdx, object_loc); 1066 __ movq(rdx, object_loc);
1068 1067
1069 // Assert that the key is a smi. 1068 // Assert that the key is a smi.
1070 Literal* key_literal = property->key()->AsLiteral(); 1069 Literal* key_literal = property->key()->AsLiteral();
1071 ASSERT_NOT_NULL(key_literal); 1070 ASSERT_NOT_NULL(key_literal);
1072 ASSERT(key_literal->handle()->IsSmi()); 1071 ASSERT(key_literal->handle()->IsSmi());
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after
1524 } 1523 }
1525 } 1524 }
1526 } 1525 }
1527 1526
1528 1527
1529 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 1528 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
1530 Token::Value op) { 1529 Token::Value op) {
1531 // Left-hand sides that rewrite to explicit property accesses do not reach 1530 // Left-hand sides that rewrite to explicit property accesses do not reach
1532 // here. 1531 // here.
1533 ASSERT(var != NULL); 1532 ASSERT(var != NULL);
1534 ASSERT(var->is_global() || var->slot() != NULL); 1533 ASSERT(var->is_global() || var->AsSlot() != NULL);
1535 1534
1536 if (var->is_global()) { 1535 if (var->is_global()) {
1537 ASSERT(!var->is_this()); 1536 ASSERT(!var->is_this());
1538 // Assignment to a global variable. Use inline caching for the 1537 // Assignment to a global variable. Use inline caching for the
1539 // assignment. Right-hand-side value is passed in rax, variable name in 1538 // assignment. Right-hand-side value is passed in rax, variable name in
1540 // rcx, and the global object on the stack. 1539 // rcx, and the global object on the stack.
1541 __ Move(rcx, var->name()); 1540 __ Move(rcx, var->name());
1542 __ movq(rdx, CodeGenerator::GlobalObject()); 1541 __ movq(rdx, CodeGenerator::GlobalObject());
1543 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 1542 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
1544 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1543 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1545 1544
1546 } else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) { 1545 } else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) {
1547 // Perform the assignment for non-const variables and for initialization 1546 // Perform the assignment for non-const variables and for initialization
1548 // of const variables. Const assignments are simply skipped. 1547 // of const variables. Const assignments are simply skipped.
1549 Label done; 1548 Label done;
1550 Slot* slot = var->slot(); 1549 Slot* slot = var->AsSlot();
1551 switch (slot->type()) { 1550 switch (slot->type()) {
1552 case Slot::PARAMETER: 1551 case Slot::PARAMETER:
1553 case Slot::LOCAL: 1552 case Slot::LOCAL:
1554 if (op == Token::INIT_CONST) { 1553 if (op == Token::INIT_CONST) {
1555 // Detect const reinitialization by checking for the hole value. 1554 // Detect const reinitialization by checking for the hole value.
1556 __ movq(rdx, Operand(rbp, SlotOffset(slot))); 1555 __ movq(rdx, Operand(rbp, SlotOffset(slot)));
1557 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex); 1556 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex);
1558 __ j(not_equal, &done); 1557 __ j(not_equal, &done);
1559 } 1558 }
1560 // Perform the assignment. 1559 // Perform the assignment.
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
1806 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); 1805 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE);
1807 __ CallStub(&stub); 1806 __ CallStub(&stub);
1808 // Restore context register. 1807 // Restore context register.
1809 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 1808 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
1810 context()->DropAndPlug(1, rax); 1809 context()->DropAndPlug(1, rax);
1811 } else if (var != NULL && !var->is_this() && var->is_global()) { 1810 } else if (var != NULL && !var->is_this() && var->is_global()) {
1812 // Call to a global variable. 1811 // Call to a global variable.
1813 // Push global object as receiver for the call IC lookup. 1812 // Push global object as receiver for the call IC lookup.
1814 __ push(CodeGenerator::GlobalObject()); 1813 __ push(CodeGenerator::GlobalObject());
1815 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT); 1814 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT);
1816 } else if (var != NULL && var->slot() != NULL && 1815 } else if (var != NULL && var->AsSlot() != NULL &&
1817 var->slot()->type() == Slot::LOOKUP) { 1816 var->AsSlot()->type() == Slot::LOOKUP) {
1818 // Call to a lookup slot (dynamically introduced variable). 1817 // Call to a lookup slot (dynamically introduced variable).
1819 Label slow, done; 1818 Label slow, done;
1820 1819
1821 // Generate code for loading from variables potentially shadowed 1820 // Generate code for loading from variables potentially shadowed
1822 // by eval-introduced variables. 1821 // by eval-introduced variables.
1823 EmitDynamicLoadFromSlotFastCase(var->slot(), 1822 EmitDynamicLoadFromSlotFastCase(var->AsSlot(),
1824 NOT_INSIDE_TYPEOF, 1823 NOT_INSIDE_TYPEOF,
1825 &slow, 1824 &slow,
1826 &done); 1825 &done);
1827 1826
1828 __ bind(&slow); 1827 __ bind(&slow);
1829 // Call the runtime to find the function to call (returned in rax) 1828 // Call the runtime to find the function to call (returned in rax)
1830 // and the object holding it (returned in rdx). 1829 // and the object holding it (returned in rdx).
1831 __ push(context_register()); 1830 __ push(context_register());
1832 __ Push(var->name()); 1831 __ Push(var->name());
1833 __ CallRuntime(Runtime::kLoadContextSlot, 2); 1832 __ CallRuntime(Runtime::kLoadContextSlot, 2);
(...skipping 965 matching lines...) Expand 10 before | Expand all | Expand 10 after
2799 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 2798 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
2800 Property* prop = expr->expression()->AsProperty(); 2799 Property* prop = expr->expression()->AsProperty();
2801 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); 2800 Variable* var = expr->expression()->AsVariableProxy()->AsVariable();
2802 if (prop == NULL && var == NULL) { 2801 if (prop == NULL && var == NULL) {
2803 // Result of deleting non-property, non-variable reference is true. 2802 // Result of deleting non-property, non-variable reference is true.
2804 // The subexpression may have side effects. 2803 // The subexpression may have side effects.
2805 VisitForEffect(expr->expression()); 2804 VisitForEffect(expr->expression());
2806 context()->Plug(true); 2805 context()->Plug(true);
2807 } else if (var != NULL && 2806 } else if (var != NULL &&
2808 !var->is_global() && 2807 !var->is_global() &&
2809 var->slot() != NULL && 2808 var->AsSlot() != NULL &&
2810 var->slot()->type() != Slot::LOOKUP) { 2809 var->AsSlot()->type() != Slot::LOOKUP) {
2811 // Result of deleting non-global, non-dynamic variables is false. 2810 // Result of deleting non-global, non-dynamic variables is false.
2812 // The subexpression does not have side effects. 2811 // The subexpression does not have side effects.
2813 context()->Plug(false); 2812 context()->Plug(false);
2814 } else { 2813 } else {
2815 // Property or variable reference. Call the delete builtin with 2814 // Property or variable reference. Call the delete builtin with
2816 // object and property name as arguments. 2815 // object and property name as arguments.
2817 if (prop != NULL) { 2816 if (prop != NULL) {
2818 VisitForStackValue(prop->obj()); 2817 VisitForStackValue(prop->obj());
2819 VisitForStackValue(prop->key()); 2818 VisitForStackValue(prop->key());
2820 } else if (var->is_global()) { 2819 } else if (var->is_global()) {
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
3089 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { 3088 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) {
3090 Comment cmnt(masm_, "Global variable"); 3089 Comment cmnt(masm_, "Global variable");
3091 __ Move(rcx, proxy->name()); 3090 __ Move(rcx, proxy->name());
3092 __ movq(rax, CodeGenerator::GlobalObject()); 3091 __ movq(rax, CodeGenerator::GlobalObject());
3093 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 3092 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
3094 // Use a regular load, not a contextual load, to avoid a reference 3093 // Use a regular load, not a contextual load, to avoid a reference
3095 // error. 3094 // error.
3096 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3095 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3097 context()->Plug(rax); 3096 context()->Plug(rax);
3098 } else if (proxy != NULL && 3097 } else if (proxy != NULL &&
3099 proxy->var()->slot() != NULL && 3098 proxy->var()->AsSlot() != NULL &&
3100 proxy->var()->slot()->type() == Slot::LOOKUP) { 3099 proxy->var()->AsSlot()->type() == Slot::LOOKUP) {
3101 Label done, slow; 3100 Label done, slow;
3102 3101
3103 // Generate code for loading from variables potentially shadowed 3102 // Generate code for loading from variables potentially shadowed
3104 // by eval-introduced variables. 3103 // by eval-introduced variables.
3105 Slot* slot = proxy->var()->slot(); 3104 Slot* slot = proxy->var()->AsSlot();
3106 EmitDynamicLoadFromSlotFastCase(slot, INSIDE_TYPEOF, &slow, &done); 3105 EmitDynamicLoadFromSlotFastCase(slot, INSIDE_TYPEOF, &slow, &done);
3107 3106
3108 __ bind(&slow); 3107 __ bind(&slow);
3109 __ push(rsi); 3108 __ push(rsi);
3110 __ Push(proxy->name()); 3109 __ Push(proxy->name());
3111 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); 3110 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2);
3112 __ bind(&done); 3111 __ bind(&done);
3113 3112
3114 context()->Plug(rax); 3113 context()->Plug(rax);
3115 } else { 3114 } else {
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
3420 __ ret(0); 3419 __ ret(0);
3421 } 3420 }
3422 3421
3423 3422
3424 #undef __ 3423 #undef __
3425 3424
3426 3425
3427 } } // namespace v8::internal 3426 } } // namespace v8::internal
3428 3427
3429 #endif // V8_TARGET_ARCH_X64 3428 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/codegen-x64.cc ('k') | src/x64/virtual-frame-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698