OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 void FastCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { | 105 void FastCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { |
106 Comment cmnt(masm_, "[ ExpressionStatement"); | 106 Comment cmnt(masm_, "[ ExpressionStatement"); |
107 SetStatementPosition(stmt); | 107 SetStatementPosition(stmt); |
108 Visit(stmt->expression()); | 108 Visit(stmt->expression()); |
109 } | 109 } |
110 | 110 |
111 | 111 |
112 void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { | 112 void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { |
113 Comment cmnt(masm_, "[ ReturnStatement"); | 113 Comment cmnt(masm_, "[ ReturnStatement"); |
114 SetStatementPosition(stmt); | 114 SetStatementPosition(stmt); |
115 Visit(stmt->expression()); | 115 Expression* expr = stmt->expression(); |
116 __ pop(rax); | 116 Visit(expr); |
| 117 |
| 118 // Complete the statement based on the location of the subexpression. |
| 119 Location source = expr->location(); |
| 120 ASSERT(!source.is_nowhere()); |
| 121 if (source.is_temporary()) { |
| 122 __ pop(rax); |
| 123 } else { |
| 124 ASSERT(source.is_constant()); |
| 125 ASSERT(expr->AsLiteral() != NULL); |
| 126 __ Move(rax, expr->AsLiteral()->handle()); |
| 127 } |
117 __ RecordJSReturn(); | 128 __ RecordJSReturn(); |
118 // Do not use the leave instruction here because it is too short to | 129 // Do not use the leave instruction here because it is too short to |
119 // patch with the code required by the debugger. | 130 // patch with the code required by the debugger. |
120 __ movq(rsp, rbp); | 131 __ movq(rsp, rbp); |
121 __ pop(rbp); | 132 __ pop(rbp); |
122 __ ret((function_->scope()->num_parameters() + 1) * kPointerSize); | 133 __ ret((function_->scope()->num_parameters() + 1) * kPointerSize); |
123 #ifdef ENABLE_DEBUGGER_SUPPORT | 134 #ifdef ENABLE_DEBUGGER_SUPPORT |
124 // Add padding that will be overwritten by a debugger breakpoint. We | 135 // Add padding that will be overwritten by a debugger breakpoint. We |
125 // have just generated "movq rsp, rbp; pop rbp; ret k" with length 7 | 136 // have just generated "movq rsp, rbp; pop rbp; ret k" with length 7 |
126 // (3 + 1 + 3). | 137 // (3 + 1 + 3). |
(...skipping 15 matching lines...) Expand all Loading... |
142 { Comment cmnt(masm_, "[ Slot"); | 153 { Comment cmnt(masm_, "[ Slot"); |
143 if (expr->location().is_temporary()) { | 154 if (expr->location().is_temporary()) { |
144 __ push(Operand(rbp, SlotOffset(slot))); | 155 __ push(Operand(rbp, SlotOffset(slot))); |
145 } else { | 156 } else { |
146 ASSERT(expr->location().is_nowhere()); | 157 ASSERT(expr->location().is_nowhere()); |
147 } | 158 } |
148 } | 159 } |
149 } | 160 } |
150 | 161 |
151 | 162 |
152 void FastCodeGenerator::VisitLiteral(Literal* expr) { | |
153 Comment cmnt(masm_, "[ Literal"); | |
154 if (expr->location().is_temporary()) { | |
155 __ Push(expr->handle()); | |
156 } else { | |
157 ASSERT(expr->location().is_nowhere()); | |
158 } | |
159 } | |
160 | |
161 | |
162 void FastCodeGenerator::VisitAssignment(Assignment* expr) { | 163 void FastCodeGenerator::VisitAssignment(Assignment* expr) { |
163 Comment cmnt(masm_, "[ Assignment"); | 164 Comment cmnt(masm_, "[ Assignment"); |
164 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR); | 165 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR); |
| 166 Expression* rhs = expr->value(); |
| 167 Visit(rhs); |
165 | 168 |
166 Visit(expr->value()); | 169 // Left-hand side is always a (parameter or local) slot. |
167 | |
168 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); | 170 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); |
169 ASSERT(var != NULL && var->slot() != NULL); | 171 ASSERT(var != NULL && var->slot() != NULL); |
170 | 172 |
171 if (expr->location().is_temporary()) { | 173 // Complete the assignment based on the location of the right-hand-side |
172 __ movq(rax, Operand(rsp, 0)); | 174 // value and the desired location of the assignment value. |
173 __ movq(Operand(rbp, SlotOffset(var->slot())), rax); | 175 Location destination = expr->location(); |
| 176 Location source = rhs->location(); |
| 177 ASSERT(!destination.is_constant()); |
| 178 ASSERT(!source.is_nowhere()); |
| 179 |
| 180 if (source.is_temporary()) { |
| 181 if (destination.is_temporary()) { |
| 182 // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side temporary |
| 183 // on the stack. |
| 184 __ movq(kScratchRegister, Operand(rsp, 0)); |
| 185 __ movq(Operand(rbp, SlotOffset(var->slot())), kScratchRegister); |
| 186 } else { |
| 187 ASSERT(destination.is_nowhere()); |
| 188 // Case 'var = temp'. Discard right-hand-side temporary. |
| 189 __ pop(Operand(rbp, SlotOffset(var->slot()))); |
| 190 } |
174 } else { | 191 } else { |
175 ASSERT(expr->location().is_nowhere()); | 192 ASSERT(source.is_constant()); |
176 __ pop(Operand(rbp, SlotOffset(var->slot()))); | 193 ASSERT(rhs->AsLiteral() != NULL); |
| 194 // Two cases: 'temp <- (var = constant)', or 'var = constant' with a |
| 195 // discarded result. Always perform the assignment. |
| 196 __ Move(kScratchRegister, rhs->AsLiteral()->handle()); |
| 197 __ movq(Operand(rbp, SlotOffset(var->slot())), kScratchRegister); |
| 198 if (destination.is_temporary()) { |
| 199 // Case 'temp <- (var = constant)'. Save result. |
| 200 __ push(kScratchRegister); |
| 201 } |
177 } | 202 } |
178 } | 203 } |
179 | 204 |
180 | 205 |
181 } } // namespace v8::internal | 206 } } // namespace v8::internal |
OLD | NEW |