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 1860 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1871 CodeForStatementPosition(node); | 1871 CodeForStatementPosition(node); |
1872 | 1872 |
1873 JumpTarget try_block; | 1873 JumpTarget try_block; |
1874 JumpTarget exit; | 1874 JumpTarget exit; |
1875 | 1875 |
1876 try_block.Call(); | 1876 try_block.Call(); |
1877 // --- Catch block --- | 1877 // --- Catch block --- |
1878 frame_->EmitPush(rax); | 1878 frame_->EmitPush(rax); |
1879 | 1879 |
1880 // Store the caught exception in the catch variable. | 1880 // Store the caught exception in the catch variable. |
1881 { Reference ref(this, node->catch_var()); | 1881 Variable* catch_var = node->catch_var()->var(); |
1882 ASSERT(ref.is_slot()); | 1882 ASSERT(catch_var != NULL && catch_var->slot() != NULL); |
1883 // Load the exception to the top of the stack. Here we make use of the | 1883 StoreToSlot(catch_var->slot(), NOT_CONST_INIT); |
1884 // convenient property that it doesn't matter whether a value is | |
1885 // immediately on top of or underneath a zero-sized reference. | |
1886 ref.SetValue(NOT_CONST_INIT); | |
1887 } | |
1888 | 1884 |
1889 // Remove the exception from the stack. | 1885 // Remove the exception from the stack. |
1890 frame_->Drop(); | 1886 frame_->Drop(); |
1891 | 1887 |
1892 VisitStatementsAndSpill(node->catch_block()->statements()); | 1888 VisitStatementsAndSpill(node->catch_block()->statements()); |
1893 if (has_valid_frame()) { | 1889 if (has_valid_frame()) { |
1894 exit.Jump(); | 1890 exit.Jump(); |
1895 } | 1891 } |
1896 | 1892 |
1897 | 1893 |
(...skipping 2840 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4738 frame_->Push(Factory::the_hole_value()); | 4734 frame_->Push(Factory::the_hole_value()); |
4739 } else { | 4735 } else { |
4740 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT); | 4736 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT); |
4741 frame_->PushFunction(); | 4737 frame_->PushFunction(); |
4742 frame_->PushReceiverSlotAddress(); | 4738 frame_->PushReceiverSlotAddress(); |
4743 frame_->Push(Smi::FromInt(scope_->num_parameters())); | 4739 frame_->Push(Smi::FromInt(scope_->num_parameters())); |
4744 Result result = frame_->CallStub(&stub, 3); | 4740 Result result = frame_->CallStub(&stub, 3); |
4745 frame_->Push(&result); | 4741 frame_->Push(&result); |
4746 } | 4742 } |
4747 | 4743 |
4748 { Reference shadow_ref(this, scope_->arguments_shadow()); | 4744 |
4749 Reference arguments_ref(this, scope_->arguments()); | 4745 Variable* arguments = scope_->arguments()->var(); |
4750 ASSERT(shadow_ref.is_slot() && arguments_ref.is_slot()); | 4746 Variable* shadow = scope_->arguments_shadow()->var(); |
4751 // Here we rely on the convenient property that references to slot | 4747 ASSERT(arguments != NULL && arguments->slot() != NULL); |
4752 // take up zero space in the frame (ie, it doesn't matter that the | 4748 ASSERT(shadow != NULL && shadow->slot() != NULL); |
4753 // stored value is actually below the reference on the frame). | 4749 JumpTarget done; |
4754 JumpTarget done; | 4750 bool skip_arguments = false; |
4755 bool skip_arguments = false; | 4751 if (mode == LAZY_ARGUMENTS_ALLOCATION && !initial) { |
4756 if (mode == LAZY_ARGUMENTS_ALLOCATION && !initial) { | 4752 // We have to skip storing into the arguments slot if it has |
4757 // We have to skip storing into the arguments slot if it has | 4753 // already been written to. This can happen if the a function |
4758 // already been written to. This can happen if the a function | 4754 // has a local variable named 'arguments'. |
4759 // has a local variable named 'arguments'. | 4755 LoadFromSlot(scope_->arguments()->var()->slot(), NOT_INSIDE_TYPEOF); |
4760 LoadFromSlot(scope_->arguments()->var()->slot(), NOT_INSIDE_TYPEOF); | 4756 Result probe = frame_->Pop(); |
4761 Result arguments = frame_->Pop(); | 4757 if (probe.is_constant()) { |
4762 if (arguments.is_constant()) { | 4758 // We have to skip updating the arguments object if it has been |
4763 // We have to skip updating the arguments object if it has | 4759 // assigned a proper value. |
4764 // been assigned a proper value. | 4760 skip_arguments = !probe.handle()->IsTheHole(); |
4765 skip_arguments = !arguments.handle()->IsTheHole(); | 4761 } else { |
4766 } else { | 4762 __ CompareRoot(probe.reg(), Heap::kTheHoleValueRootIndex); |
4767 __ CompareRoot(arguments.reg(), Heap::kTheHoleValueRootIndex); | 4763 probe.Unuse(); |
4768 arguments.Unuse(); | 4764 done.Branch(not_equal); |
4769 done.Branch(not_equal); | |
4770 } | |
4771 } | 4765 } |
4772 if (!skip_arguments) { | |
4773 arguments_ref.SetValue(NOT_CONST_INIT); | |
4774 if (mode == LAZY_ARGUMENTS_ALLOCATION) done.Bind(); | |
4775 } | |
4776 shadow_ref.SetValue(NOT_CONST_INIT); | |
4777 } | 4766 } |
| 4767 if (!skip_arguments) { |
| 4768 StoreToSlot(arguments->slot(), NOT_CONST_INIT); |
| 4769 if (mode == LAZY_ARGUMENTS_ALLOCATION) done.Bind(); |
| 4770 } |
| 4771 StoreToSlot(shadow->slot(), NOT_CONST_INIT); |
4778 return frame_->Pop(); | 4772 return frame_->Pop(); |
4779 } | 4773 } |
4780 | 4774 |
4781 | 4775 |
4782 void CodeGenerator::LoadTypeofExpression(Expression* expr) { | 4776 void CodeGenerator::LoadTypeofExpression(Expression* expr) { |
4783 // Special handling of identifiers as subexpressions of typeof. | 4777 // Special handling of identifiers as subexpressions of typeof. |
4784 Variable* variable = expr->AsVariableProxy()->AsVariable(); | 4778 Variable* variable = expr->AsVariableProxy()->AsVariable(); |
4785 if (variable != NULL && !variable->is_this() && variable->is_global()) { | 4779 if (variable != NULL && !variable->is_this() && variable->is_global()) { |
4786 // For a global variable we build the property reference | 4780 // For a global variable we build the property reference |
4787 // <global>.<variable> and perform a (regular non-contextual) property | 4781 // <global>.<variable> and perform a (regular non-contextual) property |
(...skipping 3434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8222 masm.GetCode(&desc); | 8216 masm.GetCode(&desc); |
8223 // Call the function from C++. | 8217 // Call the function from C++. |
8224 return FUNCTION_CAST<ModuloFunction>(buffer); | 8218 return FUNCTION_CAST<ModuloFunction>(buffer); |
8225 } | 8219 } |
8226 | 8220 |
8227 #endif | 8221 #endif |
8228 | 8222 |
8229 #undef __ | 8223 #undef __ |
8230 | 8224 |
8231 } } // namespace v8::internal | 8225 } } // namespace v8::internal |
OLD | NEW |