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_X87 | 5 #if V8_TARGET_ARCH_X87 |
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 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
457 { | 457 { |
458 Label done_loop, loop; | 458 Label done_loop, loop; |
459 __ bind(&loop); | 459 __ bind(&loop); |
460 __ sub(ecx, Immediate(Smi::FromInt(1))); | 460 __ sub(ecx, Immediate(Smi::FromInt(1))); |
461 __ j(carry, &done_loop, Label::kNear); | 461 __ j(carry, &done_loop, Label::kNear); |
462 __ PushRoot(Heap::kTheHoleValueRootIndex); | 462 __ PushRoot(Heap::kTheHoleValueRootIndex); |
463 __ jmp(&loop); | 463 __ jmp(&loop); |
464 __ bind(&done_loop); | 464 __ bind(&done_loop); |
465 } | 465 } |
466 | 466 |
467 // Enter a new JavaScript frame, and initialize its slots as they were when | 467 // Dispatch on the kind of generator object. |
468 // the generator was suspended. | 468 Label old_generator; |
469 FrameScope scope(masm, StackFrame::MANUAL); | 469 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
470 __ PushReturnAddressFrom(eax); // Return address. | 470 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kFunctionDataOffset)); |
471 __ Push(ebp); // Caller's frame pointer. | 471 __ CmpObjectType(ecx, BYTECODE_ARRAY_TYPE, ecx); |
472 __ Move(ebp, esp); | 472 __ j(not_equal, &old_generator); |
473 __ Push(esi); // Callee's context. | |
474 __ Push(edi); // Callee's JS Function. | |
475 | 473 |
476 // Restore the operand stack. | 474 // New-style (ignition/turbofan) generator object |
477 __ mov(eax, FieldOperand(ebx, JSGeneratorObject::kOperandStackOffset)); | |
478 { | 475 { |
479 Label done_loop, loop; | 476 __ PushReturnAddressFrom(eax); |
480 __ Move(ecx, Smi::FromInt(0)); | 477 __ mov(eax, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
481 __ bind(&loop); | 478 __ mov(eax, |
482 __ cmp(ecx, FieldOperand(eax, FixedArray::kLengthOffset)); | 479 FieldOperand(ecx, SharedFunctionInfo::kFormalParameterCountOffset)); |
483 __ j(equal, &done_loop, Label::kNear); | 480 // We abuse new.target both to indicate that this is a resume call and to |
484 __ Push(FieldOperand(eax, ecx, times_half_pointer_size, | 481 // pass in the generator object. In ordinary calls, new.target is always |
485 FixedArray::kHeaderSize)); | 482 // undefined because generator functions are non-constructable. |
486 __ add(ecx, Immediate(Smi::FromInt(1))); | 483 __ mov(edx, ebx); |
487 __ jmp(&loop); | 484 __ jmp(FieldOperand(edi, JSFunction::kCodeEntryOffset)); |
488 __ bind(&done_loop); | |
489 } | 485 } |
490 | 486 |
491 // Reset operand stack so we don't leak. | 487 // Old-style (full-codegen) generator object |
492 __ mov(FieldOperand(ebx, JSGeneratorObject::kOperandStackOffset), | 488 __ bind(&old_generator); |
493 Immediate(masm->isolate()->factory()->empty_fixed_array())); | 489 { |
| 490 // Enter a new JavaScript frame, and initialize its slots as they were when |
| 491 // the generator was suspended. |
| 492 FrameScope scope(masm, StackFrame::MANUAL); |
| 493 __ PushReturnAddressFrom(eax); // Return address. |
| 494 __ Push(ebp); // Caller's frame pointer. |
| 495 __ Move(ebp, esp); |
| 496 __ Push(esi); // Callee's context. |
| 497 __ Push(edi); // Callee's JS Function. |
494 | 498 |
495 // Resume the generator function at the continuation. | 499 // Restore the operand stack. |
496 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | 500 __ mov(eax, FieldOperand(ebx, JSGeneratorObject::kOperandStackOffset)); |
497 __ mov(edx, FieldOperand(edx, SharedFunctionInfo::kCodeOffset)); | 501 { |
498 __ mov(ecx, FieldOperand(ebx, JSGeneratorObject::kContinuationOffset)); | 502 Label done_loop, loop; |
499 __ SmiUntag(ecx); | 503 __ Move(ecx, Smi::FromInt(0)); |
500 __ lea(edx, FieldOperand(edx, ecx, times_1, Code::kHeaderSize)); | 504 __ bind(&loop); |
501 __ mov(FieldOperand(ebx, JSGeneratorObject::kContinuationOffset), | 505 __ cmp(ecx, FieldOperand(eax, FixedArray::kLengthOffset)); |
502 Immediate(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting))); | 506 __ j(equal, &done_loop, Label::kNear); |
503 __ mov(eax, ebx); // Continuation expects generator object in eax. | 507 __ Push(FieldOperand(eax, ecx, times_half_pointer_size, |
504 __ jmp(edx); | 508 FixedArray::kHeaderSize)); |
| 509 __ add(ecx, Immediate(Smi::FromInt(1))); |
| 510 __ jmp(&loop); |
| 511 __ bind(&done_loop); |
| 512 } |
| 513 |
| 514 // Reset operand stack so we don't leak. |
| 515 __ mov(FieldOperand(ebx, JSGeneratorObject::kOperandStackOffset), |
| 516 Immediate(masm->isolate()->factory()->empty_fixed_array())); |
| 517 |
| 518 // Resume the generator function at the continuation. |
| 519 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
| 520 __ mov(edx, FieldOperand(edx, SharedFunctionInfo::kCodeOffset)); |
| 521 __ mov(ecx, FieldOperand(ebx, JSGeneratorObject::kContinuationOffset)); |
| 522 __ SmiUntag(ecx); |
| 523 __ lea(edx, FieldOperand(edx, ecx, times_1, Code::kHeaderSize)); |
| 524 __ mov(FieldOperand(ebx, JSGeneratorObject::kContinuationOffset), |
| 525 Immediate(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting))); |
| 526 __ mov(eax, ebx); // Continuation expects generator object in eax. |
| 527 __ jmp(edx); |
| 528 } |
505 } | 529 } |
506 | 530 |
507 // Generate code for entering a JS function with the interpreter. | 531 // Generate code for entering a JS function with the interpreter. |
508 // On entry to the function the receiver and arguments have been pushed on the | 532 // On entry to the function the receiver and arguments have been pushed on the |
509 // stack left to right. The actual argument count matches the formal parameter | 533 // stack left to right. The actual argument count matches the formal parameter |
510 // count expected by the function. | 534 // count expected by the function. |
511 // | 535 // |
512 // The live registers are: | 536 // The live registers are: |
513 // o edi: the JS function object being called | 537 // o edi: the JS function object being called |
514 // o edx: the new target | 538 // o edx: the new target |
(...skipping 2357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2872 // And "return" to the OSR entry point of the function. | 2896 // And "return" to the OSR entry point of the function. |
2873 __ ret(0); | 2897 __ ret(0); |
2874 } | 2898 } |
2875 | 2899 |
2876 | 2900 |
2877 #undef __ | 2901 #undef __ |
2878 } // namespace internal | 2902 } // namespace internal |
2879 } // namespace v8 | 2903 } // namespace v8 |
2880 | 2904 |
2881 #endif // V8_TARGET_ARCH_X87 | 2905 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |