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 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 } | 108 } |
109 | 109 |
110 private: | 110 private: |
111 class Breakable; | 111 class Breakable; |
112 class Iteration; | 112 class Iteration; |
113 | 113 |
114 class TestContext; | 114 class TestContext; |
115 | 115 |
116 class NestedStatement BASE_EMBEDDED { | 116 class NestedStatement BASE_EMBEDDED { |
117 public: | 117 public: |
118 explicit NestedStatement(FullCodeGenerator* codegen) : codegen_(codegen) { | 118 NestedStatement(FullCodeGenerator* codegen, int stack_delta); |
119 // Link into codegen's nesting stack. | |
120 previous_ = codegen->nesting_stack_; | |
121 codegen->nesting_stack_ = this; | |
122 } | |
123 virtual ~NestedStatement() { | 119 virtual ~NestedStatement() { |
124 // Unlink from codegen's nesting stack. | 120 // Unlink from codegen's nesting stack. |
125 ASSERT_EQ(this, codegen_->nesting_stack_); | 121 ASSERT_EQ(this, codegen_->nesting_stack_); |
126 codegen_->nesting_stack_ = previous_; | 122 codegen_->nesting_stack_ = previous_; |
127 } | 123 } |
128 | 124 |
129 virtual Breakable* AsBreakable() { return NULL; } | 125 virtual Breakable* AsBreakable() { return NULL; } |
130 virtual Iteration* AsIteration() { return NULL; } | 126 virtual Iteration* AsIteration() { return NULL; } |
131 | 127 |
132 virtual bool IsContinueTarget(Statement* target) { return false; } | 128 virtual bool IsContinueTarget(Statement* target) { return false; } |
133 virtual bool IsBreakTarget(Statement* target) { return false; } | 129 virtual bool IsBreakTarget(Statement* target) { return false; } |
134 | 130 |
135 // Notify the statement that we are exiting it via break, continue, or | 131 // Notify the statement that we are exiting it via break, continue, or |
136 // return and give it a chance to generate cleanup code. Return the | 132 // return and give it a chance to generate cleanup code. Return the |
137 // next outer statement in the nesting stack. We accumulate in | 133 // next outer statement in the nesting stack. We accumulate in |
138 // *stack_depth the amount to drop the stack and in *context_length the | 134 // *stack_depth the amount to drop the stack and in *context_length the |
139 // number of context chain links to unwind as we traverse the nesting | 135 // number of context chain links to unwind as we traverse the nesting |
140 // stack from an exit to its target. | 136 // stack from an exit to its target. |
141 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { | 137 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { |
| 138 *stack_depth += stack_delta_; |
142 return previous_; | 139 return previous_; |
143 } | 140 } |
144 | 141 |
| 142 // The depth of the stack of block local variables and handlers |
| 143 // above the locals during the execution of this nested statement. |
| 144 int StackDepth() const { return stack_depth_; } |
| 145 // The depth of the stack before and after executing this nested statement. |
| 146 int StackDepthBase() const { return stack_depth_ - stack_delta_; } |
| 147 |
145 protected: | 148 protected: |
146 MacroAssembler* masm() { return codegen_->masm(); } | 149 MacroAssembler* masm() { return codegen_->masm(); } |
147 | 150 |
148 FullCodeGenerator* codegen_; | 151 FullCodeGenerator* codegen_; |
149 NestedStatement* previous_; | 152 NestedStatement* previous_; |
| 153 int stack_depth_; |
| 154 int stack_delta_; |
150 DISALLOW_COPY_AND_ASSIGN(NestedStatement); | 155 DISALLOW_COPY_AND_ASSIGN(NestedStatement); |
151 }; | 156 }; |
152 | 157 |
153 // A breakable statement such as a block. | 158 // A breakable statement such as a block. |
154 class Breakable : public NestedStatement { | 159 class Breakable : public NestedStatement { |
155 public: | 160 public: |
156 Breakable(FullCodeGenerator* codegen, BreakableStatement* statement) | 161 Breakable(FullCodeGenerator* codegen, |
157 : NestedStatement(codegen), statement_(statement) { | 162 BreakableStatement* statement, |
| 163 int stack_delta = 0) |
| 164 : NestedStatement(codegen, stack_delta), statement_(statement) { |
158 } | 165 } |
159 virtual ~Breakable() {} | 166 virtual ~Breakable() {} |
160 | 167 |
161 virtual Breakable* AsBreakable() { return this; } | 168 virtual Breakable* AsBreakable() { return this; } |
162 virtual bool IsBreakTarget(Statement* target) { | 169 virtual bool IsBreakTarget(Statement* target) { |
163 return statement() == target; | 170 return statement() == target; |
164 } | 171 } |
165 | 172 |
166 BreakableStatement* statement() { return statement_; } | 173 BreakableStatement* statement() { return statement_; } |
167 Label* break_label() { return &break_label_; } | 174 Label* break_label() { return &break_label_; } |
168 | 175 |
169 private: | 176 private: |
170 BreakableStatement* statement_; | 177 BreakableStatement* statement_; |
171 Label break_label_; | 178 Label break_label_; |
172 }; | 179 }; |
173 | 180 |
174 // An iteration statement such as a while, for, or do loop. | 181 // An iteration statement such as a while, for, or do loop. |
175 class Iteration : public Breakable { | 182 class Iteration : public Breakable { |
176 public: | 183 public: |
177 Iteration(FullCodeGenerator* codegen, IterationStatement* statement) | 184 Iteration(FullCodeGenerator* codegen, |
178 : Breakable(codegen, statement) { | 185 IterationStatement* statement, |
| 186 int stack_delta = 0) |
| 187 : Breakable(codegen, statement, stack_delta) { |
179 } | 188 } |
180 virtual ~Iteration() {} | 189 virtual ~Iteration() {} |
181 | 190 |
182 virtual Iteration* AsIteration() { return this; } | 191 virtual Iteration* AsIteration() { return this; } |
183 virtual bool IsContinueTarget(Statement* target) { | 192 virtual bool IsContinueTarget(Statement* target) { |
184 return statement() == target; | 193 return statement() == target; |
185 } | 194 } |
186 | 195 |
187 Label* continue_label() { return &continue_label_; } | 196 Label* continue_label() { return &continue_label_; } |
188 | 197 |
189 private: | 198 private: |
190 Label continue_label_; | 199 Label continue_label_; |
191 }; | 200 }; |
192 | 201 |
193 // A nested block statement. | 202 // A nested block statement. |
194 class NestedBlock : public Breakable { | 203 class NestedBlock : public Breakable { |
195 public: | 204 public: |
196 NestedBlock(FullCodeGenerator* codegen, Block* block) | 205 NestedBlock(FullCodeGenerator* codegen, Block* block); |
197 : Breakable(codegen, block) { | 206 |
198 } | |
199 virtual ~NestedBlock() {} | 207 virtual ~NestedBlock() {} |
200 | 208 |
201 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { | 209 virtual NestedStatement* Exit(int* stack_depth, int* context_length); |
202 if (statement()->AsBlock()->block_scope() != NULL) { | |
203 ++(*context_length); | |
204 } | |
205 return previous_; | |
206 }; | |
207 }; | 210 }; |
208 | 211 |
209 // The try block of a try/catch statement. | 212 // The try block of a try/catch statement. |
210 class TryCatch : public NestedStatement { | 213 class TryCatch : public NestedStatement { |
211 public: | 214 public: |
212 explicit TryCatch(FullCodeGenerator* codegen) : NestedStatement(codegen) { | 215 static const int kElementCount = |
| 216 StackHandlerConstants::kSize / kPointerSize; |
| 217 |
| 218 explicit TryCatch(FullCodeGenerator* codegen) |
| 219 : NestedStatement(codegen, kElementCount) { |
213 } | 220 } |
214 virtual ~TryCatch() {} | 221 virtual ~TryCatch() {} |
215 | 222 |
216 virtual NestedStatement* Exit(int* stack_depth, int* context_length); | 223 virtual NestedStatement* Exit(int* stack_depth, int* context_length); |
217 }; | 224 }; |
218 | 225 |
219 // The try block of a try/finally statement. | 226 // The try block of a try/finally statement. |
220 class TryFinally : public NestedStatement { | 227 class TryFinally : public NestedStatement { |
221 public: | 228 public: |
| 229 static const int kElementCount = 5; |
| 230 |
222 TryFinally(FullCodeGenerator* codegen, Label* finally_entry) | 231 TryFinally(FullCodeGenerator* codegen, Label* finally_entry) |
223 : NestedStatement(codegen), finally_entry_(finally_entry) { | 232 : NestedStatement(codegen, kElementCount), |
| 233 finally_entry_(finally_entry) { |
224 } | 234 } |
225 virtual ~TryFinally() {} | 235 virtual ~TryFinally() {} |
226 | 236 |
227 virtual NestedStatement* Exit(int* stack_depth, int* context_length); | 237 virtual NestedStatement* Exit(int* stack_depth, int* context_length); |
228 | 238 |
229 private: | 239 private: |
230 Label* finally_entry_; | 240 Label* finally_entry_; |
231 }; | 241 }; |
232 | 242 |
233 // The finally block of a try/finally statement. | 243 // The finally block of a try/finally statement. |
234 class Finally : public NestedStatement { | 244 class Finally : public NestedStatement { |
235 public: | 245 public: |
236 static const int kElementCount = 2; | 246 static const int kElementCount = 2; |
237 | 247 |
238 explicit Finally(FullCodeGenerator* codegen) : NestedStatement(codegen) { } | 248 explicit Finally(FullCodeGenerator* codegen) |
| 249 : NestedStatement(codegen, kElementCount) { } |
239 virtual ~Finally() {} | 250 virtual ~Finally() {} |
240 | |
241 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { | |
242 *stack_depth += kElementCount; | |
243 return previous_; | |
244 } | |
245 }; | 251 }; |
246 | 252 |
247 // The body of a for/in loop. | 253 // The body of a for/in loop. |
248 class ForIn : public Iteration { | 254 class ForIn : public Iteration { |
249 public: | 255 public: |
250 static const int kElementCount = 5; | 256 static const int kElementCount = 5; |
251 | 257 |
252 ForIn(FullCodeGenerator* codegen, ForInStatement* statement) | 258 ForIn(FullCodeGenerator* codegen, ForInStatement* statement) |
253 : Iteration(codegen, statement) { | 259 : Iteration(codegen, statement, kElementCount) { |
254 } | 260 } |
255 virtual ~ForIn() {} | 261 virtual ~ForIn() {} |
256 | |
257 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { | |
258 *stack_depth += kElementCount; | |
259 return previous_; | |
260 } | |
261 }; | 262 }; |
262 | 263 |
263 | 264 |
264 // The body of a with or catch. | 265 // The body of a with or catch. |
265 class WithOrCatch : public NestedStatement { | 266 class WithOrCatch : public NestedStatement { |
266 public: | 267 public: |
267 explicit WithOrCatch(FullCodeGenerator* codegen) | 268 explicit WithOrCatch(FullCodeGenerator* codegen) |
268 : NestedStatement(codegen) { | 269 : NestedStatement(codegen, 0) { |
269 } | 270 } |
270 virtual ~WithOrCatch() {} | 271 virtual ~WithOrCatch() {} |
271 | 272 |
272 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { | 273 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { |
273 ++(*context_length); | 274 ++(*context_length); |
274 return previous_; | 275 return previous_; |
275 } | 276 } |
276 }; | 277 }; |
277 | 278 |
278 // Type of a member function that generates inline code for a native function. | 279 // Type of a member function that generates inline code for a native function. |
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
761 | 762 |
762 friend class NestedStatement; | 763 friend class NestedStatement; |
763 | 764 |
764 DISALLOW_COPY_AND_ASSIGN(FullCodeGenerator); | 765 DISALLOW_COPY_AND_ASSIGN(FullCodeGenerator); |
765 }; | 766 }; |
766 | 767 |
767 | 768 |
768 } } // namespace v8::internal | 769 } } // namespace v8::internal |
769 | 770 |
770 #endif // V8_FULL_CODEGEN_H_ | 771 #endif // V8_FULL_CODEGEN_H_ |
OLD | NEW |