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 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
300 loop_nesting_ -= fun->loop_nesting(); | 300 loop_nesting_ -= fun->loop_nesting(); |
301 | 301 |
302 // Code generation state must be reset. | 302 // Code generation state must be reset. |
303 ASSERT(state_ == NULL); | 303 ASSERT(state_ == NULL); |
304 ASSERT(loop_nesting() == 0); | 304 ASSERT(loop_nesting() == 0); |
305 ASSERT(!function_return_is_shadowed_); | 305 ASSERT(!function_return_is_shadowed_); |
306 function_return_.Unuse(); | 306 function_return_.Unuse(); |
307 DeleteFrame(); | 307 DeleteFrame(); |
308 | 308 |
309 // Process any deferred code using the register allocator. | 309 // Process any deferred code using the register allocator. |
310 ProcessDeferred(); | 310 if (HasStackOverflow()) { |
| 311 ClearDeferred(); |
| 312 } else { |
| 313 ProcessDeferred(); |
| 314 } |
311 | 315 |
312 // There is no need to delete the register allocator, it is a | 316 // There is no need to delete the register allocator, it is a |
313 // stack-allocated local. | 317 // stack-allocated local. |
314 allocator_ = NULL; | 318 allocator_ = NULL; |
315 scope_ = NULL; | 319 scope_ = NULL; |
316 } | 320 } |
317 | 321 |
318 | 322 |
319 Operand CodeGenerator::SlotOperand(Slot* slot, Register tmp) { | 323 Operand CodeGenerator::SlotOperand(Slot* slot, Register tmp) { |
320 // Currently, this assertion will fail if we try to assign to | 324 // Currently, this assertion will fail if we try to assign to |
(...skipping 1239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1560 | 1564 |
1561 void CodeGenerator::VisitBlock(Block* node) { | 1565 void CodeGenerator::VisitBlock(Block* node) { |
1562 ASSERT(!in_spilled_code()); | 1566 ASSERT(!in_spilled_code()); |
1563 Comment cmnt(masm_, "[ Block"); | 1567 Comment cmnt(masm_, "[ Block"); |
1564 CodeForStatementPosition(node); | 1568 CodeForStatementPosition(node); |
1565 node->break_target()->Initialize(this); | 1569 node->break_target()->Initialize(this); |
1566 VisitStatements(node->statements()); | 1570 VisitStatements(node->statements()); |
1567 if (node->break_target()->is_linked()) { | 1571 if (node->break_target()->is_linked()) { |
1568 node->break_target()->Bind(); | 1572 node->break_target()->Bind(); |
1569 } | 1573 } |
| 1574 node->break_target()->Unuse(); |
1570 } | 1575 } |
1571 | 1576 |
1572 | 1577 |
1573 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 1578 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
1574 frame_->Push(pairs); | 1579 frame_->Push(pairs); |
1575 | 1580 |
1576 // Duplicate the context register. | 1581 // Duplicate the context register. |
1577 Result context(esi, this); | 1582 Result context(esi, this); |
1578 frame_->Push(&context); | 1583 frame_->Push(&context); |
1579 | 1584 |
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2087 // The last instruction emitted was a jump, either to the default | 2092 // The last instruction emitted was a jump, either to the default |
2088 // clause or the break target, or else to a case body from the loop | 2093 // clause or the break target, or else to a case body from the loop |
2089 // that compiles the tests. | 2094 // that compiles the tests. |
2090 ASSERT(!has_valid_frame()); | 2095 ASSERT(!has_valid_frame()); |
2091 // Compile case bodies as needed. | 2096 // Compile case bodies as needed. |
2092 for (int i = 0; i < length; i++) { | 2097 for (int i = 0; i < length; i++) { |
2093 CaseClause* clause = cases->at(i); | 2098 CaseClause* clause = cases->at(i); |
2094 | 2099 |
2095 // There are two ways to reach the body: from the corresponding | 2100 // There are two ways to reach the body: from the corresponding |
2096 // test or as the fall through of the previous body. | 2101 // test or as the fall through of the previous body. |
2097 if (!clause->body_target()->is_linked() && !has_valid_frame()) { | 2102 if (clause->body_target()->is_linked() || has_valid_frame()) { |
2098 // If we have neither, skip this body. | 2103 if (clause->body_target()->is_linked()) { |
2099 continue; | 2104 if (has_valid_frame()) { |
2100 } else if (clause->body_target()->is_linked() && has_valid_frame()) { | 2105 // If we have both a jump to the test and a fall through, put |
2101 // If we have both, put a jump on the fall through path to avoid | 2106 // a jump on the fall through path to avoid the dropping of |
2102 // the dropping of the switch value on the test path. The | 2107 // the switch value on the test path. The exception is the |
2103 // exception is the default which has already had the switch | 2108 // default which has already had the switch value dropped. |
2104 // value dropped. | 2109 if (clause->is_default()) { |
2105 if (clause->is_default()) { | 2110 clause->body_target()->Bind(); |
2106 clause->body_target()->Bind(); | 2111 } else { |
| 2112 JumpTarget body(this); |
| 2113 body.Jump(); |
| 2114 clause->body_target()->Bind(); |
| 2115 frame_->Drop(); |
| 2116 body.Bind(); |
| 2117 } |
| 2118 } else { |
| 2119 // No fall through to worry about. |
| 2120 clause->body_target()->Bind(); |
| 2121 if (!clause->is_default()) { |
| 2122 frame_->Drop(); |
| 2123 } |
| 2124 } |
2107 } else { | 2125 } else { |
2108 JumpTarget body(this); | 2126 // Otherwise, we have only fall through. |
2109 body.Jump(); | 2127 ASSERT(has_valid_frame()); |
2110 clause->body_target()->Bind(); | |
2111 frame_->Drop(); | |
2112 body.Bind(); | |
2113 } | 2128 } |
2114 } else if (clause->body_target()->is_linked()) { | 2129 |
2115 // No fall through to worry about. | 2130 // We are now prepared to compile the body. |
2116 clause->body_target()->Bind(); | 2131 Comment cmnt(masm_, "[ Case body"); |
2117 if (!clause->is_default()) { | 2132 VisitStatements(clause->statements()); |
2118 frame_->Drop(); | |
2119 } | |
2120 } else { | |
2121 // Otherwise, we have only fall through. | |
2122 ASSERT(has_valid_frame()); | |
2123 } | 2133 } |
2124 | 2134 clause->body_target()->Unuse(); |
2125 // We are now prepared to compile the body. | |
2126 Comment cmnt(masm_, "[ Case body"); | |
2127 VisitStatements(clause->statements()); | |
2128 } | 2135 } |
2129 | 2136 |
2130 // We may not have a valid frame here so bind the break target only | 2137 // We may not have a valid frame here so bind the break target only |
2131 // if needed. | 2138 // if needed. |
2132 if (node->break_target()->is_linked()) { | 2139 if (node->break_target()->is_linked()) { |
2133 node->break_target()->Bind(); | 2140 node->break_target()->Bind(); |
2134 } | 2141 } |
| 2142 node->break_target()->Unuse(); |
2135 } | 2143 } |
2136 | 2144 |
2137 | 2145 |
2138 void CodeGenerator::VisitLoopStatement(LoopStatement* node) { | 2146 void CodeGenerator::VisitLoopStatement(LoopStatement* node) { |
2139 ASSERT(!in_spilled_code()); | 2147 ASSERT(!in_spilled_code()); |
2140 Comment cmnt(masm_, "[ LoopStatement"); | 2148 Comment cmnt(masm_, "[ LoopStatement"); |
2141 CodeForStatementPosition(node); | 2149 CodeForStatementPosition(node); |
2142 node->break_target()->Initialize(this); | 2150 node->break_target()->Initialize(this); |
2143 | 2151 |
2144 // Simple condition analysis. ALWAYS_TRUE and ALWAYS_FALSE represent a | 2152 // Simple condition analysis. ALWAYS_TRUE and ALWAYS_FALSE represent a |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2445 // The break target may be already bound (by the condition), or | 2453 // The break target may be already bound (by the condition), or |
2446 // there may not be a valid frame. Bind it only if needed. | 2454 // there may not be a valid frame. Bind it only if needed. |
2447 if (node->break_target()->is_linked()) { | 2455 if (node->break_target()->is_linked()) { |
2448 node->break_target()->Bind(); | 2456 node->break_target()->Bind(); |
2449 } | 2457 } |
2450 break; | 2458 break; |
2451 } | 2459 } |
2452 } | 2460 } |
2453 | 2461 |
2454 DecrementLoopNesting(); | 2462 DecrementLoopNesting(); |
| 2463 node->continue_target()->Unuse(); |
| 2464 node->break_target()->Unuse(); |
2455 } | 2465 } |
2456 | 2466 |
2457 | 2467 |
2458 void CodeGenerator::VisitForInStatement(ForInStatement* node) { | 2468 void CodeGenerator::VisitForInStatement(ForInStatement* node) { |
2459 ASSERT(!in_spilled_code()); | 2469 ASSERT(!in_spilled_code()); |
2460 VirtualFrame::SpilledScope spilled_scope(this); | 2470 VirtualFrame::SpilledScope spilled_scope(this); |
2461 Comment cmnt(masm_, "[ ForInStatement"); | 2471 Comment cmnt(masm_, "[ ForInStatement"); |
2462 CodeForStatementPosition(node); | 2472 CodeForStatementPosition(node); |
2463 | 2473 |
2464 JumpTarget primitive(this); | 2474 JumpTarget primitive(this); |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2629 __ add(Operand(eax), Immediate(Smi::FromInt(1))); | 2639 __ add(Operand(eax), Immediate(Smi::FromInt(1))); |
2630 frame_->EmitPush(eax); | 2640 frame_->EmitPush(eax); |
2631 entry.Jump(); | 2641 entry.Jump(); |
2632 | 2642 |
2633 // Cleanup. | 2643 // Cleanup. |
2634 node->break_target()->Bind(); | 2644 node->break_target()->Bind(); |
2635 frame_->Drop(5); | 2645 frame_->Drop(5); |
2636 | 2646 |
2637 // Exit. | 2647 // Exit. |
2638 exit.Bind(); | 2648 exit.Bind(); |
| 2649 |
| 2650 node->continue_target()->Unuse(); |
| 2651 node->break_target()->Unuse(); |
2639 } | 2652 } |
2640 | 2653 |
2641 | 2654 |
2642 void CodeGenerator::VisitTryCatch(TryCatch* node) { | 2655 void CodeGenerator::VisitTryCatch(TryCatch* node) { |
2643 ASSERT(!in_spilled_code()); | 2656 ASSERT(!in_spilled_code()); |
2644 VirtualFrame::SpilledScope spilled_scope(this); | 2657 VirtualFrame::SpilledScope spilled_scope(this); |
2645 Comment cmnt(masm_, "[ TryCatch"); | 2658 Comment cmnt(masm_, "[ TryCatch"); |
2646 CodeForStatementPosition(node); | 2659 CodeForStatementPosition(node); |
2647 | 2660 |
2648 JumpTarget try_block(this); | 2661 JumpTarget try_block(this); |
(...skipping 4269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6918 | 6931 |
6919 // Slow-case: Go through the JavaScript implementation. | 6932 // Slow-case: Go through the JavaScript implementation. |
6920 __ bind(&slow); | 6933 __ bind(&slow); |
6921 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); | 6934 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); |
6922 } | 6935 } |
6923 | 6936 |
6924 | 6937 |
6925 #undef __ | 6938 #undef __ |
6926 | 6939 |
6927 } } // namespace v8::internal | 6940 } } // namespace v8::internal |
OLD | NEW |