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 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 // Call the stub for all other cases. | 290 // Call the stub for all other cases. |
291 __ push(source); | 291 __ push(source); |
292 ToBooleanStub stub; | 292 ToBooleanStub stub; |
293 __ CallStub(&stub); | 293 __ CallStub(&stub); |
294 __ testq(rax, rax); // The stub returns nonzero for true. | 294 __ testq(rax, rax); // The stub returns nonzero for true. |
295 __ j(not_zero, true_label); | 295 __ j(not_zero, true_label); |
296 __ jmp(false_label); | 296 __ jmp(false_label); |
297 } | 297 } |
298 | 298 |
299 | 299 |
| 300 void FastCodeGenerator::VisitDeclaration(Declaration* decl) { |
| 301 Variable* var = decl->proxy()->var(); |
| 302 ASSERT(var != NULL); // Must have been resolved. |
| 303 Slot* slot = var->slot(); |
| 304 ASSERT(slot != NULL); // No global declarations here. |
| 305 |
| 306 // We have 3 cases for slots: LOOKUP, LOCAL, CONTEXT. |
| 307 switch (slot->type()) { |
| 308 case Slot::LOOKUP: { |
| 309 __ push(rsi); |
| 310 __ Push(var->name()); |
| 311 // Declaration nodes are always introduced in one of two modes. |
| 312 ASSERT(decl->mode() == Variable::VAR || decl->mode() == Variable::CONST); |
| 313 PropertyAttributes attr = decl->mode() == Variable::VAR ? |
| 314 NONE : READ_ONLY; |
| 315 __ Push(Smi::FromInt(attr)); |
| 316 // Push initial value, if any. |
| 317 // Note: For variables we must not push an initial value (such as |
| 318 // 'undefined') because we may have a (legal) redeclaration and we |
| 319 // must not destroy the current value. |
| 320 if (decl->mode() == Variable::CONST) { |
| 321 __ Push(Factory::the_hole_value()); |
| 322 } else if (decl->fun() != NULL) { |
| 323 Visit(decl->fun()); |
| 324 } else { |
| 325 __ Push(Smi::FromInt(0)); // no initial value! |
| 326 } |
| 327 __ CallRuntime(Runtime::kDeclareContextSlot, 4); |
| 328 break; |
| 329 } |
| 330 case Slot::LOCAL: |
| 331 if (decl->mode() == Variable::CONST) { |
| 332 __ Move(Operand(rbp, SlotOffset(var->slot())), |
| 333 Factory::the_hole_value()); |
| 334 } else if (decl->fun() != NULL) { |
| 335 Visit(decl->fun()); |
| 336 __ pop(Operand(rbp, SlotOffset(var->slot()))); |
| 337 } |
| 338 break; |
| 339 case Slot::CONTEXT: |
| 340 // The variable in the decl always resides in the current context. |
| 341 ASSERT(function_->scope()->ContextChainLength(slot->var()->scope()) == 0); |
| 342 if (decl->mode() == Variable::CONST) { |
| 343 __ Move(rax, Factory::the_hole_value()); |
| 344 if (FLAG_debug_code) { |
| 345 // Check if we have the correct context pointer. |
| 346 __ movq(rbx, CodeGenerator::ContextOperand( |
| 347 rsi, Context::FCONTEXT_INDEX)); |
| 348 __ cmpq(rbx, rsi); |
| 349 __ Check(equal, "Unexpected declaration in current context."); |
| 350 } |
| 351 __ movq(CodeGenerator::ContextOperand(rsi, slot->index()), rax); |
| 352 // No write barrier since the_hole_value is in old space. |
| 353 ASSERT(Heap::InNewSpace(*Factory::the_hole_value())); |
| 354 } else if (decl->fun() != NULL) { |
| 355 Visit(decl->fun()); |
| 356 __ pop(rax); |
| 357 if (FLAG_debug_code) { |
| 358 // Check if we have the correct context pointer. |
| 359 __ movq(rbx, CodeGenerator::ContextOperand( |
| 360 rsi, Context::FCONTEXT_INDEX)); |
| 361 __ cmpq(rbx, rsi); |
| 362 __ Check(equal, "Unexpected declaration in current context."); |
| 363 } |
| 364 __ movq(CodeGenerator::ContextOperand(rsi, slot->index()), rax); |
| 365 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; |
| 366 __ RecordWrite(rsi, offset, rax, rcx); |
| 367 } |
| 368 break; |
| 369 default: |
| 370 UNREACHABLE(); |
| 371 } |
| 372 } |
| 373 |
| 374 |
300 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 375 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
301 // Call the runtime to declare the globals. | 376 // Call the runtime to declare the globals. |
302 __ push(rsi); // The context is the first argument. | 377 __ push(rsi); // The context is the first argument. |
303 __ Push(pairs); | 378 __ Push(pairs); |
304 __ Push(Smi::FromInt(is_eval_ ? 1 : 0)); | 379 __ Push(Smi::FromInt(is_eval_ ? 1 : 0)); |
305 __ CallRuntime(Runtime::kDeclareGlobals, 3); | 380 __ CallRuntime(Runtime::kDeclareGlobals, 3); |
306 // Return value is ignored. | 381 // Return value is ignored. |
307 } | 382 } |
308 | 383 |
309 | 384 |
(...skipping 1024 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1334 true_label_ = saved_true; | 1409 true_label_ = saved_true; |
1335 false_label_ = saved_false; | 1410 false_label_ = saved_false; |
1336 // Convert current context to test context: End post-test code. | 1411 // Convert current context to test context: End post-test code. |
1337 } | 1412 } |
1338 | 1413 |
1339 | 1414 |
1340 #undef __ | 1415 #undef __ |
1341 | 1416 |
1342 | 1417 |
1343 } } // namespace v8::internal | 1418 } } // namespace v8::internal |
OLD | NEW |