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