| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 24 matching lines...) Expand all Loading... |
| 35 // Forward declarations | 35 // Forward declarations |
| 36 class CompilationInfo; | 36 class CompilationInfo; |
| 37 class DeferredCode; | 37 class DeferredCode; |
| 38 class RegisterAllocator; | 38 class RegisterAllocator; |
| 39 class RegisterFile; | 39 class RegisterFile; |
| 40 | 40 |
| 41 enum InitState { CONST_INIT, NOT_CONST_INIT }; | 41 enum InitState { CONST_INIT, NOT_CONST_INIT }; |
| 42 enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF }; | 42 enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF }; |
| 43 | 43 |
| 44 | 44 |
| 45 // ------------------------------------------------------------------------- | 45 // ----------------------------------------------------------------------------- |
| 46 // Reference support |
| 47 |
| 48 // A reference is a C++ stack-allocated object that keeps an ECMA |
| 49 // reference on the execution stack while in scope. For variables |
| 50 // the reference is empty, indicating that it isn't necessary to |
| 51 // store state on the stack for keeping track of references to those. |
| 52 // For properties, we keep either one (named) or two (indexed) values |
| 53 // on the execution stack to represent the reference. |
| 54 class Reference BASE_EMBEDDED { |
| 55 public: |
| 56 // The values of the types is important, see size(). |
| 57 enum Type { UNLOADED = -2, ILLEGAL = -1, SLOT = 0, NAMED = 1, KEYED = 2 }; |
| 58 Reference(CodeGenerator* cgen, |
| 59 Expression* expression, |
| 60 bool persist_after_get = false); |
| 61 ~Reference(); |
| 62 |
| 63 Expression* expression() const { return expression_; } |
| 64 Type type() const { return type_; } |
| 65 void set_type(Type value) { |
| 66 ASSERT_EQ(ILLEGAL, type_); |
| 67 type_ = value; |
| 68 } |
| 69 |
| 70 void set_unloaded() { |
| 71 ASSERT_NE(ILLEGAL, type_); |
| 72 ASSERT_NE(UNLOADED, type_); |
| 73 type_ = UNLOADED; |
| 74 } |
| 75 // The size the reference takes up on the stack. |
| 76 int size() const { |
| 77 return (type_ < SLOT) ? 0 : type_; |
| 78 } |
| 79 |
| 80 bool is_illegal() const { return type_ == ILLEGAL; } |
| 81 bool is_slot() const { return type_ == SLOT; } |
| 82 bool is_property() const { return type_ == NAMED || type_ == KEYED; } |
| 83 bool is_unloaded() const { return type_ == UNLOADED; } |
| 84 |
| 85 // Return the name. Only valid for named property references. |
| 86 Handle<String> GetName(); |
| 87 |
| 88 // Generate code to push the value of the reference on top of the |
| 89 // expression stack. The reference is expected to be already on top of |
| 90 // the expression stack, and it is consumed by the call unless the |
| 91 // reference is for a compound assignment. |
| 92 // If the reference is not consumed, it is left in place under its value. |
| 93 void GetValue(); |
| 94 |
| 95 // Generate code to pop a reference, push the value of the reference, |
| 96 // and then spill the stack frame. |
| 97 inline void GetValueAndSpill(); |
| 98 |
| 99 // Generate code to store the value on top of the expression stack in the |
| 100 // reference. The reference is expected to be immediately below the value |
| 101 // on the expression stack. The value is stored in the location specified |
| 102 // by the reference, and is left on top of the stack, after the reference |
| 103 // is popped from beneath it (unloaded). |
| 104 void SetValue(InitState init_state); |
| 105 |
| 106 private: |
| 107 CodeGenerator* cgen_; |
| 108 Expression* expression_; |
| 109 Type type_; |
| 110 // Keep the reference on the stack after get, so it can be used by set later. |
| 111 bool persist_after_get_; |
| 112 }; |
| 113 |
| 114 |
| 115 // ----------------------------------------------------------------------------- |
| 46 // Code generation state | 116 // Code generation state |
| 47 | 117 |
| 48 // The state is passed down the AST by the code generator (and back up, in | 118 // The state is passed down the AST by the code generator (and back up, in |
| 49 // the form of the state of the label pair). It is threaded through the | 119 // the form of the state of the label pair). It is threaded through the |
| 50 // call stack. Constructing a state implicitly pushes it on the owning code | 120 // call stack. Constructing a state implicitly pushes it on the owning code |
| 51 // generator's stack of states, and destroying one implicitly pops it. | 121 // generator's stack of states, and destroying one implicitly pops it. |
| 52 | 122 |
| 53 class CodeGenState BASE_EMBEDDED { | 123 class CodeGenState BASE_EMBEDDED { |
| 54 public: | 124 public: |
| 55 // Create an initial code generator state. Destroying the initial state | 125 // Create an initial code generator state. Destroying the initial state |
| (...skipping 26 matching lines...) Expand all Loading... |
| 82 JumpTarget* true_target_; | 152 JumpTarget* true_target_; |
| 83 JumpTarget* false_target_; | 153 JumpTarget* false_target_; |
| 84 | 154 |
| 85 // The previous state of the owning code generator, restored when | 155 // The previous state of the owning code generator, restored when |
| 86 // this state is destroyed. | 156 // this state is destroyed. |
| 87 CodeGenState* previous_; | 157 CodeGenState* previous_; |
| 88 }; | 158 }; |
| 89 | 159 |
| 90 | 160 |
| 91 | 161 |
| 92 // ------------------------------------------------------------------------- | 162 // ----------------------------------------------------------------------------- |
| 93 // CodeGenerator | 163 // CodeGenerator |
| 94 | 164 |
| 95 class CodeGenerator: public AstVisitor { | 165 class CodeGenerator: public AstVisitor { |
| 96 public: | 166 public: |
| 97 // Compilation mode. Either the compiler is used as the primary | 167 // Compilation mode. Either the compiler is used as the primary |
| 98 // compiler and needs to setup everything or the compiler is used as | 168 // compiler and needs to setup everything or the compiler is used as |
| 99 // the secondary compiler for split compilation and has to handle | 169 // the secondary compiler for split compilation and has to handle |
| 100 // bailouts. | 170 // bailouts. |
| 101 enum Mode { | 171 enum Mode { |
| 102 PRIMARY, | 172 PRIMARY, |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 | 215 |
| 146 CodeGenState* state() { return state_; } | 216 CodeGenState* state() { return state_; } |
| 147 void set_state(CodeGenState* state) { state_ = state; } | 217 void set_state(CodeGenState* state) { state_ = state; } |
| 148 | 218 |
| 149 void AddDeferred(DeferredCode* code) { deferred_.Add(code); } | 219 void AddDeferred(DeferredCode* code) { deferred_.Add(code); } |
| 150 | 220 |
| 151 static const int kUnknownIntValue = -1; | 221 static const int kUnknownIntValue = -1; |
| 152 | 222 |
| 153 // Number of instructions used for the JS return sequence. The constant is | 223 // Number of instructions used for the JS return sequence. The constant is |
| 154 // used by the debugger to patch the JS return sequence. | 224 // used by the debugger to patch the JS return sequence. |
| 155 static const int kJSReturnSequenceLength = 6; | 225 static const int kJSReturnSequenceLength = 7; |
| 156 | 226 |
| 157 // If the name is an inline runtime function call return the number of | 227 // If the name is an inline runtime function call return the number of |
| 158 // expected arguments. Otherwise return -1. | 228 // expected arguments. Otherwise return -1. |
| 159 static int InlineRuntimeCallArgumentsCount(Handle<String> name); | 229 static int InlineRuntimeCallArgumentsCount(Handle<String> name); |
| 160 | 230 |
| 161 private: | 231 private: |
| 162 // Construction/Destruction. | 232 // Construction/Destruction. |
| 163 explicit CodeGenerator(MacroAssembler* masm); | 233 explicit CodeGenerator(MacroAssembler* masm); |
| 164 | 234 |
| 165 // Accessors. | 235 // Accessors. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 179 int loop_nesting() const { return 0; } | 249 int loop_nesting() const { return 0; } |
| 180 | 250 |
| 181 // Node visitors. | 251 // Node visitors. |
| 182 void VisitStatements(ZoneList<Statement*>* statements); | 252 void VisitStatements(ZoneList<Statement*>* statements); |
| 183 | 253 |
| 184 #define DEF_VISIT(type) \ | 254 #define DEF_VISIT(type) \ |
| 185 void Visit##type(type* node); | 255 void Visit##type(type* node); |
| 186 AST_NODE_LIST(DEF_VISIT) | 256 AST_NODE_LIST(DEF_VISIT) |
| 187 #undef DEF_VISIT | 257 #undef DEF_VISIT |
| 188 | 258 |
| 259 // Visit a statement and then spill the virtual frame if control flow can |
| 260 // reach the end of the statement (ie, it does not exit via break, |
| 261 // continue, return, or throw). This function is used temporarily while |
| 262 // the code generator is being transformed. |
| 263 inline void VisitAndSpill(Statement* statement); |
| 264 |
| 265 // Visit a list of statements and then spill the virtual frame if control |
| 266 // flow can reach the end of the list. |
| 267 inline void VisitStatementsAndSpill(ZoneList<Statement*>* statements); |
| 268 |
| 189 // Main code generation function | 269 // Main code generation function |
| 190 void Generate(CompilationInfo* info); | 270 void Generate(CompilationInfo* info); |
| 191 | 271 |
| 272 // The following are used by class Reference. |
| 273 void LoadReference(Reference* ref); |
| 274 void UnloadReference(Reference* ref); |
| 275 |
| 276 MemOperand ContextOperand(Register context, int index) const { |
| 277 return MemOperand(context, Context::SlotOffset(index)); |
| 278 } |
| 279 |
| 280 MemOperand SlotOperand(Slot* slot, Register tmp); |
| 281 |
| 282 // Expressions |
| 283 MemOperand GlobalObject() const { |
| 284 return ContextOperand(cp, Context::GLOBAL_INDEX); |
| 285 } |
| 286 |
| 287 void LoadCondition(Expression* x, |
| 288 JumpTarget* true_target, |
| 289 JumpTarget* false_target, |
| 290 bool force_cc); |
| 291 void Load(Expression* x); |
| 292 void LoadGlobal(); |
| 293 |
| 294 // Generate code to push the value of an expression on top of the frame |
| 295 // and then spill the frame fully to memory. This function is used |
| 296 // temporarily while the code generator is being transformed. |
| 297 inline void LoadAndSpill(Expression* expression); |
| 298 |
| 299 // Read a value from a slot and leave it on top of the expression stack. |
| 300 void LoadFromSlot(Slot* slot, TypeofState typeof_state); |
| 301 // Store the value on top of the stack to a slot. |
| 302 void StoreToSlot(Slot* slot, InitState init_state); |
| 303 |
| 192 struct InlineRuntimeLUT { | 304 struct InlineRuntimeLUT { |
| 193 void (CodeGenerator::*method)(ZoneList<Expression*>*); | 305 void (CodeGenerator::*method)(ZoneList<Expression*>*); |
| 194 const char* name; | 306 const char* name; |
| 195 int nargs; | 307 int nargs; |
| 196 }; | 308 }; |
| 197 | 309 |
| 198 static InlineRuntimeLUT* FindInlineRuntimeLUT(Handle<String> name); | 310 static InlineRuntimeLUT* FindInlineRuntimeLUT(Handle<String> name); |
| 199 bool CheckForInlineRuntimeCall(CallRuntime* node); | 311 bool CheckForInlineRuntimeCall(CallRuntime* node); |
| 200 static bool PatchInlineRuntimeEntry(Handle<String> name, | 312 static bool PatchInlineRuntimeEntry(Handle<String> name, |
| 201 const InlineRuntimeLUT& new_entry, | 313 const InlineRuntimeLUT& new_entry, |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 283 | 395 |
| 284 Handle<Script> script_; | 396 Handle<Script> script_; |
| 285 List<DeferredCode*> deferred_; | 397 List<DeferredCode*> deferred_; |
| 286 | 398 |
| 287 // Assembler | 399 // Assembler |
| 288 MacroAssembler* masm_; // to generate code | 400 MacroAssembler* masm_; // to generate code |
| 289 | 401 |
| 290 CompilationInfo* info_; | 402 CompilationInfo* info_; |
| 291 | 403 |
| 292 // Code generation state | 404 // Code generation state |
| 293 Scope* scope_; | |
| 294 VirtualFrame* frame_; | 405 VirtualFrame* frame_; |
| 295 RegisterAllocator* allocator_; | 406 RegisterAllocator* allocator_; |
| 296 Condition cc_reg_; | 407 Condition cc_reg_; |
| 297 CodeGenState* state_; | 408 CodeGenState* state_; |
| 298 | 409 |
| 299 // Jump targets | 410 // Jump targets |
| 300 BreakTarget function_return_; | 411 BreakTarget function_return_; |
| 301 | 412 |
| 302 // True if the function return is shadowed (ie, jumping to the target | 413 // True if the function return is shadowed (ie, jumping to the target |
| 303 // function_return_ does not jump to the true function return, but rather | 414 // function_return_ does not jump to the true function return, but rather |
| 304 // to some unlinking code). | 415 // to some unlinking code). |
| 305 bool function_return_is_shadowed_; | 416 bool function_return_is_shadowed_; |
| 306 | 417 |
| 307 static InlineRuntimeLUT kInlineRuntimeLUT[]; | 418 static InlineRuntimeLUT kInlineRuntimeLUT[]; |
| 308 | 419 |
| 309 friend class VirtualFrame; | 420 friend class VirtualFrame; |
| 310 friend class JumpTarget; | 421 friend class JumpTarget; |
| 311 friend class Reference; | 422 friend class Reference; |
| 312 friend class FastCodeGenerator; | 423 friend class FastCodeGenerator; |
| 313 friend class FullCodeGenerator; | 424 friend class FullCodeGenerator; |
| 314 friend class FullCodeGenSyntaxChecker; | 425 friend class FullCodeGenSyntaxChecker; |
| 315 | 426 |
| 316 DISALLOW_COPY_AND_ASSIGN(CodeGenerator); | 427 DISALLOW_COPY_AND_ASSIGN(CodeGenerator); |
| 317 }; | 428 }; |
| 318 | 429 |
| 319 | 430 |
| 320 } } // namespace v8::internal | 431 } } // namespace v8::internal |
| 321 | 432 |
| 322 #endif // V8_MIPS_CODEGEN_MIPS_H_ | 433 #endif // V8_MIPS_CODEGEN_MIPS_H_ |
| OLD | NEW |