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 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 if (expr->location().is_temporary()) { | 208 if (expr->location().is_temporary()) { |
209 __ ldr(ip, MemOperand(fp, SlotOffset(slot))); | 209 __ ldr(ip, MemOperand(fp, SlotOffset(slot))); |
210 __ push(ip); | 210 __ push(ip); |
211 } else { | 211 } else { |
212 ASSERT(expr->location().is_nowhere()); | 212 ASSERT(expr->location().is_nowhere()); |
213 } | 213 } |
214 } | 214 } |
215 } | 215 } |
216 | 216 |
217 | 217 |
| 218 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { |
| 219 Comment cmnt(masm_, "[ ObjectLiteral"); |
| 220 Label boilerplate_exists; |
| 221 __ ldr(r2, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 222 // r2 = literal array (0). |
| 223 __ ldr(r2, FieldMemOperand(r2, JSFunction::kLiteralsOffset)); |
| 224 int literal_offset = |
| 225 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize; |
| 226 __ ldr(r0, FieldMemOperand(r2, literal_offset)); |
| 227 // Check whether we need to materialize the object literal boilerplate. |
| 228 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
| 229 __ cmp(r0, Operand(ip)); |
| 230 __ b(ne, &boilerplate_exists); |
| 231 // Create boilerplate if it does not exist. |
| 232 // r1 = literal index (1). |
| 233 __ mov(r1, Operand(Smi::FromInt(expr->literal_index()))); |
| 234 // r0 = constant properties (2). |
| 235 __ mov(r0, Operand(expr->constant_properties())); |
| 236 __ stm(db_w, sp, r2.bit() | r1.bit() | r0.bit()); |
| 237 __ CallRuntime(Runtime::kCreateObjectLiteralBoilerplate, 3); |
| 238 __ bind(&boilerplate_exists); |
| 239 // r0 contains boilerplate. |
| 240 // Clone boilerplate. |
| 241 __ push(r0); |
| 242 if (expr->depth() > 1) { |
| 243 __ CallRuntime(Runtime::kCloneLiteralBoilerplate, 1); |
| 244 } else { |
| 245 __ CallRuntime(Runtime::kCloneShallowLiteralBoilerplate, 1); |
| 246 } |
| 247 |
| 248 // If result_saved == true: the result is saved on top of the stack. |
| 249 // If result_saved == false: the result is in eax. |
| 250 bool result_saved = false; |
| 251 |
| 252 for (int i = 0; i < expr->properties()->length(); i++) { |
| 253 ObjectLiteral::Property* property = expr->properties()->at(i); |
| 254 Literal* key = property->key(); |
| 255 Expression* value = property->value(); |
| 256 if (property->kind() == ObjectLiteral::Property::CONSTANT) continue; |
| 257 if (property->kind() == ObjectLiteral::Property::MATERIALIZED_LITERAL && |
| 258 CompileTimeValue::IsCompileTimeValue(value)) { |
| 259 continue; |
| 260 } |
| 261 if (!result_saved) { |
| 262 __ push(r0); // Save result on stack |
| 263 result_saved = true; |
| 264 } |
| 265 switch (property->kind()) { |
| 266 case ObjectLiteral::Property::MATERIALIZED_LITERAL: // fall through |
| 267 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); |
| 268 case ObjectLiteral::Property::COMPUTED: // fall through |
| 269 case ObjectLiteral::Property::PROTOTYPE: |
| 270 __ push(r0); |
| 271 Visit(key); |
| 272 if (key->location().is_constant()) { |
| 273 __ mov(r1, Operand(key->handle())); |
| 274 __ push(r1); |
| 275 } |
| 276 Visit(value); |
| 277 ASSERT(value->location().is_temporary()); |
| 278 __ CallRuntime(Runtime::kSetProperty, 3); |
| 279 __ ldr(r0, MemOperand(sp)); // Restore result into r0 |
| 280 break; |
| 281 case ObjectLiteral::Property::SETTER: // fall through |
| 282 case ObjectLiteral::Property::GETTER: |
| 283 __ push(r0); |
| 284 Visit(key); |
| 285 if (key->location().is_constant()) { |
| 286 __ mov(r1, Operand(key->handle())); |
| 287 __ push(r1); |
| 288 } |
| 289 __ mov(r1, Operand(property->kind() == ObjectLiteral::Property::SETTER ? |
| 290 Smi::FromInt(1) : |
| 291 Smi::FromInt(0))); |
| 292 __ push(r1); |
| 293 Visit(value); |
| 294 ASSERT(value->location().is_temporary()); |
| 295 __ CallRuntime(Runtime::kDefineAccessor, 4); |
| 296 __ ldr(r0, MemOperand(sp)); // Restore result into r0 |
| 297 break; |
| 298 default: UNREACHABLE(); |
| 299 } |
| 300 } |
| 301 if (expr->location().is_nowhere() && result_saved) { |
| 302 __ pop(); |
| 303 } else if (expr->location().is_temporary() && !result_saved) { |
| 304 ASSERT(expr->location().is_temporary()); |
| 305 __ push(r0); |
| 306 } |
| 307 } |
| 308 |
| 309 |
218 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { | 310 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { |
219 Comment cmnt(masm_, "[ RegExp Literal"); | 311 Comment cmnt(masm_, "[ RegExp Literal"); |
220 Label done; | 312 Label done; |
221 // Registers will be used as follows: | 313 // Registers will be used as follows: |
222 // r4 = JS function, literals array | 314 // r4 = JS function, literals array |
223 // r3 = literal index | 315 // r3 = literal index |
224 // r2 = RegExp pattern | 316 // r2 = RegExp pattern |
225 // r1 = RegExp flags | 317 // r1 = RegExp flags |
226 // r0 = temp + return value (RegExp literal) | 318 // r0 = temp + return value (RegExp literal) |
227 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 319 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
454 __ CallRuntime(function, arg_count); | 546 __ CallRuntime(function, arg_count); |
455 if (expr->location().is_temporary()) { | 547 if (expr->location().is_temporary()) { |
456 __ push(r0); | 548 __ push(r0); |
457 } else { | 549 } else { |
458 ASSERT(expr->location().is_nowhere()); | 550 ASSERT(expr->location().is_nowhere()); |
459 } | 551 } |
460 } | 552 } |
461 | 553 |
462 | 554 |
463 } } // namespace v8::internal | 555 } } // namespace v8::internal |
OLD | NEW |