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 32namespace v8 { 33namespace internal { 34 35// Forward declarations 36class CompilationInfo; 37class DeferredCode; 38class RegisterAllocator; 39class RegisterFile; 40 41enum InitState { CONST_INIT, NOT_CONST_INIT }; 42enum 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 53class 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 95class 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 void GenerateIsRegExp(ZoneList<Expression*>* args); 214 215 // Support for construct call checks. 216 void GenerateIsConstructCall(ZoneList<Expression*>* args); 217 218 // Support for arguments.length and arguments[?]. 219 void GenerateArgumentsLength(ZoneList<Expression*>* args); 220 void GenerateArgumentsAccess(ZoneList<Expression*>* args); 221 222 // Support for accessing the class and value fields of an object. 223 void GenerateClassOf(ZoneList<Expression*>* args); 224 void GenerateValueOf(ZoneList<Expression*>* args); 225 void GenerateSetValueOf(ZoneList<Expression*>* args); 226 227 // Fast support for charCodeAt(n). 228 void GenerateFastCharCodeAt(ZoneList<Expression*>* args); 229 230 // Fast support for object equality testing. 231 void GenerateObjectEquals(ZoneList<Expression*>* args); 232 233 void GenerateLog(ZoneList<Expression*>* args); 234 235 // Fast support for Math.random(). 236 void GenerateRandomPositiveSmi(ZoneList<Expression*>* args); 237 238 void GenerateIsObject(ZoneList<Expression*>* args); 239 void GenerateIsFunction(ZoneList<Expression*>* args); 240 void GenerateIsUndetectableObject(ZoneList<Expression*>* args); 241 void GenerateStringAdd(ZoneList<Expression*>* args); 242 void GenerateSubString(ZoneList<Expression*>* args); 243 void GenerateStringCompare(ZoneList<Expression*>* args); 244 void GenerateRegExpExec(ZoneList<Expression*>* args); 245 void GenerateNumberToString(ZoneList<Expression*>* args); 246 247 248 // Fast support for Math.sin and Math.cos. 249 inline void GenerateMathSin(ZoneList<Expression*>* args); 250 inline void GenerateMathCos(ZoneList<Expression*>* args); 251 252 // Simple condition analysis. 253 enum ConditionAnalysis { 254 ALWAYS_TRUE, 255 ALWAYS_FALSE, 256 DONT_KNOW 257 }; 258 ConditionAnalysis AnalyzeCondition(Expression* cond); 259 260 // Methods used to indicate which source code is generated for. Source 261 // positions are collected by the assembler and emitted with the relocation 262 // information. 263 void CodeForFunctionPosition(FunctionLiteral* fun); 264 void CodeForReturnPosition(FunctionLiteral* fun); 265 void CodeForStatementPosition(Statement* node); 266 void CodeForDoWhileConditionPosition(DoWhileStatement* stmt); 267 void CodeForSourcePosition(int pos); 268 269#ifdef DEBUG 270 // True if the registers are valid for entry to a block. 271 bool HasValidEntryRegisters(); 272#endif 273 274 bool is_eval_; // Tells whether code is generated for eval. 275 276 Handle<Script> script_; 277 List<DeferredCode*> deferred_; 278 279 // Assembler 280 MacroAssembler* masm_; // to generate code 281 282 CompilationInfo* info_; 283 284 // Code generation state 285 Scope* scope_; 286 VirtualFrame* frame_; 287 RegisterAllocator* allocator_; 288 Condition cc_reg_; 289 CodeGenState* state_; 290 291 // Jump targets 292 BreakTarget function_return_; 293 294 // True if the function return is shadowed (ie, jumping to the target 295 // function_return_ does not jump to the true function return, but rather 296 // to some unlinking code). 297 bool function_return_is_shadowed_; 298 299 static InlineRuntimeLUT kInlineRuntimeLUT[]; 300 301 friend class VirtualFrame; 302 friend class JumpTarget; 303 friend class Reference; 304 friend class FastCodeGenerator; 305 friend class FullCodeGenSyntaxChecker; 306 307 DISALLOW_COPY_AND_ASSIGN(CodeGenerator); 308}; 309 310 311} } // namespace v8::internal 312 313#endif // V8_MIPS_CODEGEN_MIPS_H_ 314