OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_INTERPRETER_CONTROL_FLOW_BUILDERS_H_ | 5 #ifndef V8_INTERPRETER_CONTROL_FLOW_BUILDERS_H_ |
6 #define V8_INTERPRETER_CONTROL_FLOW_BUILDERS_H_ | 6 #define V8_INTERPRETER_CONTROL_FLOW_BUILDERS_H_ |
7 | 7 |
8 #include "src/interpreter/bytecode-array-builder.h" | 8 #include "src/interpreter/bytecode-array-builder.h" |
9 | 9 |
10 #include "src/zone-containers.h" | 10 #include "src/zone-containers.h" |
(...skipping 30 matching lines...) Expand all Loading... |
41 | 41 |
42 // This method is called when visiting break statements in the AST. | 42 // This method is called when visiting break statements in the AST. |
43 // Inserts a jump to a unbound label that is patched when the corresponding | 43 // Inserts a jump to a unbound label that is patched when the corresponding |
44 // SetBreakTarget is called. | 44 // SetBreakTarget is called. |
45 void Break() { EmitJump(&break_sites_); } | 45 void Break() { EmitJump(&break_sites_); } |
46 void BreakIfTrue() { EmitJumpIfTrue(&break_sites_); } | 46 void BreakIfTrue() { EmitJumpIfTrue(&break_sites_); } |
47 void BreakIfFalse() { EmitJumpIfFalse(&break_sites_); } | 47 void BreakIfFalse() { EmitJumpIfFalse(&break_sites_); } |
48 void BreakIfUndefined() { EmitJumpIfUndefined(&break_sites_); } | 48 void BreakIfUndefined() { EmitJumpIfUndefined(&break_sites_); } |
49 void BreakIfNull() { EmitJumpIfNull(&break_sites_); } | 49 void BreakIfNull() { EmitJumpIfNull(&break_sites_); } |
50 | 50 |
51 | |
52 protected: | 51 protected: |
53 void EmitJump(ZoneVector<BytecodeLabel>* labels); | 52 void EmitJump(ZoneVector<BytecodeLabel>* labels); |
54 void EmitJump(ZoneVector<BytecodeLabel>* labels, int index); | 53 void EmitJump(ZoneVector<BytecodeLabel>* labels, int index); |
55 void EmitJumpIfTrue(ZoneVector<BytecodeLabel>* labels); | 54 void EmitJumpIfTrue(ZoneVector<BytecodeLabel>* labels); |
56 void EmitJumpIfTrue(ZoneVector<BytecodeLabel>* labels, int index); | 55 void EmitJumpIfTrue(ZoneVector<BytecodeLabel>* labels, int index); |
57 void EmitJumpIfFalse(ZoneVector<BytecodeLabel>* labels); | 56 void EmitJumpIfFalse(ZoneVector<BytecodeLabel>* labels); |
58 void EmitJumpIfFalse(ZoneVector<BytecodeLabel>* labels, int index); | 57 void EmitJumpIfFalse(ZoneVector<BytecodeLabel>* labels, int index); |
59 void EmitJumpIfUndefined(ZoneVector<BytecodeLabel>* labels); | 58 void EmitJumpIfUndefined(ZoneVector<BytecodeLabel>* labels); |
60 void EmitJumpIfNull(ZoneVector<BytecodeLabel>* labels); | 59 void EmitJumpIfNull(ZoneVector<BytecodeLabel>* labels); |
61 | 60 |
62 void BindLabels(const BytecodeLabel& target, ZoneVector<BytecodeLabel>* site); | 61 void BindLabels(const BytecodeLabel& target, ZoneVector<BytecodeLabel>* site); |
63 | 62 |
64 private: | 63 private: |
65 // Unbound labels that identify jumps for break statements in the code. | 64 // Unbound labels that identify jumps for break statements in the code. |
66 ZoneVector<BytecodeLabel> break_sites_; | 65 ZoneVector<BytecodeLabel> break_sites_; |
67 }; | 66 }; |
68 | 67 |
| 68 |
| 69 // Class to track control flow for block statements (which can break in JS). |
| 70 class BlockBuilder final : public BreakableControlFlowBuilder { |
| 71 public: |
| 72 explicit BlockBuilder(BytecodeArrayBuilder* builder) |
| 73 : BreakableControlFlowBuilder(builder) {} |
| 74 |
| 75 void EndBlock(); |
| 76 |
| 77 private: |
| 78 BytecodeLabel block_end_; |
| 79 }; |
| 80 |
| 81 |
69 // A class to help with co-ordinating break and continue statements with | 82 // A class to help with co-ordinating break and continue statements with |
70 // their loop. | 83 // their loop. |
71 class LoopBuilder final : public BreakableControlFlowBuilder { | 84 class LoopBuilder final : public BreakableControlFlowBuilder { |
72 public: | 85 public: |
73 explicit LoopBuilder(BytecodeArrayBuilder* builder) | 86 explicit LoopBuilder(BytecodeArrayBuilder* builder) |
74 : BreakableControlFlowBuilder(builder), | 87 : BreakableControlFlowBuilder(builder), |
75 continue_sites_(builder->zone()) {} | 88 continue_sites_(builder->zone()) {} |
76 ~LoopBuilder(); | 89 ~LoopBuilder(); |
77 | 90 |
78 void LoopHeader() { builder()->Bind(&loop_header_); } | 91 void LoopHeader() { builder()->Bind(&loop_header_); } |
79 void Condition() { builder()->Bind(&condition_); } | 92 void Condition() { builder()->Bind(&condition_); } |
80 void Next() { builder()->Bind(&next_); } | 93 void Next() { builder()->Bind(&next_); } |
81 void JumpToHeader() { builder()->Jump(&loop_header_); } | 94 void JumpToHeader() { builder()->Jump(&loop_header_); } |
82 void JumpToHeaderIfTrue() { builder()->JumpIfTrue(&loop_header_); } | 95 void JumpToHeaderIfTrue() { builder()->JumpIfTrue(&loop_header_); } |
83 void LoopEnd(); | 96 void EndLoop(); |
84 | 97 |
85 // This method is called when visiting continue statements in the AST. | 98 // This method is called when visiting continue statements in the AST. |
86 // Inserts a jump to a unbound label that is patched when the corresponding | 99 // Inserts a jump to a unbound label that is patched when the corresponding |
87 // SetContinueTarget is called. | 100 // SetContinueTarget is called. |
88 void Continue() { EmitJump(&continue_sites_); } | 101 void Continue() { EmitJump(&continue_sites_); } |
89 void ContinueIfTrue() { EmitJumpIfTrue(&continue_sites_); } | 102 void ContinueIfTrue() { EmitJumpIfTrue(&continue_sites_); } |
90 void ContinueIfUndefined() { EmitJumpIfUndefined(&continue_sites_); } | 103 void ContinueIfUndefined() { EmitJumpIfUndefined(&continue_sites_); } |
91 void ContinueIfNull() { EmitJumpIfNull(&continue_sites_); } | 104 void ContinueIfNull() { EmitJumpIfNull(&continue_sites_); } |
92 | 105 |
93 private: | 106 private: |
94 void SetContinueTarget(const BytecodeLabel& continue_target); | 107 void SetContinueTarget(const BytecodeLabel& continue_target); |
95 | 108 |
96 BytecodeLabel loop_header_; | 109 BytecodeLabel loop_header_; |
97 BytecodeLabel condition_; | 110 BytecodeLabel condition_; |
98 BytecodeLabel next_; | 111 BytecodeLabel next_; |
99 BytecodeLabel loop_end_; | 112 BytecodeLabel loop_end_; |
100 | 113 |
101 // Unbound labels that identify jumps for continue statements in the code. | 114 // Unbound labels that identify jumps for continue statements in the code. |
102 ZoneVector<BytecodeLabel> continue_sites_; | 115 ZoneVector<BytecodeLabel> continue_sites_; |
103 }; | 116 }; |
104 | 117 |
| 118 |
105 // A class to help with co-ordinating break statements with their switch. | 119 // A class to help with co-ordinating break statements with their switch. |
106 // TODO(oth): add support for TF branch/merge info. | |
107 class SwitchBuilder final : public BreakableControlFlowBuilder { | 120 class SwitchBuilder final : public BreakableControlFlowBuilder { |
108 public: | 121 public: |
109 explicit SwitchBuilder(BytecodeArrayBuilder* builder, int number_of_cases) | 122 explicit SwitchBuilder(BytecodeArrayBuilder* builder, int number_of_cases) |
110 : BreakableControlFlowBuilder(builder), | 123 : BreakableControlFlowBuilder(builder), |
111 case_sites_(builder->zone()) { | 124 case_sites_(builder->zone()) { |
112 case_sites_.resize(number_of_cases); | 125 case_sites_.resize(number_of_cases); |
113 } | 126 } |
114 ~SwitchBuilder(); | 127 ~SwitchBuilder(); |
115 | 128 |
116 // This method should be called by the SwitchBuilder owner when the case | 129 // This method should be called by the SwitchBuilder owner when the case |
(...skipping 13 matching lines...) Expand all Loading... |
130 private: | 143 private: |
131 // Unbound labels that identify jumps for case statements in the code. | 144 // Unbound labels that identify jumps for case statements in the code. |
132 ZoneVector<BytecodeLabel> case_sites_; | 145 ZoneVector<BytecodeLabel> case_sites_; |
133 }; | 146 }; |
134 | 147 |
135 } // namespace interpreter | 148 } // namespace interpreter |
136 } // namespace internal | 149 } // namespace internal |
137 } // namespace v8 | 150 } // namespace v8 |
138 | 151 |
139 #endif // V8_INTERPRETER_CONTROL_FLOW_BUILDERS_H_ | 152 #endif // V8_INTERPRETER_CONTROL_FLOW_BUILDERS_H_ |
OLD | NEW |