OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
456 { | 456 { |
457 Label done_loop, loop; | 457 Label done_loop, loop; |
458 __ bind(&loop); | 458 __ bind(&loop); |
459 __ sub(ecx, Immediate(Smi::FromInt(1))); | 459 __ sub(ecx, Immediate(Smi::FromInt(1))); |
460 __ j(carry, &done_loop, Label::kNear); | 460 __ j(carry, &done_loop, Label::kNear); |
461 __ PushRoot(Heap::kTheHoleValueRootIndex); | 461 __ PushRoot(Heap::kTheHoleValueRootIndex); |
462 __ jmp(&loop); | 462 __ jmp(&loop); |
463 __ bind(&done_loop); | 463 __ bind(&done_loop); |
464 } | 464 } |
465 | 465 |
466 // Enter a new JavaScript frame, and initialize its slots as they were when | 466 // Dispatch on the kind of generator object. |
467 // the generator was suspended. | 467 Label old_generator; |
468 FrameScope scope(masm, StackFrame::MANUAL); | 468 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
469 __ PushReturnAddressFrom(eax); // Return address. | 469 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kFunctionDataOffset)); |
470 __ Push(ebp); // Caller's frame pointer. | 470 __ CmpObjectType(ecx, BYTECODE_ARRAY_TYPE, ecx); |
471 __ Move(ebp, esp); | 471 __ j(not_equal, &old_generator); |
472 __ Push(esi); // Callee's context. | |
473 __ Push(edi); // Callee's JS Function. | |
474 | 472 |
475 // Restore the operand stack. | 473 // New-style (ignition/turbofan) generator object |
476 __ mov(eax, FieldOperand(ebx, JSGeneratorObject::kOperandStackOffset)); | |
477 { | 474 { |
478 Label done_loop, loop; | 475 __ PushReturnAddressFrom(eax); |
479 __ Move(ecx, Smi::FromInt(0)); | 476 __ mov(eax, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
480 __ bind(&loop); | 477 __ mov(eax, |
481 __ cmp(ecx, FieldOperand(eax, FixedArray::kLengthOffset)); | 478 FieldOperand(ecx, SharedFunctionInfo::kFormalParameterCountOffset)); |
482 __ j(equal, &done_loop, Label::kNear); | 479 // We abuse new.target both to indicate that this is a resume call and to |
483 __ Push(FieldOperand(eax, ecx, times_half_pointer_size, | 480 // pass in the generator object. In ordinary calls, new.target is always |
484 FixedArray::kHeaderSize)); | 481 // undefined because generator functions are non-constructable. |
485 __ add(ecx, Immediate(Smi::FromInt(1))); | 482 __ mov(edx, ebx); |
486 __ jmp(&loop); | 483 __ jmp(FieldOperand(edi, JSFunction::kCodeEntryOffset)); |
487 __ bind(&done_loop); | |
488 } | 484 } |
489 | 485 |
490 // Reset operand stack so we don't leak. | 486 // Old-style (full-codegen) generator object |
491 __ mov(FieldOperand(ebx, JSGeneratorObject::kOperandStackOffset), | 487 __ bind(&old_generator); |
492 Immediate(masm->isolate()->factory()->empty_fixed_array())); | 488 { |
| 489 // Enter a new JavaScript frame, and initialize its slots as they were when |
| 490 // the generator was suspended. |
| 491 FrameScope scope(masm, StackFrame::MANUAL); |
| 492 __ PushReturnAddressFrom(eax); // Return address. |
| 493 __ Push(ebp); // Caller's frame pointer. |
| 494 __ Move(ebp, esp); |
| 495 __ Push(esi); // Callee's context. |
| 496 __ Push(edi); // Callee's JS Function. |
493 | 497 |
494 // Resume the generator function at the continuation. | 498 // Restore the operand stack. |
495 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | 499 __ mov(eax, FieldOperand(ebx, JSGeneratorObject::kOperandStackOffset)); |
496 __ mov(edx, FieldOperand(edx, SharedFunctionInfo::kCodeOffset)); | 500 { |
497 __ mov(ecx, FieldOperand(ebx, JSGeneratorObject::kContinuationOffset)); | 501 Label done_loop, loop; |
498 __ SmiUntag(ecx); | 502 __ Move(ecx, Smi::FromInt(0)); |
499 __ lea(edx, FieldOperand(edx, ecx, times_1, Code::kHeaderSize)); | 503 __ bind(&loop); |
500 __ mov(FieldOperand(ebx, JSGeneratorObject::kContinuationOffset), | 504 __ cmp(ecx, FieldOperand(eax, FixedArray::kLengthOffset)); |
501 Immediate(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting))); | 505 __ j(equal, &done_loop, Label::kNear); |
502 __ mov(eax, ebx); // Continuation expects generator object in eax. | 506 __ Push(FieldOperand(eax, ecx, times_half_pointer_size, |
503 __ jmp(edx); | 507 FixedArray::kHeaderSize)); |
| 508 __ add(ecx, Immediate(Smi::FromInt(1))); |
| 509 __ jmp(&loop); |
| 510 __ bind(&done_loop); |
| 511 } |
| 512 |
| 513 // Reset operand stack so we don't leak. |
| 514 __ mov(FieldOperand(ebx, JSGeneratorObject::kOperandStackOffset), |
| 515 Immediate(masm->isolate()->factory()->empty_fixed_array())); |
| 516 |
| 517 // Resume the generator function at the continuation. |
| 518 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
| 519 __ mov(edx, FieldOperand(edx, SharedFunctionInfo::kCodeOffset)); |
| 520 __ mov(ecx, FieldOperand(ebx, JSGeneratorObject::kContinuationOffset)); |
| 521 __ SmiUntag(ecx); |
| 522 __ lea(edx, FieldOperand(edx, ecx, times_1, Code::kHeaderSize)); |
| 523 __ mov(FieldOperand(ebx, JSGeneratorObject::kContinuationOffset), |
| 524 Immediate(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting))); |
| 525 __ mov(eax, ebx); // Continuation expects generator object in eax. |
| 526 __ jmp(edx); |
| 527 } |
504 } | 528 } |
505 | 529 |
506 // Generate code for entering a JS function with the interpreter. | 530 // Generate code for entering a JS function with the interpreter. |
507 // On entry to the function the receiver and arguments have been pushed on the | 531 // On entry to the function the receiver and arguments have been pushed on the |
508 // stack left to right. The actual argument count matches the formal parameter | 532 // stack left to right. The actual argument count matches the formal parameter |
509 // count expected by the function. | 533 // count expected by the function. |
510 // | 534 // |
511 // The live registers are: | 535 // The live registers are: |
512 // o edi: the JS function object being called | 536 // o edi: the JS function object being called |
513 // o edx: the new target | 537 // o edx: the new target |
(...skipping 2349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2863 // And "return" to the OSR entry point of the function. | 2887 // And "return" to the OSR entry point of the function. |
2864 __ ret(0); | 2888 __ ret(0); |
2865 } | 2889 } |
2866 | 2890 |
2867 | 2891 |
2868 #undef __ | 2892 #undef __ |
2869 } // namespace internal | 2893 } // namespace internal |
2870 } // namespace v8 | 2894 } // namespace v8 |
2871 | 2895 |
2872 #endif // V8_TARGET_ARCH_IA32 | 2896 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |