OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 3474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3485 // In case of thrown exceptions, this is where we continue. | 3485 // In case of thrown exceptions, this is where we continue. |
3486 __ Set(ecx, Immediate(Smi::FromInt(THROWING))); | 3486 __ Set(ecx, Immediate(Smi::FromInt(THROWING))); |
3487 __ jmp(&finally_block); | 3487 __ jmp(&finally_block); |
3488 | 3488 |
3489 | 3489 |
3490 // --- Try block --- | 3490 // --- Try block --- |
3491 __ bind(&try_block); | 3491 __ bind(&try_block); |
3492 | 3492 |
3493 __ PushTryHandler(IN_JAVASCRIPT, TRY_FINALLY_HANDLER); | 3493 __ PushTryHandler(IN_JAVASCRIPT, TRY_FINALLY_HANDLER); |
3494 // TODO(1222589): remove the reliance of PushTryHandler on a cached TOS | 3494 // TODO(1222589): remove the reliance of PushTryHandler on a cached TOS |
3495 __ push(eax); // | 3495 __ push(eax); |
3496 | 3496 |
3497 // Introduce shadow labels for all escapes from the try block, | 3497 // Introduce shadow labels for all escapes from the try block, |
3498 // including returns. We should probably try to unify the escaping | 3498 // including returns. We should probably try to unify the escaping |
3499 // labels and the return label. | 3499 // labels and the return label. |
3500 int nof_escapes = node->escaping_labels()->length(); | 3500 int nof_escapes = node->escaping_labels()->length(); |
3501 List<LabelShadow*> shadows(1 + nof_escapes); | 3501 List<LabelShadow*> shadows(1 + nof_escapes); |
3502 shadows.Add(new LabelShadow(&function_return_)); | 3502 shadows.Add(new LabelShadow(&function_return_)); |
3503 for (int i = 0; i < nof_escapes; i++) { | 3503 for (int i = 0; i < nof_escapes; i++) { |
3504 shadows.Add(new LabelShadow(node->escaping_labels()->at(i))); | 3504 shadows.Add(new LabelShadow(node->escaping_labels()->at(i))); |
3505 } | 3505 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3551 __ lea(esp, Operand(edx, kNextOffset)); | 3551 __ lea(esp, Operand(edx, kNextOffset)); |
3552 | 3552 |
3553 __ pop(Operand::StaticVariable(handler_address)); | 3553 __ pop(Operand::StaticVariable(handler_address)); |
3554 __ add(Operand(esp), Immediate(StackHandlerConstants::kSize - kPointerSize)); | 3554 __ add(Operand(esp), Immediate(StackHandlerConstants::kSize - kPointerSize)); |
3555 // next_sp popped. | 3555 // next_sp popped. |
3556 __ push(eax); // preserve the TOS in a register across stack manipulation | 3556 __ push(eax); // preserve the TOS in a register across stack manipulation |
3557 | 3557 |
3558 // --- Finally block --- | 3558 // --- Finally block --- |
3559 __ bind(&finally_block); | 3559 __ bind(&finally_block); |
3560 | 3560 |
| 3561 // We keep a single element on the stack - the (possibly faked) |
| 3562 // result - while evaluating the finally block. Record it, so that a |
| 3563 // break/continue crossing this statement can restore the stack. |
| 3564 const int kFinallyStackSize = 1 * kPointerSize; |
| 3565 break_stack_height_ += kFinallyStackSize; |
| 3566 |
3561 // Push the state on the stack. If necessary move the state to a | 3567 // Push the state on the stack. If necessary move the state to a |
3562 // local variable to avoid having extra values on the stack while | 3568 // local variable to avoid having extra values on the stack while |
3563 // evaluating the finally block. | 3569 // evaluating the finally block. |
3564 __ push(ecx); | 3570 __ push(ecx); |
3565 if (node->finally_var() != NULL) { | 3571 if (node->finally_var() != NULL) { |
3566 Reference target(this, node->finally_var()); | 3572 Reference target(this, node->finally_var()); |
3567 SetValue(&target); | 3573 SetValue(&target); |
3568 ASSERT(target.size() == 0); // no extra stuff on the stack | 3574 ASSERT(target.size() == 0); // no extra stuff on the stack |
3569 __ pop(edx); // remove the extra value that was pushed above | 3575 __ pop(edx); // remove the extra value that was pushed above |
3570 } | 3576 } |
3571 | 3577 |
3572 // Generate code for the statements in the finally block. | 3578 // Generate code for the statements in the finally block. |
3573 VisitStatements(node->finally_block()->statements()); | 3579 VisitStatements(node->finally_block()->statements()); |
3574 | 3580 |
3575 // Get the state from the stack - or the local variable - and | 3581 // Get the state from the stack - or the local variable - and |
3576 // restore the TOS register. | 3582 // restore the TOS register. |
3577 if (node->finally_var() != NULL) { | 3583 if (node->finally_var() != NULL) { |
3578 Reference target(this, node->finally_var()); | 3584 Reference target(this, node->finally_var()); |
3579 GetValue(&target); | 3585 GetValue(&target); |
3580 } | 3586 } |
3581 __ pop(ecx); | 3587 __ pop(ecx); |
3582 | 3588 |
3583 // Restore return value or faked TOS. | 3589 // Restore return value or faked TOS. |
3584 __ pop(eax); | 3590 __ pop(eax); |
3585 | 3591 |
| 3592 // Record the fact that the result has been removed from the stack. |
| 3593 break_stack_height_ -= kFinallyStackSize; |
| 3594 |
3586 // Generate code that jumps to the right destination for all used | 3595 // Generate code that jumps to the right destination for all used |
3587 // shadow labels. | 3596 // shadow labels. |
3588 for (int i = 0; i <= nof_escapes; i++) { | 3597 for (int i = 0; i <= nof_escapes; i++) { |
3589 if (shadows[i]->is_bound()) { | 3598 if (shadows[i]->is_bound()) { |
3590 __ cmp(Operand(ecx), Immediate(Smi::FromInt(JUMPING + i))); | 3599 __ cmp(Operand(ecx), Immediate(Smi::FromInt(JUMPING + i))); |
3591 __ j(equal, shadows[i]->shadowed()); | 3600 __ j(equal, shadows[i]->shadowed()); |
3592 } | 3601 } |
3593 } | 3602 } |
3594 | 3603 |
3595 // Check if we need to rethrow the exception. | 3604 // Check if we need to rethrow the exception. |
(...skipping 1884 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5480 bool is_eval) { | 5489 bool is_eval) { |
5481 Handle<Code> code = Ia32CodeGenerator::MakeCode(fun, script, is_eval); | 5490 Handle<Code> code = Ia32CodeGenerator::MakeCode(fun, script, is_eval); |
5482 if (!code.is_null()) { | 5491 if (!code.is_null()) { |
5483 Counters::total_compiled_code_size.Increment(code->instruction_size()); | 5492 Counters::total_compiled_code_size.Increment(code->instruction_size()); |
5484 } | 5493 } |
5485 return code; | 5494 return code; |
5486 } | 5495 } |
5487 | 5496 |
5488 | 5497 |
5489 } } // namespace v8::internal | 5498 } } // namespace v8::internal |
OLD | NEW |