| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_FULL_CODEGEN_FULL_CODEGEN_H_ | 5 #ifndef V8_FULL_CODEGEN_FULL_CODEGEN_H_ |
| 6 #define V8_FULL_CODEGEN_FULL_CODEGEN_H_ | 6 #define V8_FULL_CODEGEN_FULL_CODEGEN_H_ |
| 7 | 7 |
| 8 #include "src/allocation.h" | 8 #include "src/allocation.h" |
| 9 #include "src/assert-scope.h" | 9 #include "src/assert-scope.h" |
| 10 #include "src/ast/ast.h" | 10 #include "src/ast/ast.h" |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 | 101 |
| 102 private: | 102 private: |
| 103 class Breakable; | 103 class Breakable; |
| 104 class Iteration; | 104 class Iteration; |
| 105 class TryFinally; | 105 class TryFinally; |
| 106 | 106 |
| 107 class TestContext; | 107 class TestContext; |
| 108 | 108 |
| 109 class NestedStatement BASE_EMBEDDED { | 109 class NestedStatement BASE_EMBEDDED { |
| 110 public: | 110 public: |
| 111 explicit NestedStatement(FullCodeGenerator* codegen) : codegen_(codegen) { | 111 explicit NestedStatement(FullCodeGenerator* codegen) |
| 112 : codegen_(codegen), |
| 113 stack_depth_at_target_(codegen->operand_stack_depth_) { |
| 112 // Link into codegen's nesting stack. | 114 // Link into codegen's nesting stack. |
| 113 previous_ = codegen->nesting_stack_; | 115 previous_ = codegen->nesting_stack_; |
| 114 codegen->nesting_stack_ = this; | 116 codegen->nesting_stack_ = this; |
| 115 } | 117 } |
| 116 virtual ~NestedStatement() { | 118 virtual ~NestedStatement() { |
| 117 // Unlink from codegen's nesting stack. | 119 // Unlink from codegen's nesting stack. |
| 118 DCHECK_EQ(this, codegen_->nesting_stack_); | 120 DCHECK_EQ(this, codegen_->nesting_stack_); |
| 119 codegen_->nesting_stack_ = previous_; | 121 codegen_->nesting_stack_ = previous_; |
| 120 } | 122 } |
| 121 | 123 |
| 122 virtual Breakable* AsBreakable() { return nullptr; } | 124 virtual Breakable* AsBreakable() { return nullptr; } |
| 123 virtual Iteration* AsIteration() { return nullptr; } | 125 virtual Iteration* AsIteration() { return nullptr; } |
| 124 virtual TryFinally* AsTryFinally() { return nullptr; } | 126 virtual TryFinally* AsTryFinally() { return nullptr; } |
| 125 | 127 |
| 126 virtual bool IsContinueTarget(Statement* target) { return false; } | 128 virtual bool IsContinueTarget(Statement* target) { return false; } |
| 127 virtual bool IsBreakTarget(Statement* target) { return false; } | 129 virtual bool IsBreakTarget(Statement* target) { return false; } |
| 128 virtual bool IsTryFinally() { return false; } | 130 virtual bool IsTryFinally() { return false; } |
| 129 | 131 |
| 130 // Notify the statement that we are exiting it via break, continue, or | 132 // Notify the statement that we are exiting it via break, continue, or |
| 131 // return and give it a chance to generate cleanup code. Return the | 133 // return and give it a chance to generate cleanup code. Return the |
| 132 // next outer statement in the nesting stack. We accumulate in | 134 // next outer statement in the nesting stack. We accumulate in |
| 133 // *stack_depth the amount to drop the stack and in *context_length the | 135 // {*context_length} the number of context chain links to unwind as we |
| 134 // number of context chain links to unwind as we traverse the nesting | 136 // traverse the nesting stack from an exit to its target. |
| 135 // stack from an exit to its target. | 137 virtual NestedStatement* Exit(int* context_length) { return previous_; } |
| 136 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { | 138 |
| 137 return previous_; | 139 // Determine the expected operand stack depth when this statement is being |
| 138 } | 140 // used as the target of an exit. The caller will drop to this depth. |
| 141 int GetStackDepthAtTarget() { return stack_depth_at_target_; } |
| 139 | 142 |
| 140 protected: | 143 protected: |
| 141 MacroAssembler* masm() { return codegen_->masm(); } | 144 MacroAssembler* masm() { return codegen_->masm(); } |
| 142 | 145 |
| 143 FullCodeGenerator* codegen_; | 146 FullCodeGenerator* codegen_; |
| 144 NestedStatement* previous_; | 147 NestedStatement* previous_; |
| 148 int stack_depth_at_target_; |
| 145 | 149 |
| 146 private: | 150 private: |
| 147 DISALLOW_COPY_AND_ASSIGN(NestedStatement); | 151 DISALLOW_COPY_AND_ASSIGN(NestedStatement); |
| 148 }; | 152 }; |
| 149 | 153 |
| 150 // A breakable statement such as a block. | 154 // A breakable statement such as a block. |
| 151 class Breakable : public NestedStatement { | 155 class Breakable : public NestedStatement { |
| 152 public: | 156 public: |
| 153 Breakable(FullCodeGenerator* codegen, BreakableStatement* statement) | 157 Breakable(FullCodeGenerator* codegen, BreakableStatement* statement) |
| 154 : NestedStatement(codegen), statement_(statement) { | 158 : NestedStatement(codegen), statement_(statement) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 185 Label continue_label_; | 189 Label continue_label_; |
| 186 }; | 190 }; |
| 187 | 191 |
| 188 // A nested block statement. | 192 // A nested block statement. |
| 189 class NestedBlock : public Breakable { | 193 class NestedBlock : public Breakable { |
| 190 public: | 194 public: |
| 191 NestedBlock(FullCodeGenerator* codegen, Block* block) | 195 NestedBlock(FullCodeGenerator* codegen, Block* block) |
| 192 : Breakable(codegen, block) { | 196 : Breakable(codegen, block) { |
| 193 } | 197 } |
| 194 | 198 |
| 195 NestedStatement* Exit(int* stack_depth, int* context_length) override { | 199 NestedStatement* Exit(int* context_length) override { |
| 196 auto block_scope = statement()->AsBlock()->scope(); | 200 auto block_scope = statement()->AsBlock()->scope(); |
| 197 if (block_scope != nullptr) { | 201 if (block_scope != nullptr) { |
| 198 if (block_scope->ContextLocalCount() > 0) ++(*context_length); | 202 if (block_scope->ContextLocalCount() > 0) ++(*context_length); |
| 199 } | 203 } |
| 200 return previous_; | 204 return previous_; |
| 201 } | 205 } |
| 202 }; | 206 }; |
| 203 | 207 |
| 204 // The try block of a try/catch statement. | |
| 205 class TryCatch : public NestedStatement { | |
| 206 public: | |
| 207 static const int kElementCount = TryBlockConstant::kElementCount; | |
| 208 | |
| 209 explicit TryCatch(FullCodeGenerator* codegen) : NestedStatement(codegen) {} | |
| 210 | |
| 211 NestedStatement* Exit(int* stack_depth, int* context_length) override { | |
| 212 *stack_depth += kElementCount; | |
| 213 return previous_; | |
| 214 } | |
| 215 }; | |
| 216 | |
| 217 class DeferredCommands { | 208 class DeferredCommands { |
| 218 public: | 209 public: |
| 219 enum Command { kReturn, kThrow, kBreak, kContinue }; | 210 enum Command { kReturn, kThrow, kBreak, kContinue }; |
| 220 typedef int TokenId; | 211 typedef int TokenId; |
| 221 struct DeferredCommand { | 212 struct DeferredCommand { |
| 222 Command command; | 213 Command command; |
| 223 TokenId token; | 214 TokenId token; |
| 224 Statement* target; | 215 Statement* target; |
| 225 }; | 216 }; |
| 226 | 217 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 247 ZoneVector<DeferredCommand> commands_; | 238 ZoneVector<DeferredCommand> commands_; |
| 248 TokenDispenserForFinally dispenser_; | 239 TokenDispenserForFinally dispenser_; |
| 249 TokenId return_token_; | 240 TokenId return_token_; |
| 250 TokenId throw_token_; | 241 TokenId throw_token_; |
| 251 Label* finally_entry_; | 242 Label* finally_entry_; |
| 252 }; | 243 }; |
| 253 | 244 |
| 254 // The try block of a try/finally statement. | 245 // The try block of a try/finally statement. |
| 255 class TryFinally : public NestedStatement { | 246 class TryFinally : public NestedStatement { |
| 256 public: | 247 public: |
| 257 static const int kElementCount = TryBlockConstant::kElementCount; | |
| 258 | |
| 259 TryFinally(FullCodeGenerator* codegen, DeferredCommands* commands) | 248 TryFinally(FullCodeGenerator* codegen, DeferredCommands* commands) |
| 260 : NestedStatement(codegen), deferred_commands_(commands) {} | 249 : NestedStatement(codegen), deferred_commands_(commands) {} |
| 261 | 250 |
| 262 NestedStatement* Exit(int* stack_depth, int* context_length) override; | 251 NestedStatement* Exit(int* context_length) override; |
| 263 | 252 |
| 264 bool IsTryFinally() override { return true; } | 253 bool IsTryFinally() override { return true; } |
| 265 TryFinally* AsTryFinally() override { return this; } | 254 TryFinally* AsTryFinally() override { return this; } |
| 266 | 255 |
| 267 DeferredCommands* deferred_commands() { return deferred_commands_; } | 256 DeferredCommands* deferred_commands() { return deferred_commands_; } |
| 268 | 257 |
| 269 private: | 258 private: |
| 270 DeferredCommands* deferred_commands_; | 259 DeferredCommands* deferred_commands_; |
| 271 }; | 260 }; |
| 272 | 261 |
| 273 // The finally block of a try/finally statement. | |
| 274 class Finally : public NestedStatement { | |
| 275 public: | |
| 276 static const int kElementCount = 3; | |
| 277 | |
| 278 explicit Finally(FullCodeGenerator* codegen) : NestedStatement(codegen) {} | |
| 279 | |
| 280 NestedStatement* Exit(int* stack_depth, int* context_length) override { | |
| 281 *stack_depth += kElementCount; | |
| 282 return previous_; | |
| 283 } | |
| 284 }; | |
| 285 | |
| 286 // The body of a for/in loop. | |
| 287 class ForIn : public Iteration { | |
| 288 public: | |
| 289 static const int kElementCount = 5; | |
| 290 | |
| 291 ForIn(FullCodeGenerator* codegen, ForInStatement* statement) | |
| 292 : Iteration(codegen, statement) { | |
| 293 } | |
| 294 | |
| 295 NestedStatement* Exit(int* stack_depth, int* context_length) override { | |
| 296 *stack_depth += kElementCount; | |
| 297 return previous_; | |
| 298 } | |
| 299 }; | |
| 300 | |
| 301 | |
| 302 // The body of a with or catch. | 262 // The body of a with or catch. |
| 303 class WithOrCatch : public NestedStatement { | 263 class WithOrCatch : public NestedStatement { |
| 304 public: | 264 public: |
| 305 explicit WithOrCatch(FullCodeGenerator* codegen) | 265 explicit WithOrCatch(FullCodeGenerator* codegen) |
| 306 : NestedStatement(codegen) { | 266 : NestedStatement(codegen) { |
| 307 } | 267 } |
| 308 | 268 |
| 309 NestedStatement* Exit(int* stack_depth, int* context_length) override { | 269 NestedStatement* Exit(int* context_length) override { |
| 310 ++(*context_length); | 270 ++(*context_length); |
| 311 return previous_; | 271 return previous_; |
| 312 } | 272 } |
| 313 }; | 273 }; |
| 314 | 274 |
| 315 // A platform-specific utility to overwrite the accumulator register | 275 // A platform-specific utility to overwrite the accumulator register |
| 316 // with a GC-safe value. | 276 // with a GC-safe value. |
| 317 void ClearAccumulator(); | 277 void ClearAccumulator(); |
| 318 | 278 |
| 319 // Determine whether or not to inline the smi case for the given | 279 // Determine whether or not to inline the smi case for the given |
| (...skipping 777 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1097 Address start_; | 1057 Address start_; |
| 1098 Address instruction_start_; | 1058 Address instruction_start_; |
| 1099 uint32_t length_; | 1059 uint32_t length_; |
| 1100 }; | 1060 }; |
| 1101 | 1061 |
| 1102 | 1062 |
| 1103 } // namespace internal | 1063 } // namespace internal |
| 1104 } // namespace v8 | 1064 } // namespace v8 |
| 1105 | 1065 |
| 1106 #endif // V8_FULL_CODEGEN_FULL_CODEGEN_H_ | 1066 #endif // V8_FULL_CODEGEN_FULL_CODEGEN_H_ |
| OLD | NEW |