| 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 |