• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
7 namespace v8 {
8 namespace internal {
9 namespace interpreter {
10 
11 
~BreakableControlFlowBuilder()12 BreakableControlFlowBuilder::~BreakableControlFlowBuilder() {
13   DCHECK(break_sites_.empty());
14 }
15 
16 
SetBreakTarget(const BytecodeLabel & target)17 void BreakableControlFlowBuilder::SetBreakTarget(const BytecodeLabel& target) {
18   BindLabels(target, &break_sites_);
19 }
20 
21 
EmitJump(ZoneVector<BytecodeLabel> * sites)22 void BreakableControlFlowBuilder::EmitJump(ZoneVector<BytecodeLabel>* sites) {
23   sites->push_back(BytecodeLabel());
24   builder()->Jump(&sites->back());
25 }
26 
27 
EmitJumpIfTrue(ZoneVector<BytecodeLabel> * sites)28 void BreakableControlFlowBuilder::EmitJumpIfTrue(
29     ZoneVector<BytecodeLabel>* sites) {
30   sites->push_back(BytecodeLabel());
31   builder()->JumpIfTrue(&sites->back());
32 }
33 
34 
EmitJumpIfFalse(ZoneVector<BytecodeLabel> * sites)35 void BreakableControlFlowBuilder::EmitJumpIfFalse(
36     ZoneVector<BytecodeLabel>* sites) {
37   sites->push_back(BytecodeLabel());
38   builder()->JumpIfFalse(&sites->back());
39 }
40 
41 
EmitJumpIfUndefined(ZoneVector<BytecodeLabel> * sites)42 void BreakableControlFlowBuilder::EmitJumpIfUndefined(
43     ZoneVector<BytecodeLabel>* sites) {
44   sites->push_back(BytecodeLabel());
45   builder()->JumpIfUndefined(&sites->back());
46 }
47 
48 
EmitJumpIfNull(ZoneVector<BytecodeLabel> * sites)49 void BreakableControlFlowBuilder::EmitJumpIfNull(
50     ZoneVector<BytecodeLabel>* sites) {
51   sites->push_back(BytecodeLabel());
52   builder()->JumpIfNull(&sites->back());
53 }
54 
55 
EmitJump(ZoneVector<BytecodeLabel> * sites,int index)56 void BreakableControlFlowBuilder::EmitJump(ZoneVector<BytecodeLabel>* sites,
57                                            int index) {
58   builder()->Jump(&sites->at(index));
59 }
60 
61 
EmitJumpIfTrue(ZoneVector<BytecodeLabel> * sites,int index)62 void BreakableControlFlowBuilder::EmitJumpIfTrue(
63     ZoneVector<BytecodeLabel>* sites, int index) {
64   builder()->JumpIfTrue(&sites->at(index));
65 }
66 
67 
EmitJumpIfFalse(ZoneVector<BytecodeLabel> * sites,int index)68 void BreakableControlFlowBuilder::EmitJumpIfFalse(
69     ZoneVector<BytecodeLabel>* sites, int index) {
70   builder()->JumpIfFalse(&sites->at(index));
71 }
72 
73 
BindLabels(const BytecodeLabel & target,ZoneVector<BytecodeLabel> * sites)74 void BreakableControlFlowBuilder::BindLabels(const BytecodeLabel& target,
75                                              ZoneVector<BytecodeLabel>* sites) {
76   for (size_t i = 0; i < sites->size(); i++) {
77     BytecodeLabel& site = sites->at(i);
78     builder()->Bind(target, &site);
79   }
80   sites->clear();
81 }
82 
83 
EndBlock()84 void BlockBuilder::EndBlock() {
85   builder()->Bind(&block_end_);
86   SetBreakTarget(block_end_);
87 }
88 
89 
~LoopBuilder()90 LoopBuilder::~LoopBuilder() { DCHECK(continue_sites_.empty()); }
91 
92 
LoopHeader(ZoneVector<BytecodeLabel> * additional_labels)93 void LoopBuilder::LoopHeader(ZoneVector<BytecodeLabel>* additional_labels) {
94   // Jumps from before the loop header into the loop violate ordering
95   // requirements of bytecode basic blocks. The only entry into a loop
96   // must be the loop header. Surely breaks is okay? Not if nested
97   // and misplaced between the headers.
98   DCHECK(break_sites_.empty() && continue_sites_.empty());
99   builder()->Bind(&loop_header_);
100   for (auto& label : *additional_labels) {
101     builder()->Bind(loop_header_, &label);
102   }
103 }
104 
105 
EndLoop()106 void LoopBuilder::EndLoop() {
107   // Loop must have closed form, i.e. all loop elements are within the loop,
108   // the loop header precedes the body and next elements in the loop.
109   DCHECK(loop_header_.is_bound());
110   builder()->Bind(&loop_end_);
111   SetBreakTarget(loop_end_);
112 }
113 
SetContinueTarget()114 void LoopBuilder::SetContinueTarget() {
115   BytecodeLabel target;
116   builder()->Bind(&target);
117   BindLabels(target, &continue_sites_);
118 }
119 
120 
~SwitchBuilder()121 SwitchBuilder::~SwitchBuilder() {
122 #ifdef DEBUG
123   for (auto site : case_sites_) {
124     DCHECK(site.is_bound());
125   }
126 #endif
127 }
128 
129 
SetCaseTarget(int index)130 void SwitchBuilder::SetCaseTarget(int index) {
131   BytecodeLabel& site = case_sites_.at(index);
132   builder()->Bind(&site);
133 }
134 
135 
BeginTry(Register context)136 void TryCatchBuilder::BeginTry(Register context) {
137   builder()->MarkTryBegin(handler_id_, context);
138 }
139 
140 
EndTry()141 void TryCatchBuilder::EndTry() {
142   builder()->MarkTryEnd(handler_id_);
143   builder()->Jump(&exit_);
144   builder()->Bind(&handler_);
145   builder()->MarkHandler(handler_id_, true);
146 }
147 
148 
EndCatch()149 void TryCatchBuilder::EndCatch() { builder()->Bind(&exit_); }
150 
151 
BeginTry(Register context)152 void TryFinallyBuilder::BeginTry(Register context) {
153   builder()->MarkTryBegin(handler_id_, context);
154 }
155 
156 
LeaveTry()157 void TryFinallyBuilder::LeaveTry() {
158   finalization_sites_.push_back(BytecodeLabel());
159   builder()->Jump(&finalization_sites_.back());
160 }
161 
162 
EndTry()163 void TryFinallyBuilder::EndTry() {
164   builder()->MarkTryEnd(handler_id_);
165 }
166 
167 
BeginHandler()168 void TryFinallyBuilder::BeginHandler() {
169   builder()->Bind(&handler_);
170   builder()->MarkHandler(handler_id_, will_catch_);
171 }
172 
173 
BeginFinally()174 void TryFinallyBuilder::BeginFinally() {
175   for (size_t i = 0; i < finalization_sites_.size(); i++) {
176     BytecodeLabel& site = finalization_sites_.at(i);
177     builder()->Bind(&site);
178   }
179 }
180 
181 
EndFinally()182 void TryFinallyBuilder::EndFinally() {
183   // Nothing to be done here.
184 }
185 
186 }  // namespace interpreter
187 }  // namespace internal
188 }  // namespace v8
189