1 // Copyright 2015 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "src/interpreter/control-flow-builders.h" 6 #include "src/objects-inl.h" 7 8 namespace v8 { 9 namespace internal { 10 namespace interpreter { 11 12 13 BreakableControlFlowBuilder::~BreakableControlFlowBuilder() { 14 DCHECK(break_labels_.empty() || break_labels_.is_bound()); 15 } 16 17 void BreakableControlFlowBuilder::BindBreakTarget() { 18 break_labels_.Bind(builder()); 19 } 20 21 void BreakableControlFlowBuilder::EmitJump(BytecodeLabels* sites) { 22 builder()->Jump(sites->New()); 23 } 24 25 void BreakableControlFlowBuilder::EmitJumpIfTrue(BytecodeLabels* sites) { 26 builder()->JumpIfTrue(sites->New()); 27 } 28 29 void BreakableControlFlowBuilder::EmitJumpIfFalse(BytecodeLabels* sites) { 30 builder()->JumpIfFalse(sites->New()); 31 } 32 33 void BreakableControlFlowBuilder::EmitJumpIfUndefined(BytecodeLabels* sites) { 34 builder()->JumpIfUndefined(sites->New()); 35 } 36 37 void BreakableControlFlowBuilder::EmitJumpIfNull(BytecodeLabels* sites) { 38 builder()->JumpIfNull(sites->New()); 39 } 40 41 42 void BlockBuilder::EndBlock() { 43 builder()->Bind(&block_end_); 44 BindBreakTarget(); 45 } 46 47 LoopBuilder::~LoopBuilder() { 48 DCHECK(continue_labels_.empty() || continue_labels_.is_bound()); 49 DCHECK(header_labels_.empty() || header_labels_.is_bound()); 50 } 51 52 void LoopBuilder::LoopHeader(ZoneVector<BytecodeLabel>* additional_labels) { 53 // Jumps from before the loop header into the loop violate ordering 54 // requirements of bytecode basic blocks. The only entry into a loop 55 // must be the loop header. Surely breaks is okay? Not if nested 56 // and misplaced between the headers. 57 DCHECK(break_labels_.empty() && continue_labels_.empty()); 58 builder()->Bind(&loop_header_); 59 if (additional_labels != nullptr) { 60 for (auto& label : *additional_labels) { 61 builder()->Bind(&label); 62 } 63 } 64 } 65 66 void LoopBuilder::JumpToHeader(int loop_depth) { 67 // Pass the proper loop nesting level to the backwards branch, to trigger 68 // on-stack replacement when armed for the given loop nesting depth. 69 int level = Min(loop_depth, AbstractCode::kMaxLoopNestingMarker - 1); 70 // Loop must have closed form, i.e. all loop elements are within the loop, 71 // the loop header precedes the body and next elements in the loop. 72 DCHECK(loop_header_.is_bound()); 73 builder()->JumpLoop(&loop_header_, level); 74 } 75 76 void LoopBuilder::EndLoop() { 77 BindBreakTarget(); 78 header_labels_.BindToLabel(builder(), loop_header_); 79 } 80 81 void LoopBuilder::BindContinueTarget() { continue_labels_.Bind(builder()); } 82 83 SwitchBuilder::~SwitchBuilder() { 84 #ifdef DEBUG 85 for (auto site : case_sites_) { 86 DCHECK(site.is_bound()); 87 } 88 #endif 89 } 90 91 92 void SwitchBuilder::SetCaseTarget(int index) { 93 BytecodeLabel& site = case_sites_.at(index); 94 builder()->Bind(&site); 95 } 96 97 98 void TryCatchBuilder::BeginTry(Register context) { 99 builder()->MarkTryBegin(handler_id_, context); 100 } 101 102 103 void TryCatchBuilder::EndTry() { 104 builder()->MarkTryEnd(handler_id_); 105 builder()->Jump(&exit_); 106 builder()->Bind(&handler_); 107 builder()->MarkHandler(handler_id_, catch_prediction_); 108 } 109 110 111 void TryCatchBuilder::EndCatch() { builder()->Bind(&exit_); } 112 113 114 void TryFinallyBuilder::BeginTry(Register context) { 115 builder()->MarkTryBegin(handler_id_, context); 116 } 117 118 119 void TryFinallyBuilder::LeaveTry() { 120 builder()->Jump(finalization_sites_.New()); 121 } 122 123 124 void TryFinallyBuilder::EndTry() { 125 builder()->MarkTryEnd(handler_id_); 126 } 127 128 129 void TryFinallyBuilder::BeginHandler() { 130 builder()->Bind(&handler_); 131 builder()->MarkHandler(handler_id_, catch_prediction_); 132 } 133 134 void TryFinallyBuilder::BeginFinally() { finalization_sites_.Bind(builder()); } 135 136 void TryFinallyBuilder::EndFinally() { 137 // Nothing to be done here. 138 } 139 140 } // namespace interpreter 141 } // namespace internal 142 } // namespace v8 143