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 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 case NO_REGISTERS: return "NO_REGISTERS"; | 104 case NO_REGISTERS: return "NO_REGISTERS"; |
105 case TOS_REG: return "TOS_REG"; | 105 case TOS_REG: return "TOS_REG"; |
106 } | 106 } |
107 UNREACHABLE(); | 107 UNREACHABLE(); |
108 return NULL; | 108 return NULL; |
109 } | 109 } |
110 | 110 |
111 private: | 111 private: |
112 class Breakable; | 112 class Breakable; |
113 class Iteration; | 113 class Iteration; |
114 class TryCatch; | 114 |
115 class TryFinally; | |
116 class Finally; | |
117 class ForIn; | |
118 class TestContext; | 115 class TestContext; |
119 | 116 |
120 class NestedStatement BASE_EMBEDDED { | 117 class NestedStatement BASE_EMBEDDED { |
121 public: | 118 public: |
122 explicit NestedStatement(FullCodeGenerator* codegen) : codegen_(codegen) { | 119 explicit NestedStatement(FullCodeGenerator* codegen) : codegen_(codegen) { |
123 // Link into codegen's nesting stack. | 120 // Link into codegen's nesting stack. |
124 previous_ = codegen->nesting_stack_; | 121 previous_ = codegen->nesting_stack_; |
125 codegen->nesting_stack_ = this; | 122 codegen->nesting_stack_ = this; |
126 } | 123 } |
127 virtual ~NestedStatement() { | 124 virtual ~NestedStatement() { |
128 // Unlink from codegen's nesting stack. | 125 // Unlink from codegen's nesting stack. |
129 ASSERT_EQ(this, codegen_->nesting_stack_); | 126 ASSERT_EQ(this, codegen_->nesting_stack_); |
130 codegen_->nesting_stack_ = previous_; | 127 codegen_->nesting_stack_ = previous_; |
131 } | 128 } |
132 | 129 |
133 virtual Breakable* AsBreakable() { return NULL; } | 130 virtual Breakable* AsBreakable() { return NULL; } |
134 virtual Iteration* AsIteration() { return NULL; } | 131 virtual Iteration* AsIteration() { return NULL; } |
135 virtual TryCatch* AsTryCatch() { return NULL; } | |
136 virtual TryFinally* AsTryFinally() { return NULL; } | |
137 virtual Finally* AsFinally() { return NULL; } | |
138 virtual ForIn* AsForIn() { return NULL; } | |
139 | 132 |
140 virtual bool IsContinueTarget(Statement* target) { return false; } | 133 virtual bool IsContinueTarget(Statement* target) { return false; } |
141 virtual bool IsBreakTarget(Statement* target) { return false; } | 134 virtual bool IsBreakTarget(Statement* target) { return false; } |
142 | 135 |
143 // Notify the statement that we are exiting it via break, continue, or | 136 // Notify the statement that we are exiting it via break, continue, or |
144 // return and give it a chance to generate cleanup code. Return the | 137 // return and give it a chance to generate cleanup code. Return the |
145 // next outer statement in the nesting stack. We accumulate in | 138 // next outer statement in the nesting stack. We accumulate in |
146 // *stack_depth the amount to drop the stack and in *context_length the | 139 // *stack_depth the amount to drop the stack and in *context_length the |
147 // number of context chain links to unwind as we traverse the nesting | 140 // number of context chain links to unwind as we traverse the nesting |
148 // stack from an exit to its target. | 141 // stack from an exit to its target. |
149 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { | 142 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { |
150 return previous_; | 143 return previous_; |
151 } | 144 } |
152 | 145 |
153 protected: | 146 protected: |
154 MacroAssembler* masm() { return codegen_->masm(); } | 147 MacroAssembler* masm() { return codegen_->masm(); } |
155 | 148 |
156 FullCodeGenerator* codegen_; | 149 FullCodeGenerator* codegen_; |
157 NestedStatement* previous_; | 150 NestedStatement* previous_; |
158 DISALLOW_COPY_AND_ASSIGN(NestedStatement); | 151 DISALLOW_COPY_AND_ASSIGN(NestedStatement); |
159 }; | 152 }; |
160 | 153 |
| 154 // A breakable statement such as a block. |
161 class Breakable : public NestedStatement { | 155 class Breakable : public NestedStatement { |
162 public: | 156 public: |
163 Breakable(FullCodeGenerator* codegen, | 157 Breakable(FullCodeGenerator* codegen, BreakableStatement* statement) |
164 BreakableStatement* break_target) | 158 : NestedStatement(codegen), statement_(statement) { |
165 : NestedStatement(codegen), | 159 } |
166 target_(break_target) {} | |
167 virtual ~Breakable() {} | 160 virtual ~Breakable() {} |
| 161 |
168 virtual Breakable* AsBreakable() { return this; } | 162 virtual Breakable* AsBreakable() { return this; } |
169 virtual bool IsBreakTarget(Statement* statement) { | 163 virtual bool IsBreakTarget(Statement* target) { |
170 return target_ == statement; | 164 return statement() == target; |
171 } | 165 } |
172 BreakableStatement* statement() { return target_; } | 166 |
173 Label* break_target() { return &break_target_label_; } | 167 BreakableStatement* statement() { return statement_; } |
| 168 Label* break_label() { return &break_label_; } |
| 169 |
174 private: | 170 private: |
175 BreakableStatement* target_; | 171 BreakableStatement* statement_; |
176 Label break_target_label_; | 172 Label break_label_; |
177 DISALLOW_COPY_AND_ASSIGN(Breakable); | |
178 }; | 173 }; |
179 | 174 |
| 175 // An iteration statement such as a while, for, or do loop. |
180 class Iteration : public Breakable { | 176 class Iteration : public Breakable { |
181 public: | 177 public: |
182 Iteration(FullCodeGenerator* codegen, | 178 Iteration(FullCodeGenerator* codegen, IterationStatement* statement) |
183 IterationStatement* iteration_statement) | 179 : Breakable(codegen, statement) { |
184 : Breakable(codegen, iteration_statement) {} | 180 } |
185 virtual ~Iteration() {} | 181 virtual ~Iteration() {} |
| 182 |
186 virtual Iteration* AsIteration() { return this; } | 183 virtual Iteration* AsIteration() { return this; } |
187 virtual bool IsContinueTarget(Statement* statement) { | 184 virtual bool IsContinueTarget(Statement* target) { |
188 return this->statement() == statement; | 185 return statement() == target; |
189 } | 186 } |
190 Label* continue_target() { return &continue_target_label_; } | 187 |
| 188 Label* continue_label() { return &continue_label_; } |
| 189 |
191 private: | 190 private: |
192 Label continue_target_label_; | 191 Label continue_label_; |
193 DISALLOW_COPY_AND_ASSIGN(Iteration); | |
194 }; | 192 }; |
195 | 193 |
196 // The environment inside the try block of a try/catch statement. | 194 // The try block of a try/catch statement. |
197 class TryCatch : public NestedStatement { | 195 class TryCatch : public NestedStatement { |
198 public: | 196 public: |
199 explicit TryCatch(FullCodeGenerator* codegen, Label* catch_entry) | 197 explicit TryCatch(FullCodeGenerator* codegen) : NestedStatement(codegen) { |
200 : NestedStatement(codegen), catch_entry_(catch_entry) { } | 198 } |
201 virtual ~TryCatch() {} | 199 virtual ~TryCatch() {} |
202 virtual TryCatch* AsTryCatch() { return this; } | 200 |
203 Label* catch_entry() { return catch_entry_; } | |
204 virtual NestedStatement* Exit(int* stack_depth, int* context_length); | 201 virtual NestedStatement* Exit(int* stack_depth, int* context_length); |
205 private: | |
206 Label* catch_entry_; | |
207 DISALLOW_COPY_AND_ASSIGN(TryCatch); | |
208 }; | 202 }; |
209 | 203 |
210 // The environment inside the try block of a try/finally statement. | 204 // The try block of a try/finally statement. |
211 class TryFinally : public NestedStatement { | 205 class TryFinally : public NestedStatement { |
212 public: | 206 public: |
213 explicit TryFinally(FullCodeGenerator* codegen, Label* finally_entry) | 207 TryFinally(FullCodeGenerator* codegen, Label* finally_entry) |
214 : NestedStatement(codegen), finally_entry_(finally_entry) { } | 208 : NestedStatement(codegen), finally_entry_(finally_entry) { |
| 209 } |
215 virtual ~TryFinally() {} | 210 virtual ~TryFinally() {} |
216 virtual TryFinally* AsTryFinally() { return this; } | 211 |
217 Label* finally_entry() { return finally_entry_; } | |
218 virtual NestedStatement* Exit(int* stack_depth, int* context_length); | 212 virtual NestedStatement* Exit(int* stack_depth, int* context_length); |
| 213 |
219 private: | 214 private: |
220 Label* finally_entry_; | 215 Label* finally_entry_; |
221 DISALLOW_COPY_AND_ASSIGN(TryFinally); | |
222 }; | 216 }; |
223 | 217 |
224 // A FinallyEnvironment represents being inside a finally block. | 218 // The finally block of a try/finally statement. |
225 // Abnormal termination of the finally block needs to clean up | |
226 // the block's parameters from the stack. | |
227 class Finally : public NestedStatement { | 219 class Finally : public NestedStatement { |
228 public: | 220 public: |
| 221 static const int kElementCount = 2; |
| 222 |
229 explicit Finally(FullCodeGenerator* codegen) : NestedStatement(codegen) { } | 223 explicit Finally(FullCodeGenerator* codegen) : NestedStatement(codegen) { } |
230 virtual ~Finally() {} | 224 virtual ~Finally() {} |
231 virtual Finally* AsFinally() { return this; } | 225 |
232 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { | 226 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { |
233 *stack_depth += kFinallyStackElementCount; | 227 *stack_depth += kElementCount; |
234 return previous_; | 228 return previous_; |
235 } | 229 } |
236 private: | |
237 // Number of extra stack slots occupied during a finally block. | |
238 static const int kFinallyStackElementCount = 2; | |
239 DISALLOW_COPY_AND_ASSIGN(Finally); | |
240 }; | 230 }; |
241 | 231 |
242 // A ForInEnvironment represents being inside a for-in loop. | 232 // The body of a for/in loop. |
243 // Abnormal termination of the for-in block needs to clean up | |
244 // the block's temporary storage from the stack. | |
245 class ForIn : public Iteration { | 233 class ForIn : public Iteration { |
246 public: | 234 public: |
247 ForIn(FullCodeGenerator* codegen, | 235 static const int kElementCount = 5; |
248 ForInStatement* statement) | 236 |
249 : Iteration(codegen, statement) { } | 237 ForIn(FullCodeGenerator* codegen, ForInStatement* statement) |
| 238 : Iteration(codegen, statement) { |
| 239 } |
250 virtual ~ForIn() {} | 240 virtual ~ForIn() {} |
251 virtual ForIn* AsForIn() { return this; } | 241 |
252 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { | 242 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { |
253 *stack_depth += kForInStackElementCount; | 243 *stack_depth += kElementCount; |
254 return previous_; | 244 return previous_; |
255 } | 245 } |
256 private: | |
257 static const int kForInStackElementCount = 5; | |
258 DISALLOW_COPY_AND_ASSIGN(ForIn); | |
259 }; | 246 }; |
260 | 247 |
261 | 248 |
262 // A WithOrCatch represents being inside the body of a with or catch | 249 // 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 { | 250 class WithOrCatch : public NestedStatement { |
266 public: | 251 public: |
267 explicit WithOrCatch(FullCodeGenerator* codegen) | 252 explicit WithOrCatch(FullCodeGenerator* codegen) |
268 : NestedStatement(codegen) { | 253 : NestedStatement(codegen) { |
269 } | 254 } |
270 virtual ~WithOrCatch() {} | 255 virtual ~WithOrCatch() {} |
271 | 256 |
272 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { | 257 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { |
273 ++(*context_length); | 258 ++(*context_length); |
274 return previous_; | 259 return previous_; |
(...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
817 | 802 |
818 friend class NestedStatement; | 803 friend class NestedStatement; |
819 | 804 |
820 DISALLOW_COPY_AND_ASSIGN(FullCodeGenerator); | 805 DISALLOW_COPY_AND_ASSIGN(FullCodeGenerator); |
821 }; | 806 }; |
822 | 807 |
823 | 808 |
824 } } // namespace v8::internal | 809 } } // namespace v8::internal |
825 | 810 |
826 #endif // V8_FULL_CODEGEN_H_ | 811 #endif // V8_FULL_CODEGEN_H_ |
OLD | NEW |