| 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 // Generate code to leave the nested statement. This includes | 136 // Notify the statement that we are exiting it via break, continue, or |
| 144 // cleaning up any stack elements in use and restoring the | 137 // return and give it a chance to generate cleanup code. Return the |
| 145 // stack to the expectations of the surrounding statements. | 138 // next outer statement in the nesting stack. We accumulate in |
| 146 // Takes a number of stack elements currently on top of the | 139 // *stack_depth the amount to drop the stack and in *context_length the |
| 147 // nested statement's stack, and returns a number of stack | 140 // number of context chain links to unwind as we traverse the nesting |
| 148 // elements left on top of the surrounding statement's stack. | 141 // stack from an exit to its target. |
| 149 // The generated code must preserve the result register (which | 142 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { |
| 150 // contains the value in case of a return). | 143 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 } | 144 } |
| 156 NestedStatement* outer() { return previous_; } | |
| 157 | 145 |
| 158 protected: | 146 protected: |
| 159 MacroAssembler* masm() { return codegen_->masm(); } | 147 MacroAssembler* masm() { return codegen_->masm(); } |
| 160 | 148 |
| 161 private: | |
| 162 FullCodeGenerator* codegen_; | 149 FullCodeGenerator* codegen_; |
| 163 NestedStatement* previous_; | 150 NestedStatement* previous_; |
| 164 DISALLOW_COPY_AND_ASSIGN(NestedStatement); | 151 DISALLOW_COPY_AND_ASSIGN(NestedStatement); |
| 165 }; | 152 }; |
| 166 | 153 |
| 154 // A breakable statement such as a block. |
| 167 class Breakable : public NestedStatement { | 155 class Breakable : public NestedStatement { |
| 168 public: | 156 public: |
| 169 Breakable(FullCodeGenerator* codegen, | 157 Breakable(FullCodeGenerator* codegen, BreakableStatement* statement) |
| 170 BreakableStatement* break_target) | 158 : NestedStatement(codegen), statement_(statement) { |
| 171 : NestedStatement(codegen), | 159 } |
| 172 target_(break_target) {} | |
| 173 virtual ~Breakable() {} | 160 virtual ~Breakable() {} |
| 161 |
| 174 virtual Breakable* AsBreakable() { return this; } | 162 virtual Breakable* AsBreakable() { return this; } |
| 175 virtual bool IsBreakTarget(Statement* statement) { | 163 virtual bool IsBreakTarget(Statement* target) { |
| 176 return target_ == statement; | 164 return statement() == target; |
| 177 } | 165 } |
| 178 BreakableStatement* statement() { return target_; } | 166 |
| 179 Label* break_target() { return &break_target_label_; } | 167 BreakableStatement* statement() { return statement_; } |
| 168 Label* break_label() { return &break_label_; } |
| 169 |
| 180 private: | 170 private: |
| 181 BreakableStatement* target_; | 171 BreakableStatement* statement_; |
| 182 Label break_target_label_; | 172 Label break_label_; |
| 183 DISALLOW_COPY_AND_ASSIGN(Breakable); | |
| 184 }; | 173 }; |
| 185 | 174 |
| 175 // An iteration statement such as a while, for, or do loop. |
| 186 class Iteration : public Breakable { | 176 class Iteration : public Breakable { |
| 187 public: | 177 public: |
| 188 Iteration(FullCodeGenerator* codegen, | 178 Iteration(FullCodeGenerator* codegen, IterationStatement* statement) |
| 189 IterationStatement* iteration_statement) | 179 : Breakable(codegen, statement) { |
| 190 : Breakable(codegen, iteration_statement) {} | 180 } |
| 191 virtual ~Iteration() {} | 181 virtual ~Iteration() {} |
| 182 |
| 192 virtual Iteration* AsIteration() { return this; } | 183 virtual Iteration* AsIteration() { return this; } |
| 193 virtual bool IsContinueTarget(Statement* statement) { | 184 virtual bool IsContinueTarget(Statement* target) { |
| 194 return this->statement() == statement; | 185 return statement() == target; |
| 195 } | 186 } |
| 196 Label* continue_target() { return &continue_target_label_; } | 187 |
| 188 Label* continue_label() { return &continue_label_; } |
| 189 |
| 197 private: | 190 private: |
| 198 Label continue_target_label_; | 191 Label continue_label_; |
| 199 DISALLOW_COPY_AND_ASSIGN(Iteration); | |
| 200 }; | 192 }; |
| 201 | 193 |
| 202 // The environment inside the try block of a try/catch statement. | 194 // The try block of a try/catch statement. |
| 203 class TryCatch : public NestedStatement { | 195 class TryCatch : public NestedStatement { |
| 204 public: | 196 public: |
| 205 explicit TryCatch(FullCodeGenerator* codegen, Label* catch_entry) | 197 explicit TryCatch(FullCodeGenerator* codegen) : NestedStatement(codegen) { |
| 206 : NestedStatement(codegen), catch_entry_(catch_entry) { } | 198 } |
| 207 virtual ~TryCatch() {} | 199 virtual ~TryCatch() {} |
| 208 virtual TryCatch* AsTryCatch() { return this; } | 200 |
| 209 Label* catch_entry() { return catch_entry_; } | 201 virtual NestedStatement* Exit(int* stack_depth, int* context_length); |
| 210 virtual int Exit(int stack_depth); | |
| 211 private: | |
| 212 Label* catch_entry_; | |
| 213 DISALLOW_COPY_AND_ASSIGN(TryCatch); | |
| 214 }; | 202 }; |
| 215 | 203 |
| 216 // The environment inside the try block of a try/finally statement. | 204 // The try block of a try/finally statement. |
| 217 class TryFinally : public NestedStatement { | 205 class TryFinally : public NestedStatement { |
| 218 public: | 206 public: |
| 219 explicit TryFinally(FullCodeGenerator* codegen, Label* finally_entry) | 207 TryFinally(FullCodeGenerator* codegen, Label* finally_entry) |
| 220 : NestedStatement(codegen), finally_entry_(finally_entry) { } | 208 : NestedStatement(codegen), finally_entry_(finally_entry) { |
| 209 } |
| 221 virtual ~TryFinally() {} | 210 virtual ~TryFinally() {} |
| 222 virtual TryFinally* AsTryFinally() { return this; } | 211 |
| 223 Label* finally_entry() { return finally_entry_; } | 212 virtual NestedStatement* Exit(int* stack_depth, int* context_length); |
| 224 virtual int Exit(int stack_depth); | 213 |
| 225 private: | 214 private: |
| 226 Label* finally_entry_; | 215 Label* finally_entry_; |
| 227 DISALLOW_COPY_AND_ASSIGN(TryFinally); | |
| 228 }; | 216 }; |
| 229 | 217 |
| 230 // A FinallyEnvironment represents being inside a finally block. | 218 // The finally block of a try/finally statement. |
| 231 // Abnormal termination of the finally block needs to clean up | |
| 232 // the block's parameters from the stack. | |
| 233 class Finally : public NestedStatement { | 219 class Finally : public NestedStatement { |
| 234 public: | 220 public: |
| 221 static const int kElementCount = 2; |
| 222 |
| 235 explicit Finally(FullCodeGenerator* codegen) : NestedStatement(codegen) { } | 223 explicit Finally(FullCodeGenerator* codegen) : NestedStatement(codegen) { } |
| 236 virtual ~Finally() {} | 224 virtual ~Finally() {} |
| 237 virtual Finally* AsFinally() { return this; } | 225 |
| 238 virtual int Exit(int stack_depth) { | 226 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { |
| 239 return stack_depth + kFinallyStackElementCount; | 227 *stack_depth += kElementCount; |
| 228 return previous_; |
| 240 } | 229 } |
| 241 private: | |
| 242 // Number of extra stack slots occupied during a finally block. | |
| 243 static const int kFinallyStackElementCount = 2; | |
| 244 DISALLOW_COPY_AND_ASSIGN(Finally); | |
| 245 }; | 230 }; |
| 246 | 231 |
| 247 // A ForInEnvironment represents being inside a for-in loop. | 232 // The body of a for/in loop. |
| 248 // Abnormal termination of the for-in block needs to clean up | |
| 249 // the block's temporary storage from the stack. | |
| 250 class ForIn : public Iteration { | 233 class ForIn : public Iteration { |
| 251 public: | 234 public: |
| 252 ForIn(FullCodeGenerator* codegen, | 235 static const int kElementCount = 5; |
| 253 ForInStatement* statement) | 236 |
| 254 : Iteration(codegen, statement) { } | 237 ForIn(FullCodeGenerator* codegen, ForInStatement* statement) |
| 238 : Iteration(codegen, statement) { |
| 239 } |
| 255 virtual ~ForIn() {} | 240 virtual ~ForIn() {} |
| 256 virtual ForIn* AsForIn() { return this; } | 241 |
| 257 virtual int Exit(int stack_depth) { | 242 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { |
| 258 return stack_depth + kForInStackElementCount; | 243 *stack_depth += kElementCount; |
| 244 return previous_; |
| 259 } | 245 } |
| 260 private: | 246 }; |
| 261 static const int kForInStackElementCount = 5; | 247 |
| 262 DISALLOW_COPY_AND_ASSIGN(ForIn); | 248 |
| 249 // The body of a with or catch. |
| 250 class WithOrCatch : public NestedStatement { |
| 251 public: |
| 252 explicit WithOrCatch(FullCodeGenerator* codegen) |
| 253 : NestedStatement(codegen) { |
| 254 } |
| 255 virtual ~WithOrCatch() {} |
| 256 |
| 257 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { |
| 258 ++(*context_length); |
| 259 return previous_; |
| 260 } |
| 263 }; | 261 }; |
| 264 | 262 |
| 265 // The forward bailout stack keeps track of the expressions that can | 263 // 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 | 264 // bail out to just before the control flow is split in a child |
| 267 // node. The stack elements are linked together through the parent | 265 // node. The stack elements are linked together through the parent |
| 268 // link when visiting expressions in test contexts after requesting | 266 // link when visiting expressions in test contexts after requesting |
| 269 // bailout in child forwarding. | 267 // bailout in child forwarding. |
| 270 class ForwardBailoutStack BASE_EMBEDDED { | 268 class ForwardBailoutStack BASE_EMBEDDED { |
| 271 public: | 269 public: |
| 272 ForwardBailoutStack(Expression* expr, ForwardBailoutStack* parent) | 270 ForwardBailoutStack(Expression* expr, ForwardBailoutStack* parent) |
| (...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 804 | 802 |
| 805 friend class NestedStatement; | 803 friend class NestedStatement; |
| 806 | 804 |
| 807 DISALLOW_COPY_AND_ASSIGN(FullCodeGenerator); | 805 DISALLOW_COPY_AND_ASSIGN(FullCodeGenerator); |
| 808 }; | 806 }; |
| 809 | 807 |
| 810 | 808 |
| 811 } } // namespace v8::internal | 809 } } // namespace v8::internal |
| 812 | 810 |
| 813 #endif // V8_FULL_CODEGEN_H_ | 811 #endif // V8_FULL_CODEGEN_H_ |
| OLD | NEW |