OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 virtual Breakable* AsBreakable() { return NULL; } | 133 virtual Breakable* AsBreakable() { return NULL; } |
134 virtual Iteration* AsIteration() { return NULL; } | 134 virtual Iteration* AsIteration() { return NULL; } |
135 virtual TryCatch* AsTryCatch() { return NULL; } | 135 virtual TryCatch* AsTryCatch() { return NULL; } |
136 virtual TryFinally* AsTryFinally() { return NULL; } | 136 virtual TryFinally* AsTryFinally() { return NULL; } |
137 virtual Finally* AsFinally() { return NULL; } | 137 virtual Finally* AsFinally() { return NULL; } |
138 virtual ForIn* AsForIn() { return NULL; } | 138 virtual ForIn* AsForIn() { return NULL; } |
139 | 139 |
140 virtual bool IsContinueTarget(Statement* target) { return false; } | 140 virtual bool IsContinueTarget(Statement* target) { return false; } |
141 virtual bool IsBreakTarget(Statement* target) { return false; } | 141 virtual bool IsBreakTarget(Statement* target) { return false; } |
142 | 142 |
143 // Generate code to leave the nested statement. This includes | 143 // Notify the statement that we are exiting it via break, continue, or |
144 // cleaning up any stack elements in use and restoring the | 144 // return and give it a chance to generate cleanup code. Return the |
145 // stack to the expectations of the surrounding statements. | 145 // next outer statement in the nesting stack. We accumulate in |
146 // Takes a number of stack elements currently on top of the | 146 // *stack_depth the amount to drop the stack and in *context_length the |
147 // nested statement's stack, and returns a number of stack | 147 // number of context chain links to unwind as we traverse the nesting |
148 // elements left on top of the surrounding statement's stack. | 148 // stack from an exit to its target. |
149 // The generated code must preserve the result register (which | 149 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { |
150 // contains the value in case of a return). | 150 return previous_; |
151 virtual int Exit(int stack_depth) { | |
152 // Default implementation for the case where there is | |
153 // nothing to clean up. | |
154 return stack_depth; | |
155 } | 151 } |
156 NestedStatement* outer() { return previous_; } | |
157 | 152 |
158 protected: | 153 protected: |
159 MacroAssembler* masm() { return codegen_->masm(); } | 154 MacroAssembler* masm() { return codegen_->masm(); } |
160 | 155 |
161 private: | |
162 FullCodeGenerator* codegen_; | 156 FullCodeGenerator* codegen_; |
163 NestedStatement* previous_; | 157 NestedStatement* previous_; |
164 DISALLOW_COPY_AND_ASSIGN(NestedStatement); | 158 DISALLOW_COPY_AND_ASSIGN(NestedStatement); |
165 }; | 159 }; |
166 | 160 |
167 class Breakable : public NestedStatement { | 161 class Breakable : public NestedStatement { |
168 public: | 162 public: |
169 Breakable(FullCodeGenerator* codegen, | 163 Breakable(FullCodeGenerator* codegen, |
170 BreakableStatement* break_target) | 164 BreakableStatement* break_target) |
171 : NestedStatement(codegen), | 165 : NestedStatement(codegen), |
(...skipping 28 matching lines...) Expand all Loading... |
200 }; | 194 }; |
201 | 195 |
202 // The environment inside the try block of a try/catch statement. | 196 // The environment inside the try block of a try/catch statement. |
203 class TryCatch : public NestedStatement { | 197 class TryCatch : public NestedStatement { |
204 public: | 198 public: |
205 explicit TryCatch(FullCodeGenerator* codegen, Label* catch_entry) | 199 explicit TryCatch(FullCodeGenerator* codegen, Label* catch_entry) |
206 : NestedStatement(codegen), catch_entry_(catch_entry) { } | 200 : NestedStatement(codegen), catch_entry_(catch_entry) { } |
207 virtual ~TryCatch() {} | 201 virtual ~TryCatch() {} |
208 virtual TryCatch* AsTryCatch() { return this; } | 202 virtual TryCatch* AsTryCatch() { return this; } |
209 Label* catch_entry() { return catch_entry_; } | 203 Label* catch_entry() { return catch_entry_; } |
210 virtual int Exit(int stack_depth); | 204 virtual NestedStatement* Exit(int* stack_depth, int* context_length); |
211 private: | 205 private: |
212 Label* catch_entry_; | 206 Label* catch_entry_; |
213 DISALLOW_COPY_AND_ASSIGN(TryCatch); | 207 DISALLOW_COPY_AND_ASSIGN(TryCatch); |
214 }; | 208 }; |
215 | 209 |
216 // The environment inside the try block of a try/finally statement. | 210 // The environment inside the try block of a try/finally statement. |
217 class TryFinally : public NestedStatement { | 211 class TryFinally : public NestedStatement { |
218 public: | 212 public: |
219 explicit TryFinally(FullCodeGenerator* codegen, Label* finally_entry) | 213 explicit TryFinally(FullCodeGenerator* codegen, Label* finally_entry) |
220 : NestedStatement(codegen), finally_entry_(finally_entry) { } | 214 : NestedStatement(codegen), finally_entry_(finally_entry) { } |
221 virtual ~TryFinally() {} | 215 virtual ~TryFinally() {} |
222 virtual TryFinally* AsTryFinally() { return this; } | 216 virtual TryFinally* AsTryFinally() { return this; } |
223 Label* finally_entry() { return finally_entry_; } | 217 Label* finally_entry() { return finally_entry_; } |
224 virtual int Exit(int stack_depth); | 218 virtual NestedStatement* Exit(int* stack_depth, int* context_length); |
225 private: | 219 private: |
226 Label* finally_entry_; | 220 Label* finally_entry_; |
227 DISALLOW_COPY_AND_ASSIGN(TryFinally); | 221 DISALLOW_COPY_AND_ASSIGN(TryFinally); |
228 }; | 222 }; |
229 | 223 |
230 // A FinallyEnvironment represents being inside a finally block. | 224 // A FinallyEnvironment represents being inside a finally block. |
231 // Abnormal termination of the finally block needs to clean up | 225 // Abnormal termination of the finally block needs to clean up |
232 // the block's parameters from the stack. | 226 // the block's parameters from the stack. |
233 class Finally : public NestedStatement { | 227 class Finally : public NestedStatement { |
234 public: | 228 public: |
235 explicit Finally(FullCodeGenerator* codegen) : NestedStatement(codegen) { } | 229 explicit Finally(FullCodeGenerator* codegen) : NestedStatement(codegen) { } |
236 virtual ~Finally() {} | 230 virtual ~Finally() {} |
237 virtual Finally* AsFinally() { return this; } | 231 virtual Finally* AsFinally() { return this; } |
238 virtual int Exit(int stack_depth) { | 232 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { |
239 return stack_depth + kFinallyStackElementCount; | 233 *stack_depth += kFinallyStackElementCount; |
| 234 return previous_; |
240 } | 235 } |
241 private: | 236 private: |
242 // Number of extra stack slots occupied during a finally block. | 237 // Number of extra stack slots occupied during a finally block. |
243 static const int kFinallyStackElementCount = 2; | 238 static const int kFinallyStackElementCount = 2; |
244 DISALLOW_COPY_AND_ASSIGN(Finally); | 239 DISALLOW_COPY_AND_ASSIGN(Finally); |
245 }; | 240 }; |
246 | 241 |
247 // A ForInEnvironment represents being inside a for-in loop. | 242 // A ForInEnvironment represents being inside a for-in loop. |
248 // Abnormal termination of the for-in block needs to clean up | 243 // Abnormal termination of the for-in block needs to clean up |
249 // the block's temporary storage from the stack. | 244 // the block's temporary storage from the stack. |
250 class ForIn : public Iteration { | 245 class ForIn : public Iteration { |
251 public: | 246 public: |
252 ForIn(FullCodeGenerator* codegen, | 247 ForIn(FullCodeGenerator* codegen, |
253 ForInStatement* statement) | 248 ForInStatement* statement) |
254 : Iteration(codegen, statement) { } | 249 : Iteration(codegen, statement) { } |
255 virtual ~ForIn() {} | 250 virtual ~ForIn() {} |
256 virtual ForIn* AsForIn() { return this; } | 251 virtual ForIn* AsForIn() { return this; } |
257 virtual int Exit(int stack_depth) { | 252 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { |
258 return stack_depth + kForInStackElementCount; | 253 *stack_depth += kForInStackElementCount; |
| 254 return previous_; |
259 } | 255 } |
260 private: | 256 private: |
261 static const int kForInStackElementCount = 5; | 257 static const int kForInStackElementCount = 5; |
262 DISALLOW_COPY_AND_ASSIGN(ForIn); | 258 DISALLOW_COPY_AND_ASSIGN(ForIn); |
263 }; | 259 }; |
264 | 260 |
| 261 |
| 262 // A WithOrCatch represents being inside the body of a with or catch |
| 263 // statement. Exiting the body needs to remove a link from the context |
| 264 // chain. |
| 265 class WithOrCatch : public NestedStatement { |
| 266 public: |
| 267 explicit WithOrCatch(FullCodeGenerator* codegen) |
| 268 : NestedStatement(codegen) { |
| 269 } |
| 270 virtual ~WithOrCatch() {} |
| 271 |
| 272 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { |
| 273 ++(*context_length); |
| 274 return previous_; |
| 275 } |
| 276 }; |
| 277 |
265 // The forward bailout stack keeps track of the expressions that can | 278 // The forward bailout stack keeps track of the expressions that can |
266 // bail out to just before the control flow is split in a child | 279 // bail out to just before the control flow is split in a child |
267 // node. The stack elements are linked together through the parent | 280 // node. The stack elements are linked together through the parent |
268 // link when visiting expressions in test contexts after requesting | 281 // link when visiting expressions in test contexts after requesting |
269 // bailout in child forwarding. | 282 // bailout in child forwarding. |
270 class ForwardBailoutStack BASE_EMBEDDED { | 283 class ForwardBailoutStack BASE_EMBEDDED { |
271 public: | 284 public: |
272 ForwardBailoutStack(Expression* expr, ForwardBailoutStack* parent) | 285 ForwardBailoutStack(Expression* expr, ForwardBailoutStack* parent) |
273 : expr_(expr), parent_(parent) { } | 286 : expr_(expr), parent_(parent) { } |
274 | 287 |
(...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
804 | 817 |
805 friend class NestedStatement; | 818 friend class NestedStatement; |
806 | 819 |
807 DISALLOW_COPY_AND_ASSIGN(FullCodeGenerator); | 820 DISALLOW_COPY_AND_ASSIGN(FullCodeGenerator); |
808 }; | 821 }; |
809 | 822 |
810 | 823 |
811 } } // namespace v8::internal | 824 } } // namespace v8::internal |
812 | 825 |
813 #endif // V8_FULL_CODEGEN_H_ | 826 #endif // V8_FULL_CODEGEN_H_ |
OLD | NEW |