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 |