OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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_FULL_CODEGEN_FULL_CODEGEN_H_ | 5 #ifndef V8_FULL_CODEGEN_FULL_CODEGEN_H_ |
6 #define V8_FULL_CODEGEN_FULL_CODEGEN_H_ | 6 #define V8_FULL_CODEGEN_FULL_CODEGEN_H_ |
7 | 7 |
8 #include "src/allocation.h" | 8 #include "src/allocation.h" |
9 #include "src/assert-scope.h" | 9 #include "src/assert-scope.h" |
10 #include "src/ast/ast.h" | 10 #include "src/ast/ast.h" |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 | 101 |
102 private: | 102 private: |
103 class Breakable; | 103 class Breakable; |
104 class Iteration; | 104 class Iteration; |
105 class TryFinally; | 105 class TryFinally; |
106 | 106 |
107 class TestContext; | 107 class TestContext; |
108 | 108 |
109 class NestedStatement BASE_EMBEDDED { | 109 class NestedStatement BASE_EMBEDDED { |
110 public: | 110 public: |
111 explicit NestedStatement(FullCodeGenerator* codegen) : codegen_(codegen) { | 111 explicit NestedStatement(FullCodeGenerator* codegen) |
| 112 : codegen_(codegen), |
| 113 stack_depth_at_target_(codegen->operand_stack_depth_) { |
112 // Link into codegen's nesting stack. | 114 // Link into codegen's nesting stack. |
113 previous_ = codegen->nesting_stack_; | 115 previous_ = codegen->nesting_stack_; |
114 codegen->nesting_stack_ = this; | 116 codegen->nesting_stack_ = this; |
115 } | 117 } |
116 virtual ~NestedStatement() { | 118 virtual ~NestedStatement() { |
117 // Unlink from codegen's nesting stack. | 119 // Unlink from codegen's nesting stack. |
118 DCHECK_EQ(this, codegen_->nesting_stack_); | 120 DCHECK_EQ(this, codegen_->nesting_stack_); |
119 codegen_->nesting_stack_ = previous_; | 121 codegen_->nesting_stack_ = previous_; |
120 } | 122 } |
121 | 123 |
122 virtual Breakable* AsBreakable() { return nullptr; } | 124 virtual Breakable* AsBreakable() { return nullptr; } |
123 virtual Iteration* AsIteration() { return nullptr; } | 125 virtual Iteration* AsIteration() { return nullptr; } |
124 virtual TryFinally* AsTryFinally() { return nullptr; } | 126 virtual TryFinally* AsTryFinally() { return nullptr; } |
125 | 127 |
126 virtual bool IsContinueTarget(Statement* target) { return false; } | 128 virtual bool IsContinueTarget(Statement* target) { return false; } |
127 virtual bool IsBreakTarget(Statement* target) { return false; } | 129 virtual bool IsBreakTarget(Statement* target) { return false; } |
128 virtual bool IsTryFinally() { return false; } | 130 virtual bool IsTryFinally() { return false; } |
129 | 131 |
130 // Notify the statement that we are exiting it via break, continue, or | 132 // Notify the statement that we are exiting it via break, continue, or |
131 // return and give it a chance to generate cleanup code. Return the | 133 // return and give it a chance to generate cleanup code. Return the |
132 // next outer statement in the nesting stack. We accumulate in | 134 // next outer statement in the nesting stack. We accumulate in |
133 // *stack_depth the amount to drop the stack and in *context_length the | 135 // {*context_length} the number of context chain links to unwind as we |
134 // number of context chain links to unwind as we traverse the nesting | 136 // traverse the nesting stack from an exit to its target. |
135 // stack from an exit to its target. | 137 virtual NestedStatement* Exit(int* context_length) { return previous_; } |
136 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { | 138 |
137 return previous_; | 139 // Determine the expected operand stack depth when this statement is being |
138 } | 140 // used as the target of an exit. The caller will drop to this depth. |
| 141 int GetStackDepthAtTarget() { return stack_depth_at_target_; } |
139 | 142 |
140 protected: | 143 protected: |
141 MacroAssembler* masm() { return codegen_->masm(); } | 144 MacroAssembler* masm() { return codegen_->masm(); } |
142 | 145 |
143 FullCodeGenerator* codegen_; | 146 FullCodeGenerator* codegen_; |
144 NestedStatement* previous_; | 147 NestedStatement* previous_; |
| 148 int stack_depth_at_target_; |
145 | 149 |
146 private: | 150 private: |
147 DISALLOW_COPY_AND_ASSIGN(NestedStatement); | 151 DISALLOW_COPY_AND_ASSIGN(NestedStatement); |
148 }; | 152 }; |
149 | 153 |
150 // A breakable statement such as a block. | 154 // A breakable statement such as a block. |
151 class Breakable : public NestedStatement { | 155 class Breakable : public NestedStatement { |
152 public: | 156 public: |
153 Breakable(FullCodeGenerator* codegen, BreakableStatement* statement) | 157 Breakable(FullCodeGenerator* codegen, BreakableStatement* statement) |
154 : NestedStatement(codegen), statement_(statement) { | 158 : NestedStatement(codegen), statement_(statement) { |
(...skipping 30 matching lines...) Expand all Loading... |
185 Label continue_label_; | 189 Label continue_label_; |
186 }; | 190 }; |
187 | 191 |
188 // A nested block statement. | 192 // A nested block statement. |
189 class NestedBlock : public Breakable { | 193 class NestedBlock : public Breakable { |
190 public: | 194 public: |
191 NestedBlock(FullCodeGenerator* codegen, Block* block) | 195 NestedBlock(FullCodeGenerator* codegen, Block* block) |
192 : Breakable(codegen, block) { | 196 : Breakable(codegen, block) { |
193 } | 197 } |
194 | 198 |
195 NestedStatement* Exit(int* stack_depth, int* context_length) override { | 199 NestedStatement* Exit(int* context_length) override { |
196 auto block_scope = statement()->AsBlock()->scope(); | 200 auto block_scope = statement()->AsBlock()->scope(); |
197 if (block_scope != nullptr) { | 201 if (block_scope != nullptr) { |
198 if (block_scope->ContextLocalCount() > 0) ++(*context_length); | 202 if (block_scope->ContextLocalCount() > 0) ++(*context_length); |
199 } | 203 } |
200 return previous_; | 204 return previous_; |
201 } | 205 } |
202 }; | 206 }; |
203 | 207 |
204 // The try block of a try/catch statement. | |
205 class TryCatch : public NestedStatement { | |
206 public: | |
207 static const int kElementCount = TryBlockConstant::kElementCount; | |
208 | |
209 explicit TryCatch(FullCodeGenerator* codegen) : NestedStatement(codegen) {} | |
210 | |
211 NestedStatement* Exit(int* stack_depth, int* context_length) override { | |
212 *stack_depth += kElementCount; | |
213 return previous_; | |
214 } | |
215 }; | |
216 | |
217 class DeferredCommands { | 208 class DeferredCommands { |
218 public: | 209 public: |
219 enum Command { kReturn, kThrow, kBreak, kContinue }; | 210 enum Command { kReturn, kThrow, kBreak, kContinue }; |
220 typedef int TokenId; | 211 typedef int TokenId; |
221 struct DeferredCommand { | 212 struct DeferredCommand { |
222 Command command; | 213 Command command; |
223 TokenId token; | 214 TokenId token; |
224 Statement* target; | 215 Statement* target; |
225 }; | 216 }; |
226 | 217 |
(...skipping 20 matching lines...) Expand all Loading... |
247 ZoneVector<DeferredCommand> commands_; | 238 ZoneVector<DeferredCommand> commands_; |
248 TokenDispenserForFinally dispenser_; | 239 TokenDispenserForFinally dispenser_; |
249 TokenId return_token_; | 240 TokenId return_token_; |
250 TokenId throw_token_; | 241 TokenId throw_token_; |
251 Label* finally_entry_; | 242 Label* finally_entry_; |
252 }; | 243 }; |
253 | 244 |
254 // The try block of a try/finally statement. | 245 // The try block of a try/finally statement. |
255 class TryFinally : public NestedStatement { | 246 class TryFinally : public NestedStatement { |
256 public: | 247 public: |
257 static const int kElementCount = TryBlockConstant::kElementCount; | |
258 | |
259 TryFinally(FullCodeGenerator* codegen, DeferredCommands* commands) | 248 TryFinally(FullCodeGenerator* codegen, DeferredCommands* commands) |
260 : NestedStatement(codegen), deferred_commands_(commands) {} | 249 : NestedStatement(codegen), deferred_commands_(commands) {} |
261 | 250 |
262 NestedStatement* Exit(int* stack_depth, int* context_length) override; | 251 NestedStatement* Exit(int* context_length) override; |
263 | 252 |
264 bool IsTryFinally() override { return true; } | 253 bool IsTryFinally() override { return true; } |
265 TryFinally* AsTryFinally() override { return this; } | 254 TryFinally* AsTryFinally() override { return this; } |
266 | 255 |
267 DeferredCommands* deferred_commands() { return deferred_commands_; } | 256 DeferredCommands* deferred_commands() { return deferred_commands_; } |
268 | 257 |
269 private: | 258 private: |
270 DeferredCommands* deferred_commands_; | 259 DeferredCommands* deferred_commands_; |
271 }; | 260 }; |
272 | 261 |
273 // The finally block of a try/finally statement. | |
274 class Finally : public NestedStatement { | |
275 public: | |
276 static const int kElementCount = 3; | |
277 | |
278 explicit Finally(FullCodeGenerator* codegen) : NestedStatement(codegen) {} | |
279 | |
280 NestedStatement* Exit(int* stack_depth, int* context_length) override { | |
281 *stack_depth += kElementCount; | |
282 return previous_; | |
283 } | |
284 }; | |
285 | |
286 // The body of a for/in loop. | |
287 class ForIn : public Iteration { | |
288 public: | |
289 static const int kElementCount = 5; | |
290 | |
291 ForIn(FullCodeGenerator* codegen, ForInStatement* statement) | |
292 : Iteration(codegen, statement) { | |
293 } | |
294 | |
295 NestedStatement* Exit(int* stack_depth, int* context_length) override { | |
296 *stack_depth += kElementCount; | |
297 return previous_; | |
298 } | |
299 }; | |
300 | |
301 | |
302 // The body of a with or catch. | 262 // The body of a with or catch. |
303 class WithOrCatch : public NestedStatement { | 263 class WithOrCatch : public NestedStatement { |
304 public: | 264 public: |
305 explicit WithOrCatch(FullCodeGenerator* codegen) | 265 explicit WithOrCatch(FullCodeGenerator* codegen) |
306 : NestedStatement(codegen) { | 266 : NestedStatement(codegen) { |
307 } | 267 } |
308 | 268 |
309 NestedStatement* Exit(int* stack_depth, int* context_length) override { | 269 NestedStatement* Exit(int* context_length) override { |
310 ++(*context_length); | 270 ++(*context_length); |
311 return previous_; | 271 return previous_; |
312 } | 272 } |
313 }; | 273 }; |
314 | 274 |
315 // A platform-specific utility to overwrite the accumulator register | 275 // A platform-specific utility to overwrite the accumulator register |
316 // with a GC-safe value. | 276 // with a GC-safe value. |
317 void ClearAccumulator(); | 277 void ClearAccumulator(); |
318 | 278 |
319 // Determine whether or not to inline the smi case for the given | 279 // Determine whether or not to inline the smi case for the given |
(...skipping 777 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1097 Address start_; | 1057 Address start_; |
1098 Address instruction_start_; | 1058 Address instruction_start_; |
1099 uint32_t length_; | 1059 uint32_t length_; |
1100 }; | 1060 }; |
1101 | 1061 |
1102 | 1062 |
1103 } // namespace internal | 1063 } // namespace internal |
1104 } // namespace v8 | 1064 } // namespace v8 |
1105 | 1065 |
1106 #endif // V8_FULL_CODEGEN_FULL_CODEGEN_H_ | 1066 #endif // V8_FULL_CODEGEN_FULL_CODEGEN_H_ |
OLD | NEW |