| 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.h" | 10 #include "src/ast.h" |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 private: | 146 private: |
| 147 DISALLOW_COPY_AND_ASSIGN(NestedStatement); | 147 DISALLOW_COPY_AND_ASSIGN(NestedStatement); |
| 148 }; | 148 }; |
| 149 | 149 |
| 150 // A breakable statement such as a block. | 150 // A breakable statement such as a block. |
| 151 class Breakable : public NestedStatement { | 151 class Breakable : public NestedStatement { |
| 152 public: | 152 public: |
| 153 Breakable(FullCodeGenerator* codegen, BreakableStatement* statement) | 153 Breakable(FullCodeGenerator* codegen, BreakableStatement* statement) |
| 154 : NestedStatement(codegen), statement_(statement) { | 154 : NestedStatement(codegen), statement_(statement) { |
| 155 } | 155 } |
| 156 virtual ~Breakable() {} | |
| 157 | 156 |
| 158 virtual Breakable* AsBreakable() { return this; } | 157 Breakable* AsBreakable() override { return this; } |
| 159 virtual bool IsBreakTarget(Statement* target) { | 158 bool IsBreakTarget(Statement* target) override { |
| 160 return statement() == target; | 159 return statement() == target; |
| 161 } | 160 } |
| 162 | 161 |
| 163 BreakableStatement* statement() { return statement_; } | 162 BreakableStatement* statement() { return statement_; } |
| 164 Label* break_label() { return &break_label_; } | 163 Label* break_label() { return &break_label_; } |
| 165 | 164 |
| 166 private: | 165 private: |
| 167 BreakableStatement* statement_; | 166 BreakableStatement* statement_; |
| 168 Label break_label_; | 167 Label break_label_; |
| 169 }; | 168 }; |
| 170 | 169 |
| 171 // An iteration statement such as a while, for, or do loop. | 170 // An iteration statement such as a while, for, or do loop. |
| 172 class Iteration : public Breakable { | 171 class Iteration : public Breakable { |
| 173 public: | 172 public: |
| 174 Iteration(FullCodeGenerator* codegen, IterationStatement* statement) | 173 Iteration(FullCodeGenerator* codegen, IterationStatement* statement) |
| 175 : Breakable(codegen, statement) { | 174 : Breakable(codegen, statement) { |
| 176 } | 175 } |
| 177 virtual ~Iteration() {} | |
| 178 | 176 |
| 179 virtual Iteration* AsIteration() { return this; } | 177 Iteration* AsIteration() override { return this; } |
| 180 virtual bool IsContinueTarget(Statement* target) { | 178 bool IsContinueTarget(Statement* target) override { |
| 181 return statement() == target; | 179 return statement() == target; |
| 182 } | 180 } |
| 183 | 181 |
| 184 Label* continue_label() { return &continue_label_; } | 182 Label* continue_label() { return &continue_label_; } |
| 185 | 183 |
| 186 private: | 184 private: |
| 187 Label continue_label_; | 185 Label continue_label_; |
| 188 }; | 186 }; |
| 189 | 187 |
| 190 // A nested block statement. | 188 // A nested block statement. |
| 191 class NestedBlock : public Breakable { | 189 class NestedBlock : public Breakable { |
| 192 public: | 190 public: |
| 193 NestedBlock(FullCodeGenerator* codegen, Block* block) | 191 NestedBlock(FullCodeGenerator* codegen, Block* block) |
| 194 : Breakable(codegen, block) { | 192 : Breakable(codegen, block) { |
| 195 } | 193 } |
| 196 virtual ~NestedBlock() {} | |
| 197 | 194 |
| 198 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { | 195 NestedStatement* Exit(int* stack_depth, int* context_length) override { |
| 199 auto block_scope = statement()->AsBlock()->scope(); | 196 auto block_scope = statement()->AsBlock()->scope(); |
| 200 if (block_scope != nullptr) { | 197 if (block_scope != nullptr) { |
| 201 if (block_scope->ContextLocalCount() > 0) ++(*context_length); | 198 if (block_scope->ContextLocalCount() > 0) ++(*context_length); |
| 202 } | 199 } |
| 203 return previous_; | 200 return previous_; |
| 204 } | 201 } |
| 205 }; | 202 }; |
| 206 | 203 |
| 207 // The try block of a try/catch statement. | 204 // The try block of a try/catch statement. |
| 208 class TryCatch : public NestedStatement { | 205 class TryCatch : public NestedStatement { |
| 209 public: | 206 public: |
| 210 static const int kElementCount = TryBlockConstant::kElementCount; | 207 static const int kElementCount = TryBlockConstant::kElementCount; |
| 211 | 208 |
| 212 explicit TryCatch(FullCodeGenerator* codegen) : NestedStatement(codegen) {} | 209 explicit TryCatch(FullCodeGenerator* codegen) : NestedStatement(codegen) {} |
| 213 virtual ~TryCatch() {} | |
| 214 | 210 |
| 215 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { | 211 NestedStatement* Exit(int* stack_depth, int* context_length) override { |
| 216 *stack_depth += kElementCount; | 212 *stack_depth += kElementCount; |
| 217 return previous_; | 213 return previous_; |
| 218 } | 214 } |
| 219 virtual NestedStatement* AccumulateDepth(int* stack_depth) { | 215 NestedStatement* AccumulateDepth(int* stack_depth) override { |
| 220 *stack_depth += kElementCount; | 216 *stack_depth += kElementCount; |
| 221 return previous_; | 217 return previous_; |
| 222 } | 218 } |
| 223 }; | 219 }; |
| 224 | 220 |
| 225 // The try block of a try/finally statement. | 221 // The try block of a try/finally statement. |
| 226 class TryFinally : public NestedStatement { | 222 class TryFinally : public NestedStatement { |
| 227 public: | 223 public: |
| 228 static const int kElementCount = TryBlockConstant::kElementCount; | 224 static const int kElementCount = TryBlockConstant::kElementCount; |
| 229 | 225 |
| 230 TryFinally(FullCodeGenerator* codegen, Label* finally_entry) | 226 TryFinally(FullCodeGenerator* codegen, Label* finally_entry) |
| 231 : NestedStatement(codegen), finally_entry_(finally_entry) { | 227 : NestedStatement(codegen), finally_entry_(finally_entry) { |
| 232 } | 228 } |
| 233 virtual ~TryFinally() {} | |
| 234 | 229 |
| 235 virtual NestedStatement* Exit(int* stack_depth, int* context_length); | 230 NestedStatement* Exit(int* stack_depth, int* context_length) override; |
| 236 virtual NestedStatement* AccumulateDepth(int* stack_depth) { | 231 NestedStatement* AccumulateDepth(int* stack_depth) override { |
| 237 *stack_depth += kElementCount; | 232 *stack_depth += kElementCount; |
| 238 return previous_; | 233 return previous_; |
| 239 } | 234 } |
| 240 | 235 |
| 241 private: | 236 private: |
| 242 Label* finally_entry_; | 237 Label* finally_entry_; |
| 243 }; | 238 }; |
| 244 | 239 |
| 245 // The finally block of a try/finally statement. | 240 // The finally block of a try/finally statement. |
| 246 class Finally : public NestedStatement { | 241 class Finally : public NestedStatement { |
| 247 public: | 242 public: |
| 248 static const int kElementCount = 3; | 243 static const int kElementCount = 3; |
| 249 | 244 |
| 250 explicit Finally(FullCodeGenerator* codegen) : NestedStatement(codegen) {} | 245 explicit Finally(FullCodeGenerator* codegen) : NestedStatement(codegen) {} |
| 251 virtual ~Finally() {} | |
| 252 | 246 |
| 253 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { | 247 NestedStatement* Exit(int* stack_depth, int* context_length) override { |
| 254 *stack_depth += kElementCount; | 248 *stack_depth += kElementCount; |
| 255 return previous_; | 249 return previous_; |
| 256 } | 250 } |
| 257 virtual NestedStatement* AccumulateDepth(int* stack_depth) { | 251 NestedStatement* AccumulateDepth(int* stack_depth) override { |
| 258 *stack_depth += kElementCount; | 252 *stack_depth += kElementCount; |
| 259 return previous_; | 253 return previous_; |
| 260 } | 254 } |
| 261 }; | 255 }; |
| 262 | 256 |
| 263 // The body of a for/in loop. | 257 // The body of a for/in loop. |
| 264 class ForIn : public Iteration { | 258 class ForIn : public Iteration { |
| 265 public: | 259 public: |
| 266 static const int kElementCount = 5; | 260 static const int kElementCount = 5; |
| 267 | 261 |
| 268 ForIn(FullCodeGenerator* codegen, ForInStatement* statement) | 262 ForIn(FullCodeGenerator* codegen, ForInStatement* statement) |
| 269 : Iteration(codegen, statement) { | 263 : Iteration(codegen, statement) { |
| 270 } | 264 } |
| 271 virtual ~ForIn() {} | |
| 272 | 265 |
| 273 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { | 266 NestedStatement* Exit(int* stack_depth, int* context_length) override { |
| 274 *stack_depth += kElementCount; | 267 *stack_depth += kElementCount; |
| 275 return previous_; | 268 return previous_; |
| 276 } | 269 } |
| 277 virtual NestedStatement* AccumulateDepth(int* stack_depth) { | 270 NestedStatement* AccumulateDepth(int* stack_depth) override { |
| 278 *stack_depth += kElementCount; | 271 *stack_depth += kElementCount; |
| 279 return previous_; | 272 return previous_; |
| 280 } | 273 } |
| 281 }; | 274 }; |
| 282 | 275 |
| 283 | 276 |
| 284 // The body of a with or catch. | 277 // The body of a with or catch. |
| 285 class WithOrCatch : public NestedStatement { | 278 class WithOrCatch : public NestedStatement { |
| 286 public: | 279 public: |
| 287 explicit WithOrCatch(FullCodeGenerator* codegen) | 280 explicit WithOrCatch(FullCodeGenerator* codegen) |
| 288 : NestedStatement(codegen) { | 281 : NestedStatement(codegen) { |
| 289 } | 282 } |
| 290 virtual ~WithOrCatch() {} | |
| 291 | 283 |
| 292 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { | 284 NestedStatement* Exit(int* stack_depth, int* context_length) override { |
| 293 ++(*context_length); | 285 ++(*context_length); |
| 294 return previous_; | 286 return previous_; |
| 295 } | 287 } |
| 296 }; | 288 }; |
| 297 | 289 |
| 298 // A platform-specific utility to overwrite the accumulator register | 290 // A platform-specific utility to overwrite the accumulator register |
| 299 // with a GC-safe value. | 291 // with a GC-safe value. |
| 300 void ClearAccumulator(); | 292 void ClearAccumulator(); |
| 301 | 293 |
| 302 // Determine whether or not to inline the smi case for the given | 294 // Determine whether or not to inline the smi case for the given |
| (...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 716 // in v8::internal::Context. | 708 // in v8::internal::Context. |
| 717 void LoadContextField(Register dst, int context_index); | 709 void LoadContextField(Register dst, int context_index); |
| 718 | 710 |
| 719 // Push the function argument for the runtime functions PushWithContext | 711 // Push the function argument for the runtime functions PushWithContext |
| 720 // and PushCatchContext. | 712 // and PushCatchContext. |
| 721 void PushFunctionArgumentForContextAllocation(); | 713 void PushFunctionArgumentForContextAllocation(); |
| 722 | 714 |
| 723 void PushCalleeAndWithBaseObject(Call* expr); | 715 void PushCalleeAndWithBaseObject(Call* expr); |
| 724 | 716 |
| 725 // AST node visit functions. | 717 // AST node visit functions. |
| 726 #define DECLARE_VISIT(type) virtual void Visit##type(type* node) override; | 718 #define DECLARE_VISIT(type) void Visit##type(type* node) override; |
| 727 AST_NODE_LIST(DECLARE_VISIT) | 719 AST_NODE_LIST(DECLARE_VISIT) |
| 728 #undef DECLARE_VISIT | 720 #undef DECLARE_VISIT |
| 729 | 721 |
| 730 void VisitComma(BinaryOperation* expr); | 722 void VisitComma(BinaryOperation* expr); |
| 731 void VisitLogicalExpression(BinaryOperation* expr); | 723 void VisitLogicalExpression(BinaryOperation* expr); |
| 732 void VisitArithmeticExpression(BinaryOperation* expr); | 724 void VisitArithmeticExpression(BinaryOperation* expr); |
| 733 | 725 |
| 734 void VisitForTypeofValue(Expression* expr); | 726 void VisitForTypeofValue(Expression* expr); |
| 735 | 727 |
| 736 void Generate(); | 728 void Generate(); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 830 private: | 822 private: |
| 831 const ExpressionContext* old_; | 823 const ExpressionContext* old_; |
| 832 FullCodeGenerator* codegen_; | 824 FullCodeGenerator* codegen_; |
| 833 }; | 825 }; |
| 834 | 826 |
| 835 class AccumulatorValueContext : public ExpressionContext { | 827 class AccumulatorValueContext : public ExpressionContext { |
| 836 public: | 828 public: |
| 837 explicit AccumulatorValueContext(FullCodeGenerator* codegen) | 829 explicit AccumulatorValueContext(FullCodeGenerator* codegen) |
| 838 : ExpressionContext(codegen) { } | 830 : ExpressionContext(codegen) { } |
| 839 | 831 |
| 840 virtual void Plug(bool flag) const; | 832 void Plug(bool flag) const override; |
| 841 virtual void Plug(Register reg) const; | 833 void Plug(Register reg) const override; |
| 842 virtual void Plug(Label* materialize_true, Label* materialize_false) const; | 834 void Plug(Label* materialize_true, Label* materialize_false) const override; |
| 843 virtual void Plug(Variable* var) const; | 835 void Plug(Variable* var) const override; |
| 844 virtual void Plug(Handle<Object> lit) const; | 836 void Plug(Handle<Object> lit) const override; |
| 845 virtual void Plug(Heap::RootListIndex) const; | 837 void Plug(Heap::RootListIndex) const override; |
| 846 virtual void PlugTOS() const; | 838 void PlugTOS() const override; |
| 847 virtual void DropAndPlug(int count, Register reg) const; | 839 void DropAndPlug(int count, Register reg) const override; |
| 848 virtual void PrepareTest(Label* materialize_true, | 840 void PrepareTest(Label* materialize_true, Label* materialize_false, |
| 849 Label* materialize_false, | 841 Label** if_true, Label** if_false, |
| 850 Label** if_true, | 842 Label** fall_through) const override; |
| 851 Label** if_false, | 843 bool IsAccumulatorValue() const override { return true; } |
| 852 Label** fall_through) const; | |
| 853 virtual bool IsAccumulatorValue() const { return true; } | |
| 854 }; | 844 }; |
| 855 | 845 |
| 856 class StackValueContext : public ExpressionContext { | 846 class StackValueContext : public ExpressionContext { |
| 857 public: | 847 public: |
| 858 explicit StackValueContext(FullCodeGenerator* codegen) | 848 explicit StackValueContext(FullCodeGenerator* codegen) |
| 859 : ExpressionContext(codegen) { } | 849 : ExpressionContext(codegen) { } |
| 860 | 850 |
| 861 virtual void Plug(bool flag) const; | 851 void Plug(bool flag) const override; |
| 862 virtual void Plug(Register reg) const; | 852 void Plug(Register reg) const override; |
| 863 virtual void Plug(Label* materialize_true, Label* materialize_false) const; | 853 void Plug(Label* materialize_true, Label* materialize_false) const override; |
| 864 virtual void Plug(Variable* var) const; | 854 void Plug(Variable* var) const override; |
| 865 virtual void Plug(Handle<Object> lit) const; | 855 void Plug(Handle<Object> lit) const override; |
| 866 virtual void Plug(Heap::RootListIndex) const; | 856 void Plug(Heap::RootListIndex) const override; |
| 867 virtual void PlugTOS() const; | 857 void PlugTOS() const override; |
| 868 virtual void DropAndPlug(int count, Register reg) const; | 858 void DropAndPlug(int count, Register reg) const override; |
| 869 virtual void PrepareTest(Label* materialize_true, | 859 void PrepareTest(Label* materialize_true, Label* materialize_false, |
| 870 Label* materialize_false, | 860 Label** if_true, Label** if_false, |
| 871 Label** if_true, | 861 Label** fall_through) const override; |
| 872 Label** if_false, | 862 bool IsStackValue() const override { return true; } |
| 873 Label** fall_through) const; | |
| 874 virtual bool IsStackValue() const { return true; } | |
| 875 }; | 863 }; |
| 876 | 864 |
| 877 class TestContext : public ExpressionContext { | 865 class TestContext : public ExpressionContext { |
| 878 public: | 866 public: |
| 879 TestContext(FullCodeGenerator* codegen, | 867 TestContext(FullCodeGenerator* codegen, |
| 880 Expression* condition, | 868 Expression* condition, |
| 881 Label* true_label, | 869 Label* true_label, |
| 882 Label* false_label, | 870 Label* false_label, |
| 883 Label* fall_through) | 871 Label* fall_through) |
| 884 : ExpressionContext(codegen), | 872 : ExpressionContext(codegen), |
| 885 condition_(condition), | 873 condition_(condition), |
| 886 true_label_(true_label), | 874 true_label_(true_label), |
| 887 false_label_(false_label), | 875 false_label_(false_label), |
| 888 fall_through_(fall_through) { } | 876 fall_through_(fall_through) { } |
| 889 | 877 |
| 890 static const TestContext* cast(const ExpressionContext* context) { | 878 static const TestContext* cast(const ExpressionContext* context) { |
| 891 DCHECK(context->IsTest()); | 879 DCHECK(context->IsTest()); |
| 892 return reinterpret_cast<const TestContext*>(context); | 880 return reinterpret_cast<const TestContext*>(context); |
| 893 } | 881 } |
| 894 | 882 |
| 895 Expression* condition() const { return condition_; } | 883 Expression* condition() const { return condition_; } |
| 896 Label* true_label() const { return true_label_; } | 884 Label* true_label() const { return true_label_; } |
| 897 Label* false_label() const { return false_label_; } | 885 Label* false_label() const { return false_label_; } |
| 898 Label* fall_through() const { return fall_through_; } | 886 Label* fall_through() const { return fall_through_; } |
| 899 | 887 |
| 900 virtual void Plug(bool flag) const; | 888 void Plug(bool flag) const override; |
| 901 virtual void Plug(Register reg) const; | 889 void Plug(Register reg) const override; |
| 902 virtual void Plug(Label* materialize_true, Label* materialize_false) const; | 890 void Plug(Label* materialize_true, Label* materialize_false) const override; |
| 903 virtual void Plug(Variable* var) const; | 891 void Plug(Variable* var) const override; |
| 904 virtual void Plug(Handle<Object> lit) const; | 892 void Plug(Handle<Object> lit) const override; |
| 905 virtual void Plug(Heap::RootListIndex) const; | 893 void Plug(Heap::RootListIndex) const override; |
| 906 virtual void PlugTOS() const; | 894 void PlugTOS() const override; |
| 907 virtual void DropAndPlug(int count, Register reg) const; | 895 void DropAndPlug(int count, Register reg) const override; |
| 908 virtual void PrepareTest(Label* materialize_true, | 896 void PrepareTest(Label* materialize_true, Label* materialize_false, |
| 909 Label* materialize_false, | 897 Label** if_true, Label** if_false, |
| 910 Label** if_true, | 898 Label** fall_through) const override; |
| 911 Label** if_false, | 899 bool IsTest() const override { return true; } |
| 912 Label** fall_through) const; | |
| 913 virtual bool IsTest() const { return true; } | |
| 914 | 900 |
| 915 private: | 901 private: |
| 916 Expression* condition_; | 902 Expression* condition_; |
| 917 Label* true_label_; | 903 Label* true_label_; |
| 918 Label* false_label_; | 904 Label* false_label_; |
| 919 Label* fall_through_; | 905 Label* fall_through_; |
| 920 }; | 906 }; |
| 921 | 907 |
| 922 class EffectContext : public ExpressionContext { | 908 class EffectContext : public ExpressionContext { |
| 923 public: | 909 public: |
| 924 explicit EffectContext(FullCodeGenerator* codegen) | 910 explicit EffectContext(FullCodeGenerator* codegen) |
| 925 : ExpressionContext(codegen) { } | 911 : ExpressionContext(codegen) { } |
| 926 | 912 |
| 927 virtual void Plug(bool flag) const; | 913 void Plug(bool flag) const override; |
| 928 virtual void Plug(Register reg) const; | 914 void Plug(Register reg) const override; |
| 929 virtual void Plug(Label* materialize_true, Label* materialize_false) const; | 915 void Plug(Label* materialize_true, Label* materialize_false) const override; |
| 930 virtual void Plug(Variable* var) const; | 916 void Plug(Variable* var) const override; |
| 931 virtual void Plug(Handle<Object> lit) const; | 917 void Plug(Handle<Object> lit) const override; |
| 932 virtual void Plug(Heap::RootListIndex) const; | 918 void Plug(Heap::RootListIndex) const override; |
| 933 virtual void PlugTOS() const; | 919 void PlugTOS() const override; |
| 934 virtual void DropAndPlug(int count, Register reg) const; | 920 void DropAndPlug(int count, Register reg) const override; |
| 935 virtual void PrepareTest(Label* materialize_true, | 921 void PrepareTest(Label* materialize_true, Label* materialize_false, |
| 936 Label* materialize_false, | 922 Label** if_true, Label** if_false, |
| 937 Label** if_true, | 923 Label** fall_through) const override; |
| 938 Label** if_false, | 924 bool IsEffect() const override { return true; } |
| 939 Label** fall_through) const; | |
| 940 virtual bool IsEffect() const { return true; } | |
| 941 }; | 925 }; |
| 942 | 926 |
| 943 class EnterBlockScopeIfNeeded { | 927 class EnterBlockScopeIfNeeded { |
| 944 public: | 928 public: |
| 945 EnterBlockScopeIfNeeded(FullCodeGenerator* codegen, Scope* scope, | 929 EnterBlockScopeIfNeeded(FullCodeGenerator* codegen, Scope* scope, |
| 946 BailoutId entry_id, BailoutId declarations_id, | 930 BailoutId entry_id, BailoutId declarations_id, |
| 947 BailoutId exit_id); | 931 BailoutId exit_id); |
| 948 ~EnterBlockScopeIfNeeded(); | 932 ~EnterBlockScopeIfNeeded(); |
| 949 | 933 |
| 950 private: | 934 private: |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1063 Address start_; | 1047 Address start_; |
| 1064 Address instruction_start_; | 1048 Address instruction_start_; |
| 1065 uint32_t length_; | 1049 uint32_t length_; |
| 1066 }; | 1050 }; |
| 1067 | 1051 |
| 1068 | 1052 |
| 1069 } // namespace internal | 1053 } // namespace internal |
| 1070 } // namespace v8 | 1054 } // namespace v8 |
| 1071 | 1055 |
| 1072 #endif // V8_FULL_CODEGEN_FULL_CODEGEN_H_ | 1056 #endif // V8_FULL_CODEGEN_FULL_CODEGEN_H_ |
| OLD | NEW |