| OLD | NEW | 
| (Empty) |  | 
 |    1 // Copyright 2010 the V8 project authors. All rights reserved. | 
 |    2 // Redistribution and use in source and binary forms, with or without | 
 |    3 // modification, are permitted provided that the following conditions are | 
 |    4 // met: | 
 |    5 // | 
 |    6 //     * Redistributions of source code must retain the above copyright | 
 |    7 //       notice, this list of conditions and the following disclaimer. | 
 |    8 //     * Redistributions in binary form must reproduce the above | 
 |    9 //       copyright notice, this list of conditions and the following | 
 |   10 //       disclaimer in the documentation and/or other materials provided | 
 |   11 //       with the distribution. | 
 |   12 //     * Neither the name of Google Inc. nor the names of its | 
 |   13 //       contributors may be used to endorse or promote products derived | 
 |   14 //       from this software without specific prior written permission. | 
 |   15 // | 
 |   16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 
 |   17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 
 |   18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 
 |   19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 
 |   20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 
 |   21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 
 |   22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
 |   23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
 |   24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
 |   25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
 |   26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
 |   27  | 
 |   28  | 
 |   29 #ifndef V8_MIPS_CODEGEN_MIPS_H_ | 
 |   30 #define V8_MIPS_CODEGEN_MIPS_H_ | 
 |   31  | 
 |   32 namespace v8 { | 
 |   33 namespace internal { | 
 |   34  | 
 |   35 // Forward declarations | 
 |   36 class CompilationInfo; | 
 |   37 class DeferredCode; | 
 |   38 class RegisterAllocator; | 
 |   39 class RegisterFile; | 
 |   40  | 
 |   41 enum InitState { CONST_INIT, NOT_CONST_INIT }; | 
 |   42 enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF }; | 
 |   43  | 
 |   44  | 
 |   45 // ------------------------------------------------------------------------- | 
 |   46 // Code generation state | 
 |   47  | 
 |   48 // 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 | 
 |   50 // call stack.  Constructing a state implicitly pushes it on the owning code | 
 |   51 // generator's stack of states, and destroying one implicitly pops it. | 
 |   52  | 
 |   53 class CodeGenState BASE_EMBEDDED { | 
 |   54  public: | 
 |   55   // Create an initial code generator state.  Destroying the initial state | 
 |   56   // leaves the code generator with a NULL state. | 
 |   57   explicit CodeGenState(CodeGenerator* owner); | 
 |   58  | 
 |   59   // Create a code generator state based on a code generator's current | 
 |   60   // state.  The new state has its own typeof state and pair of branch | 
 |   61   // labels. | 
 |   62   CodeGenState(CodeGenerator* owner, | 
 |   63                JumpTarget* true_target, | 
 |   64                JumpTarget* false_target); | 
 |   65  | 
 |   66   // Destroy a code generator state and restore the owning code generator's | 
 |   67   // previous state. | 
 |   68   ~CodeGenState(); | 
 |   69  | 
 |   70   TypeofState typeof_state() const { return typeof_state_; } | 
 |   71   JumpTarget* true_target() const { return true_target_; } | 
 |   72   JumpTarget* false_target() const { return false_target_; } | 
 |   73  | 
 |   74  private: | 
 |   75   // The owning code generator. | 
 |   76   CodeGenerator* owner_; | 
 |   77  | 
 |   78   // A flag indicating whether we are compiling the immediate subexpression | 
 |   79   // of a typeof expression. | 
 |   80   TypeofState typeof_state_; | 
 |   81  | 
 |   82   JumpTarget* true_target_; | 
 |   83   JumpTarget* false_target_; | 
 |   84  | 
 |   85   // The previous state of the owning code generator, restored when | 
 |   86   // this state is destroyed. | 
 |   87   CodeGenState* previous_; | 
 |   88 }; | 
 |   89  | 
 |   90  | 
 |   91  | 
 |   92 // ------------------------------------------------------------------------- | 
 |   93 // CodeGenerator | 
 |   94  | 
 |   95 class CodeGenerator: public AstVisitor { | 
 |   96  public: | 
 |   97   // Compilation mode.  Either the compiler is used as the primary | 
 |   98   // compiler and needs to setup everything or the compiler is used as | 
 |   99   // the secondary compiler for split compilation and has to handle | 
 |  100   // bailouts. | 
 |  101   enum Mode { | 
 |  102     PRIMARY, | 
 |  103     SECONDARY | 
 |  104   }; | 
 |  105  | 
 |  106   // Takes a function literal, generates code for it. This function should only | 
 |  107   // be called by compiler.cc. | 
 |  108   static Handle<Code> MakeCode(CompilationInfo* info); | 
 |  109  | 
 |  110   // Printing of AST, etc. as requested by flags. | 
 |  111   static void MakeCodePrologue(CompilationInfo* info); | 
 |  112  | 
 |  113   // Allocate and install the code. | 
 |  114   static Handle<Code> MakeCodeEpilogue(MacroAssembler* masm, | 
 |  115                                        Code::Flags flags, | 
 |  116                                        CompilationInfo* info); | 
 |  117  | 
 |  118 #ifdef ENABLE_LOGGING_AND_PROFILING | 
 |  119   static bool ShouldGenerateLog(Expression* type); | 
 |  120 #endif | 
 |  121  | 
 |  122   static void SetFunctionInfo(Handle<JSFunction> fun, | 
 |  123                               FunctionLiteral* lit, | 
 |  124                               bool is_toplevel, | 
 |  125                               Handle<Script> script); | 
 |  126  | 
 |  127   static void RecordPositions(MacroAssembler* masm, int pos); | 
 |  128  | 
 |  129   // Accessors | 
 |  130   MacroAssembler* masm() { return masm_; } | 
 |  131   VirtualFrame* frame() const { return frame_; } | 
 |  132   inline Handle<Script> script(); | 
 |  133  | 
 |  134   bool has_valid_frame() const { return frame_ != NULL; } | 
 |  135  | 
 |  136   // Set the virtual frame to be new_frame, with non-frame register | 
 |  137   // reference counts given by non_frame_registers.  The non-frame | 
 |  138   // register reference counts of the old frame are returned in | 
 |  139   // non_frame_registers. | 
 |  140   void SetFrame(VirtualFrame* new_frame, RegisterFile* non_frame_registers); | 
 |  141  | 
 |  142   void DeleteFrame(); | 
 |  143  | 
 |  144   RegisterAllocator* allocator() const { return allocator_; } | 
 |  145  | 
 |  146   CodeGenState* state() { return state_; } | 
 |  147   void set_state(CodeGenState* state) { state_ = state; } | 
 |  148  | 
 |  149   void AddDeferred(DeferredCode* code) { deferred_.Add(code); } | 
 |  150  | 
 |  151   static const int kUnknownIntValue = -1; | 
 |  152  | 
 |  153   // Number of instructions used for the JS return sequence. The constant is | 
 |  154   // used by the debugger to patch the JS return sequence. | 
 |  155   static const int kJSReturnSequenceLength = 6; | 
 |  156  | 
 |  157  private: | 
 |  158   // Construction/Destruction. | 
 |  159   explicit CodeGenerator(MacroAssembler* masm); | 
 |  160   virtual ~CodeGenerator() { delete masm_; } | 
 |  161  | 
 |  162   // Accessors. | 
 |  163   inline bool is_eval(); | 
 |  164   Scope* scope() const { return scope_; } | 
 |  165  | 
 |  166   // Generating deferred code. | 
 |  167   void ProcessDeferred(); | 
 |  168  | 
 |  169   // State | 
 |  170   bool has_cc() const  { return cc_reg_ != cc_always; } | 
 |  171   TypeofState typeof_state() const { return state_->typeof_state(); } | 
 |  172   JumpTarget* true_target() const  { return state_->true_target(); } | 
 |  173   JumpTarget* false_target() const  { return state_->false_target(); } | 
 |  174  | 
 |  175   // We don't track loop nesting level on mips yet. | 
 |  176   int loop_nesting() const { return 0; } | 
 |  177  | 
 |  178   // Node visitors. | 
 |  179   void VisitStatements(ZoneList<Statement*>* statements); | 
 |  180  | 
 |  181 #define DEF_VISIT(type) \ | 
 |  182   void Visit##type(type* node); | 
 |  183   AST_NODE_LIST(DEF_VISIT) | 
 |  184 #undef DEF_VISIT | 
 |  185  | 
 |  186   // Main code generation function | 
 |  187   void Generate(CompilationInfo* info, Mode mode); | 
 |  188  | 
 |  189   struct InlineRuntimeLUT { | 
 |  190     void (CodeGenerator::*method)(ZoneList<Expression*>*); | 
 |  191     const char* name; | 
 |  192   }; | 
 |  193  | 
 |  194   static InlineRuntimeLUT* FindInlineRuntimeLUT(Handle<String> name); | 
 |  195   bool CheckForInlineRuntimeCall(CallRuntime* node); | 
 |  196   static bool PatchInlineRuntimeEntry(Handle<String> name, | 
 |  197                                       const InlineRuntimeLUT& new_entry, | 
 |  198                                       InlineRuntimeLUT* old_entry); | 
 |  199  | 
 |  200   static Handle<Code> ComputeLazyCompile(int argc); | 
 |  201   void ProcessDeclarations(ZoneList<Declaration*>* declarations); | 
 |  202  | 
 |  203   Handle<Code> ComputeCallInitialize(int argc, InLoopFlag in_loop); | 
 |  204  | 
 |  205   // Declare global variables and functions in the given array of | 
 |  206   // name/value pairs. | 
 |  207   void DeclareGlobals(Handle<FixedArray> pairs); | 
 |  208  | 
 |  209   // Support for type checks. | 
 |  210   void GenerateIsSmi(ZoneList<Expression*>* args); | 
 |  211   void GenerateIsNonNegativeSmi(ZoneList<Expression*>* args); | 
 |  212   void GenerateIsArray(ZoneList<Expression*>* args); | 
 |  213  | 
 |  214   // Support for construct call checks. | 
 |  215   void GenerateIsConstructCall(ZoneList<Expression*>* args); | 
 |  216  | 
 |  217   // Support for arguments.length and arguments[?]. | 
 |  218   void GenerateArgumentsLength(ZoneList<Expression*>* args); | 
 |  219   void GenerateArgumentsAccess(ZoneList<Expression*>* args); | 
 |  220  | 
 |  221   // Support for accessing the class and value fields of an object. | 
 |  222   void GenerateClassOf(ZoneList<Expression*>* args); | 
 |  223   void GenerateValueOf(ZoneList<Expression*>* args); | 
 |  224   void GenerateSetValueOf(ZoneList<Expression*>* args); | 
 |  225  | 
 |  226   // Fast support for charCodeAt(n). | 
 |  227   void GenerateFastCharCodeAt(ZoneList<Expression*>* args); | 
 |  228  | 
 |  229   // Fast support for object equality testing. | 
 |  230   void GenerateObjectEquals(ZoneList<Expression*>* args); | 
 |  231  | 
 |  232   void GenerateLog(ZoneList<Expression*>* args); | 
 |  233  | 
 |  234   // Fast support for Math.random(). | 
 |  235   void GenerateRandomPositiveSmi(ZoneList<Expression*>* args); | 
 |  236  | 
 |  237   void GenerateIsObject(ZoneList<Expression*>* args); | 
 |  238   void GenerateIsFunction(ZoneList<Expression*>* args); | 
 |  239   void GenerateIsUndetectableObject(ZoneList<Expression*>* args); | 
 |  240   void GenerateStringAdd(ZoneList<Expression*>* args); | 
 |  241   void GenerateSubString(ZoneList<Expression*>* args); | 
 |  242   void GenerateStringCompare(ZoneList<Expression*>* args); | 
 |  243   void GenerateRegExpExec(ZoneList<Expression*>* args); | 
 |  244  | 
 |  245   // Fast support for Math.sin and Math.cos. | 
 |  246   inline void GenerateMathSin(ZoneList<Expression*>* args); | 
 |  247   inline void GenerateMathCos(ZoneList<Expression*>* args); | 
 |  248  | 
 |  249   // Simple condition analysis. | 
 |  250   enum ConditionAnalysis { | 
 |  251     ALWAYS_TRUE, | 
 |  252     ALWAYS_FALSE, | 
 |  253     DONT_KNOW | 
 |  254   }; | 
 |  255   ConditionAnalysis AnalyzeCondition(Expression* cond); | 
 |  256  | 
 |  257   // Methods used to indicate which source code is generated for. Source | 
 |  258   // positions are collected by the assembler and emitted with the relocation | 
 |  259   // information. | 
 |  260   void CodeForFunctionPosition(FunctionLiteral* fun); | 
 |  261   void CodeForReturnPosition(FunctionLiteral* fun); | 
 |  262   void CodeForStatementPosition(Statement* node); | 
 |  263   void CodeForDoWhileConditionPosition(DoWhileStatement* stmt); | 
 |  264   void CodeForSourcePosition(int pos); | 
 |  265  | 
 |  266 #ifdef DEBUG | 
 |  267   // True if the registers are valid for entry to a block. | 
 |  268   bool HasValidEntryRegisters(); | 
 |  269 #endif | 
 |  270  | 
 |  271   bool is_eval_;  // Tells whether code is generated for eval. | 
 |  272  | 
 |  273   Handle<Script> script_; | 
 |  274   List<DeferredCode*> deferred_; | 
 |  275  | 
 |  276   // Assembler | 
 |  277   MacroAssembler* masm_;  // to generate code | 
 |  278  | 
 |  279   CompilationInfo* info_; | 
 |  280  | 
 |  281   // Code generation state | 
 |  282   Scope* scope_; | 
 |  283   VirtualFrame* frame_; | 
 |  284   RegisterAllocator* allocator_; | 
 |  285   Condition cc_reg_; | 
 |  286   CodeGenState* state_; | 
 |  287  | 
 |  288   // Jump targets | 
 |  289   BreakTarget function_return_; | 
 |  290  | 
 |  291   // True if the function return is shadowed (ie, jumping to the target | 
 |  292   // function_return_ does not jump to the true function return, but rather | 
 |  293   // to some unlinking code). | 
 |  294   bool function_return_is_shadowed_; | 
 |  295  | 
 |  296   static InlineRuntimeLUT kInlineRuntimeLUT[]; | 
 |  297  | 
 |  298   friend class VirtualFrame; | 
 |  299   friend class JumpTarget; | 
 |  300   friend class Reference; | 
 |  301   friend class FastCodeGenerator; | 
 |  302   friend class FullCodeGenSyntaxChecker; | 
 |  303  | 
 |  304   DISALLOW_COPY_AND_ASSIGN(CodeGenerator); | 
 |  305 }; | 
 |  306  | 
 |  307  | 
 |  308 } }  // namespace v8::internal | 
 |  309  | 
 |  310 #endif  // V8_MIPS_CODEGEN_MIPS_H_ | 
 |  311  | 
| OLD | NEW |