| 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 |