| OLD | NEW | 
|---|
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 20 matching lines...) Expand all  Loading... | 
| 31 #include "scopes.h" | 31 #include "scopes.h" | 
| 32 | 32 | 
| 33 namespace v8 { namespace internal { | 33 namespace v8 { namespace internal { | 
| 34 | 34 | 
| 35 // Forward declarations | 35 // Forward declarations | 
| 36 class DeferredCode; | 36 class DeferredCode; | 
| 37 | 37 | 
| 38 // Mode to overwrite BinaryExpression values. | 38 // Mode to overwrite BinaryExpression values. | 
| 39 enum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT }; | 39 enum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT }; | 
| 40 | 40 | 
|  | 41 enum InitState { CONST_INIT, NOT_CONST_INIT }; | 
|  | 42 enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF }; | 
| 41 | 43 | 
| 42 // ----------------------------------------------------------------------------- | 44 | 
|  | 45 // ------------------------------------------------------------------------- | 
|  | 46 // Virtual frame | 
|  | 47 | 
|  | 48 class VirtualFrame BASE_EMBEDDED { | 
|  | 49  public: | 
|  | 50   explicit VirtualFrame(CodeGenerator* cgen); | 
|  | 51 | 
|  | 52   void Enter(); | 
|  | 53   void Exit(); | 
|  | 54 | 
|  | 55   void AllocateLocals(); | 
|  | 56 | 
|  | 57   Operand Top() const { return Operand(esp, 0); } | 
|  | 58 | 
|  | 59   Operand Element(int index) const { | 
|  | 60     return Operand(esp, index * kPointerSize); | 
|  | 61   } | 
|  | 62 | 
|  | 63   Operand Local(int index) const { | 
|  | 64     ASSERT(0 <= index && index < frame_local_count_); | 
|  | 65     return Operand(ebp, kLocal0Offset - index * kPointerSize); | 
|  | 66   } | 
|  | 67 | 
|  | 68   Operand Function() const { return Operand(ebp, kFunctionOffset); } | 
|  | 69 | 
|  | 70   Operand Context() const { return Operand(ebp, kContextOffset); } | 
|  | 71 | 
|  | 72   Operand Parameter(int index) const { | 
|  | 73     ASSERT(-1 <= index && index < parameter_count_); | 
|  | 74     return Operand(ebp, (1 + parameter_count_ - index) * kPointerSize); | 
|  | 75   } | 
|  | 76 | 
|  | 77   Operand Receiver() const { return Parameter(-1); } | 
|  | 78 | 
|  | 79   inline void Drop(int count); | 
|  | 80 | 
|  | 81   inline void Pop(Register reg); | 
|  | 82   inline void Pop(Operand operand); | 
|  | 83 | 
|  | 84   inline void Push(Register reg); | 
|  | 85   inline void Push(Operand operand); | 
|  | 86   inline void Push(Immediate immediate); | 
|  | 87 | 
|  | 88  private: | 
|  | 89   static const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset; | 
|  | 90   static const int kFunctionOffset = JavaScriptFrameConstants::kFunctionOffset; | 
|  | 91   static const int kContextOffset = StandardFrameConstants::kContextOffset; | 
|  | 92 | 
|  | 93   MacroAssembler* masm_; | 
|  | 94   int frame_local_count_; | 
|  | 95   int parameter_count_; | 
|  | 96 }; | 
|  | 97 | 
|  | 98 | 
|  | 99 // ------------------------------------------------------------------------- | 
| 43 // Reference support | 100 // Reference support | 
| 44 | 101 | 
| 45 // A reference is a C++ stack-allocated object that keeps an ECMA | 102 // A reference is a C++ stack-allocated object that keeps an ECMA | 
| 46 // reference on the execution stack while in scope. For variables | 103 // reference on the execution stack while in scope. For variables | 
| 47 // the reference is empty, indicating that it isn't necessary to | 104 // the reference is empty, indicating that it isn't necessary to | 
| 48 // store state on the stack for keeping track of references to those. | 105 // store state on the stack for keeping track of references to those. | 
| 49 // For properties, we keep either one (named) or two (indexed) values | 106 // For properties, we keep either one (named) or two (indexed) values | 
| 50 // on the execution stack to represent the reference. | 107 // on the execution stack to represent the reference. | 
| 51 | 108 | 
| 52 enum InitState { CONST_INIT, NOT_CONST_INIT }; |  | 
| 53 enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF }; |  | 
| 54 |  | 
| 55 class Reference BASE_EMBEDDED { | 109 class Reference BASE_EMBEDDED { | 
| 56  public: | 110  public: | 
| 57   // The values of the types is important, see size(). | 111   // The values of the types is important, see size(). | 
| 58   enum Type { ILLEGAL = -1, SLOT = 0, NAMED = 1, KEYED = 2 }; | 112   enum Type { ILLEGAL = -1, SLOT = 0, NAMED = 1, KEYED = 2 }; | 
| 59   Reference(CodeGenerator* cgen, Expression* expression); | 113   Reference(CodeGenerator* cgen, Expression* expression); | 
| 60   ~Reference(); | 114   ~Reference(); | 
| 61 | 115 | 
| 62   Expression* expression() const { return expression_; } | 116   Expression* expression() const { return expression_; } | 
| 63   Type type() const { return type_; } | 117   Type type() const { return type_; } | 
| 64   void set_type(Type value) { | 118   void set_type(Type value) { | 
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 128   CodeGenerator* owner_; | 182   CodeGenerator* owner_; | 
| 129   TypeofState typeof_state_; | 183   TypeofState typeof_state_; | 
| 130   Label* true_target_; | 184   Label* true_target_; | 
| 131   Label* false_target_; | 185   Label* false_target_; | 
| 132   CodeGenState* previous_; | 186   CodeGenState* previous_; | 
| 133 }; | 187 }; | 
| 134 | 188 | 
| 135 | 189 | 
| 136 | 190 | 
| 137 | 191 | 
| 138 // ----------------------------------------------------------------------------- | 192 // ------------------------------------------------------------------------- | 
| 139 // CodeGenerator | 193 // CodeGenerator | 
| 140 | 194 | 
| 141 // |  | 
| 142 class CodeGenerator: public Visitor { | 195 class CodeGenerator: public Visitor { | 
| 143  public: | 196  public: | 
| 144   // Takes a function literal, generates code for it. This function should only | 197   // Takes a function literal, generates code for it. This function should only | 
| 145   // be called by compiler.cc. | 198   // be called by compiler.cc. | 
| 146   static Handle<Code> MakeCode(FunctionLiteral* fun, | 199   static Handle<Code> MakeCode(FunctionLiteral* fun, | 
| 147                                Handle<Script> script, | 200                                Handle<Script> script, | 
| 148                                bool is_eval); | 201                                bool is_eval); | 
| 149 | 202 | 
| 150   static void SetFunctionInfo(Handle<JSFunction> fun, | 203   static void SetFunctionInfo(Handle<JSFunction> fun, | 
| 151                               int length, | 204                               int length, | 
| 152                               int function_token_position, | 205                               int function_token_position, | 
| 153                               int start_position, | 206                               int start_position, | 
| 154                               int end_position, | 207                               int end_position, | 
| 155                               bool is_expression, | 208                               bool is_expression, | 
| 156                               bool is_toplevel, | 209                               bool is_toplevel, | 
| 157                               Handle<Script> script); | 210                               Handle<Script> script); | 
| 158 | 211 | 
| 159   // Accessors | 212   // Accessors | 
| 160   MacroAssembler* masm() { return masm_; } | 213   MacroAssembler* masm() { return masm_; } | 
| 161 | 214 | 
|  | 215   VirtualFrame* frame() const { return frame_; } | 
|  | 216 | 
| 162   CodeGenState* state() { return state_; } | 217   CodeGenState* state() { return state_; } | 
| 163   void set_state(CodeGenState* state) { state_ = state; } | 218   void set_state(CodeGenState* state) { state_ = state; } | 
| 164 | 219 | 
| 165   void AddDeferred(DeferredCode* code) { deferred_.Add(code); } | 220   void AddDeferred(DeferredCode* code) { deferred_.Add(code); } | 
| 166 | 221 | 
| 167  private: | 222  private: | 
| 168   // Construction/Destruction | 223   // Construction/Destruction | 
| 169   CodeGenerator(int buffer_size, Handle<Script> script, bool is_eval); | 224   CodeGenerator(int buffer_size, Handle<Script> script, bool is_eval); | 
| 170   virtual ~CodeGenerator() { delete masm_; } | 225   virtual ~CodeGenerator() { delete masm_; } | 
| 171 | 226 | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
| 189   NODE_LIST(DEF_VISIT) | 244   NODE_LIST(DEF_VISIT) | 
| 190 #undef DEF_VISIT | 245 #undef DEF_VISIT | 
| 191 | 246 | 
| 192   // Main code generation function | 247   // Main code generation function | 
| 193   void GenCode(FunctionLiteral* fun); | 248   void GenCode(FunctionLiteral* fun); | 
| 194 | 249 | 
| 195   // The following are used by class Reference. | 250   // The following are used by class Reference. | 
| 196   void LoadReference(Reference* ref); | 251   void LoadReference(Reference* ref); | 
| 197   void UnloadReference(Reference* ref); | 252   void UnloadReference(Reference* ref); | 
| 198 | 253 | 
| 199   // Support functions for accessing parameters and other operands. |  | 
| 200   Operand ParameterOperand(int index) const { |  | 
| 201     int num_parameters = scope()->num_parameters(); |  | 
| 202     ASSERT(-2 <= index && index < num_parameters); |  | 
| 203     return Operand(ebp, (1 + num_parameters - index) * kPointerSize); |  | 
| 204   } |  | 
| 205 |  | 
| 206   Operand ReceiverOperand() const { return ParameterOperand(-1); } |  | 
| 207 |  | 
| 208   Operand FunctionOperand() const { |  | 
| 209     return Operand(ebp, JavaScriptFrameConstants::kFunctionOffset); |  | 
| 210   } |  | 
| 211 |  | 
| 212   Operand ContextOperand(Register context, int index) const { | 254   Operand ContextOperand(Register context, int index) const { | 
| 213     return Operand(context, Context::SlotOffset(index)); | 255     return Operand(context, Context::SlotOffset(index)); | 
| 214   } | 256   } | 
| 215 | 257 | 
| 216   Operand SlotOperand(Slot* slot, Register tmp); | 258   Operand SlotOperand(Slot* slot, Register tmp); | 
| 217 | 259 | 
| 218 | 260 | 
| 219   // Expressions | 261   // Expressions | 
| 220   Operand GlobalObject() const { | 262   Operand GlobalObject() const { | 
| 221     return ContextOperand(esi, Context::GLOBAL_INDEX); | 263     return ContextOperand(esi, Context::GLOBAL_INDEX); | 
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 342   // permits optimization and calls GenerateFastCaseSwitch if it does. | 384   // permits optimization and calls GenerateFastCaseSwitch if it does. | 
| 343   // Returns true if the fast-case switch was generated, and false if not. | 385   // Returns true if the fast-case switch was generated, and false if not. | 
| 344   bool TryGenerateFastCaseSwitchStatement(SwitchStatement *node); | 386   bool TryGenerateFastCaseSwitchStatement(SwitchStatement *node); | 
| 345 | 387 | 
| 346 | 388 | 
| 347   // Bottle-neck interface to call the Assembler to generate the statement | 389   // Bottle-neck interface to call the Assembler to generate the statement | 
| 348   // position. This allows us to easily control whether statement positions | 390   // position. This allows us to easily control whether statement positions | 
| 349   // should be generated or not. | 391   // should be generated or not. | 
| 350   void RecordStatementPosition(Node* node); | 392   void RecordStatementPosition(Node* node); | 
| 351 | 393 | 
| 352   // Activation frames. |  | 
| 353   void EnterJSFrame(); |  | 
| 354   void ExitJSFrame(); |  | 
| 355 |  | 
| 356 |  | 
| 357   bool is_eval_;  // Tells whether code is generated for eval. | 394   bool is_eval_;  // Tells whether code is generated for eval. | 
| 358   Handle<Script> script_; | 395   Handle<Script> script_; | 
| 359   List<DeferredCode*> deferred_; | 396   List<DeferredCode*> deferred_; | 
| 360 | 397 | 
| 361   // Assembler | 398   // Assembler | 
| 362   MacroAssembler* masm_;  // to generate code | 399   MacroAssembler* masm_;  // to generate code | 
| 363 | 400 | 
| 364   // Code generation state | 401   // Code generation state | 
| 365   Scope* scope_; | 402   Scope* scope_; | 
|  | 403   VirtualFrame* frame_; | 
| 366   Condition cc_reg_; | 404   Condition cc_reg_; | 
| 367   CodeGenState* state_; | 405   CodeGenState* state_; | 
| 368   bool is_inside_try_; | 406   bool is_inside_try_; | 
| 369   int break_stack_height_; | 407   int break_stack_height_; | 
| 370 | 408 | 
| 371   // Labels | 409   // Labels | 
| 372   Label function_return_; | 410   Label function_return_; | 
| 373 | 411 | 
|  | 412   friend class VirtualFrame; | 
| 374   friend class Reference; | 413   friend class Reference; | 
| 375   friend class Property; |  | 
| 376   friend class VariableProxy; |  | 
| 377   friend class Slot; |  | 
| 378 | 414 | 
| 379   DISALLOW_COPY_AND_ASSIGN(CodeGenerator); | 415   DISALLOW_COPY_AND_ASSIGN(CodeGenerator); | 
| 380 }; | 416 }; | 
| 381 | 417 | 
| 382 | 418 | 
| 383 } }  // namespace v8::internal | 419 } }  // namespace v8::internal | 
| 384 | 420 | 
| 385 #endif  // V8_CODEGEN_IA32_H_ | 421 #endif  // V8_CODEGEN_IA32_H_ | 
| OLD | NEW | 
|---|