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 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 ASSERT(slot != NULL); | 216 ASSERT(slot != NULL); |
217 if (expr->location().is_temporary()) { | 217 if (expr->location().is_temporary()) { |
218 __ push(Operand(rbp, SlotOffset(slot))); | 218 __ push(Operand(rbp, SlotOffset(slot))); |
219 } else { | 219 } else { |
220 ASSERT(expr->location().is_nowhere()); | 220 ASSERT(expr->location().is_nowhere()); |
221 } | 221 } |
222 } | 222 } |
223 } | 223 } |
224 | 224 |
225 | 225 |
| 226 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { |
| 227 Comment cmnt(masm_, "[ ObjectLiteral"); |
| 228 Label boilerplate_exists; |
| 229 |
| 230 __ movq(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |
| 231 __ movq(rbx, FieldOperand(rdi, JSFunction::kLiteralsOffset)); |
| 232 int literal_offset = |
| 233 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize; |
| 234 __ movq(rax, FieldOperand(rbx, literal_offset)); |
| 235 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); |
| 236 __ j(not_equal, &boilerplate_exists); |
| 237 // Create boilerplate if it does not exist. |
| 238 // Literal array (0). |
| 239 __ push(rbx); |
| 240 // Literal index (1). |
| 241 __ Push(Smi::FromInt(expr->literal_index())); |
| 242 // Constant properties (2). |
| 243 __ Push(expr->constant_properties()); |
| 244 __ CallRuntime(Runtime::kCreateObjectLiteralBoilerplate, 3); |
| 245 __ bind(&boilerplate_exists); |
| 246 // rax contains boilerplate. |
| 247 // Clone boilerplate. |
| 248 __ push(rax); |
| 249 if (expr->depth() == 1) { |
| 250 __ CallRuntime(Runtime::kCloneShallowLiteralBoilerplate, 1); |
| 251 } else { |
| 252 __ CallRuntime(Runtime::kCloneLiteralBoilerplate, 1); |
| 253 } |
| 254 |
| 255 // If result_saved == true: the result is saved on top of the stack. |
| 256 // If result_saved == false: the result is not on the stack, just in rax. |
| 257 bool result_saved = false; |
| 258 |
| 259 for (int i = 0; i < expr->properties()->length(); i++) { |
| 260 ObjectLiteral::Property* property = expr->properties()->at(i); |
| 261 Literal* key = property->key(); |
| 262 Expression* value = property->value(); |
| 263 if (property->kind() == ObjectLiteral::Property::CONSTANT) continue; |
| 264 if (property->kind() == ObjectLiteral::Property::MATERIALIZED_LITERAL && |
| 265 CompileTimeValue::IsCompileTimeValue(value)) { |
| 266 continue; |
| 267 } |
| 268 if (!result_saved) { |
| 269 __ push(rax); // Save result on the stack |
| 270 result_saved = true; |
| 271 } |
| 272 switch (property->kind()) { |
| 273 case ObjectLiteral::Property::MATERIALIZED_LITERAL: // fall through |
| 274 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); |
| 275 case ObjectLiteral::Property::COMPUTED: |
| 276 if (key->handle()->IsSymbol()) { |
| 277 Visit(value); |
| 278 ASSERT(value->location().is_temporary()); |
| 279 __ pop(rax); |
| 280 __ Move(rcx, key->handle()); |
| 281 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
| 282 __ call(ic, RelocInfo::CODE_TARGET); |
| 283 // StoreIC leaves the receiver on the stack. |
| 284 break; |
| 285 } |
| 286 // fall through |
| 287 case ObjectLiteral::Property::PROTOTYPE: |
| 288 __ push(rax); |
| 289 Visit(key); |
| 290 if (key->location().is_constant()) { |
| 291 __ Push(key->handle()); |
| 292 } |
| 293 Visit(value); |
| 294 ASSERT(value->location().is_temporary()); |
| 295 __ CallRuntime(Runtime::kSetProperty, 3); |
| 296 __ movq(rax, Operand(rsp, 0)); // Restore result into rax. |
| 297 break; |
| 298 case ObjectLiteral::Property::SETTER: // fall through |
| 299 case ObjectLiteral::Property::GETTER: |
| 300 __ push(rax); |
| 301 Visit(key); |
| 302 if (key->location().is_constant()) { |
| 303 __ Push(key->handle()); |
| 304 } |
| 305 __ Push(property->kind() == ObjectLiteral::Property::SETTER ? |
| 306 Smi::FromInt(1) : |
| 307 Smi::FromInt(0)); |
| 308 Visit(value); |
| 309 ASSERT(value->location().is_temporary()); |
| 310 __ CallRuntime(Runtime::kDefineAccessor, 4); |
| 311 __ movq(rax, Operand(rsp, 0)); // Restore result into rax. |
| 312 break; |
| 313 default: UNREACHABLE(); |
| 314 } |
| 315 } |
| 316 if (expr->location().is_nowhere() && result_saved) { |
| 317 __ addq(rsp, Immediate(kPointerSize)); |
| 318 } else if (expr->location().is_temporary() && !result_saved) { |
| 319 __ push(rax); |
| 320 } |
| 321 } |
| 322 |
| 323 |
226 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { | 324 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { |
227 Comment cmnt(masm_, "[ RegExp Literal"); | 325 Comment cmnt(masm_, "[ RegExp Literal"); |
228 Label done; | 326 Label done; |
229 // Registers will be used as follows: | 327 // Registers will be used as follows: |
230 // rdi = JS function. | 328 // rdi = JS function. |
231 // rbx = literals array. | 329 // rbx = literals array. |
232 // rax = regexp literal. | 330 // rax = regexp literal. |
233 __ movq(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 331 __ movq(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |
234 __ movq(rbx, FieldOperand(rdi, JSFunction::kLiteralsOffset)); | 332 __ movq(rbx, FieldOperand(rdi, JSFunction::kLiteralsOffset)); |
235 int literal_offset = | 333 int literal_offset = |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
453 __ CallRuntime(function, arg_count); | 551 __ CallRuntime(function, arg_count); |
454 if (expr->location().is_temporary()) { | 552 if (expr->location().is_temporary()) { |
455 __ push(rax); | 553 __ push(rax); |
456 } else { | 554 } else { |
457 ASSERT(expr->location().is_nowhere()); | 555 ASSERT(expr->location().is_nowhere()); |
458 } | 556 } |
459 } | 557 } |
460 | 558 |
461 | 559 |
462 } } // namespace v8::internal | 560 } } // namespace v8::internal |
OLD | NEW |