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 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 } | 159 } |
160 } | 160 } |
161 | 161 |
162 | 162 |
163 void FastCodeGenerator::VisitAssignment(Assignment* expr) { | 163 void FastCodeGenerator::VisitAssignment(Assignment* expr) { |
164 Comment cmnt(masm_, "[ Assignment"); | 164 Comment cmnt(masm_, "[ Assignment"); |
165 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(); | 166 Expression* rhs = expr->value(); |
167 Visit(rhs); | 167 Visit(rhs); |
168 | 168 |
169 // Left-hand side is always a (parameter or local) slot. | 169 // Left-hand side can only be a global or a (parameter or local) slot. |
170 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); | 170 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); |
171 ASSERT(var != NULL && var->slot() != NULL); | 171 ASSERT(var != NULL); |
| 172 ASSERT(var->is_global() || var->slot() != NULL); |
172 | 173 |
173 // Complete the assignment based on the location of the right-hand-side | 174 // Complete the assignment based on the location of the right-hand-side |
174 // value and the desired location of the assignment value. | 175 // value and the desired location of the assignment value. |
175 Location destination = expr->location(); | 176 Location destination = expr->location(); |
176 Location source = rhs->location(); | 177 Location source = rhs->location(); |
177 ASSERT(!destination.is_constant()); | 178 ASSERT(!destination.is_constant()); |
178 ASSERT(!source.is_nowhere()); | 179 ASSERT(!source.is_nowhere()); |
179 | 180 |
180 if (source.is_temporary()) { | 181 if (var->is_global()) { |
| 182 // Assignment to a global variable, use inline caching. Right-hand-side |
| 183 // value is passed in rax, variable name in rcx, and the global object |
| 184 // on the stack. |
| 185 if (source.is_temporary()) { |
| 186 __ pop(rax); |
| 187 } else { |
| 188 ASSERT(source.is_constant()); |
| 189 ASSERT(rhs->AsLiteral() != NULL); |
| 190 __ Move(rax, rhs->AsLiteral()->handle()); |
| 191 } |
| 192 __ Move(rcx, var->name()); |
| 193 __ push(CodeGenerator::GlobalObject()); |
| 194 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
| 195 __ Call(ic, RelocInfo::CODE_TARGET); |
| 196 // Overwrite the global object on the stack with the result if needed. |
181 if (destination.is_temporary()) { | 197 if (destination.is_temporary()) { |
182 // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side temporary | 198 __ movq(Operand(rsp, 0), rax); |
183 // on the stack. | |
184 __ movq(kScratchRegister, Operand(rsp, 0)); | |
185 __ movq(Operand(rbp, SlotOffset(var->slot())), kScratchRegister); | |
186 } else { | 199 } else { |
187 ASSERT(destination.is_nowhere()); | 200 __ pop(rax); |
188 // Case 'var = temp'. Discard right-hand-side temporary. | |
189 __ pop(Operand(rbp, SlotOffset(var->slot()))); | |
190 } | 201 } |
191 } else { | 202 } else { |
192 ASSERT(source.is_constant()); | 203 if (source.is_temporary()) { |
193 ASSERT(rhs->AsLiteral() != NULL); | 204 if (destination.is_temporary()) { |
194 // Two cases: 'temp <- (var = constant)', or 'var = constant' with a | 205 // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side temporary |
195 // discarded result. Always perform the assignment. | 206 // on the stack. |
196 __ Move(kScratchRegister, rhs->AsLiteral()->handle()); | 207 __ movq(kScratchRegister, Operand(rsp, 0)); |
197 __ movq(Operand(rbp, SlotOffset(var->slot())), kScratchRegister); | 208 __ movq(Operand(rbp, SlotOffset(var->slot())), kScratchRegister); |
198 if (destination.is_temporary()) { | 209 } else { |
199 // Case 'temp <- (var = constant)'. Save result. | 210 ASSERT(destination.is_nowhere()); |
200 __ push(kScratchRegister); | 211 // Case 'var = temp'. Discard right-hand-side temporary. |
| 212 __ pop(Operand(rbp, SlotOffset(var->slot()))); |
| 213 } |
| 214 } else { |
| 215 ASSERT(source.is_constant()); |
| 216 ASSERT(rhs->AsLiteral() != NULL); |
| 217 // Two cases: 'temp <- (var = constant)', or 'var = constant' with a |
| 218 // discarded result. Always perform the assignment. |
| 219 __ Move(kScratchRegister, rhs->AsLiteral()->handle()); |
| 220 __ movq(Operand(rbp, SlotOffset(var->slot())), kScratchRegister); |
| 221 if (destination.is_temporary()) { |
| 222 // Case 'temp <- (var = constant)'. Save result. |
| 223 __ push(kScratchRegister); |
| 224 } |
201 } | 225 } |
202 } | 226 } |
203 } | 227 } |
204 | 228 |
205 | 229 |
206 } } // namespace v8::internal | 230 } } // namespace v8::internal |
OLD | NEW |