⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 codegen-arm.cc.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
// Copyright 2006-2008 the V8 project authors. All rights reserved.// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are// met:////     * Redistributions of source code must retain the above copyright//       notice, this list of conditions and the following disclaimer.//     * Redistributions in binary form must reproduce the above//       copyright notice, this list of conditions and the following//       disclaimer in the documentation and/or other materials provided//       with the distribution.//     * Neither the name of Google Inc. nor the names of its//       contributors may be used to endorse or promote products derived//       from this software without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#include "v8.h"#include "bootstrapper.h"#include "codegen-inl.h"#include "debug.h"#include "prettyprinter.h"#include "scopeinfo.h"#include "scopes.h"#include "runtime.h"namespace v8 { namespace internal {class ArmCodeGenerator;// -----------------------------------------------------------------------------// Reference support// A reference is a C++ stack-allocated object that keeps an ECMA// reference on the execution stack while in scope. For variables// the reference is empty, indicating that it isn't necessary to// store state on the stack for keeping track of references to those.// For properties, we keep either one (named) or two (indexed) values// on the execution stack to represent the reference.class Reference BASE_EMBEDDED { public:  enum Type { ILLEGAL = -1, EMPTY = 0, NAMED = 1, KEYED = 2 };  Reference(ArmCodeGenerator* cgen, Expression* expression);  ~Reference();  Expression* expression() const  { return expression_; }  Type type() const  { return type_; }  void set_type(Type value)  {    ASSERT(type_ == ILLEGAL);    type_ = value;  }  int size() const  { return type_; }  bool is_illegal() const  { return type_ == ILLEGAL; } private:  ArmCodeGenerator* cgen_;  Expression* expression_;  Type type_;};// -------------------------------------------------------------------------// Code generation state// The state is passed down the AST by the code generator.  It is passed// implicitly (in a member variable) to the non-static code generator member// functions, and explicitly (as an argument) to the static member functions// and the AST node member functions.//// The state is threaded through the call stack.  Constructing a state// implicitly pushes it on the owning code generator's stack of states, and// destroying one implicitly pops it.class CodeGenState BASE_EMBEDDED { public:  enum AccessType {    UNDEFINED,    LOAD,    LOAD_TYPEOF_EXPR  };  // Create an initial code generator state.  Destroying the initial state  // leaves the code generator with a NULL state.  explicit CodeGenState(ArmCodeGenerator* owner);  // Create a code generator state based on a code generator's current  // state.  The new state has its own access type and pair of branch  // labels, and no reference.  CodeGenState(ArmCodeGenerator* owner,               AccessType access,               Label* true_target,               Label* false_target);  // Create a code generator state based on a code generator's current  // state.  The new state has an access type of LOAD, its own reference,  // and inherits the pair of branch labels of the current state.  CodeGenState(ArmCodeGenerator* owner, Reference* ref);  // Destroy a code generator state and restore the owning code generator's  // previous state.  ~CodeGenState();  AccessType access() const { return access_; }  Reference* ref() const { return ref_; }  Label* true_target() const { return true_target_; }  Label* false_target() const { return false_target_; } private:  ArmCodeGenerator* owner_;  AccessType access_;  Reference* ref_;  Label* true_target_;  Label* false_target_;  CodeGenState* previous_;};// -----------------------------------------------------------------------------// ArmCodeGeneratorclass ArmCodeGenerator: public CodeGenerator { public:  static Handle<Code> MakeCode(FunctionLiteral* fun,                               Handle<Script> script,                               bool is_eval);  MacroAssembler* masm()  { return masm_; }  CodeGenState* state() { return state_; }  void set_state(CodeGenState* state) { state_ = state; } private:  // Assembler  MacroAssembler* masm_;  // to generate code  // Code generation state  Scope* scope_;  Condition cc_reg_;  CodeGenState* state_;  int break_stack_height_;  // Labels  Label function_return_;  // Construction/destruction  ArmCodeGenerator(int buffer_size,                   Handle<Script> script,                   bool is_eval);  virtual ~ArmCodeGenerator()  { delete masm_; }  // Main code generation function  void GenCode(FunctionLiteral* fun);  // The following are used by class Reference.  void LoadReference(Reference* ref);  void UnloadReference(Reference* ref);  // State  bool has_cc() const  { return cc_reg_ != al; }  CodeGenState::AccessType access() const  { return state_->access(); }  Reference* ref() const  { return state_->ref(); }  bool is_referenced() const { return state_->ref() != NULL; }  Label* true_target() const  { return state_->true_target(); }  Label* false_target() const  { return state_->false_target(); }  // Expressions  MemOperand GlobalObject() const  {    return ContextOperand(cp, Context::GLOBAL_INDEX);  }  static MemOperand ContextOperand(Register context, int index) {    return MemOperand(context, Context::SlotOffset(index));  }  static MemOperand ParameterOperand(Scope* scope, int index) {    // index -2 corresponds to the activated closure, -1 corresponds    // to the receiver    ASSERT(-2 <= index && index < scope->num_parameters());    int offset = (1 + scope->num_parameters() - index) * kPointerSize;    return MemOperand(fp, offset);  }  MemOperand ParameterOperand(int index) const {    return ParameterOperand(scope_, index);  }  MemOperand FunctionOperand() const {    return MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset);  }  static MemOperand SlotOperand(MacroAssembler* masm,                                Scope* scope,                                Slot* slot,                                Register tmp);  MemOperand SlotOperand(Slot* slot, Register tmp) {    return SlotOperand(masm_, scope_, slot, tmp);  }  void LoadCondition(Expression* x, CodeGenState::AccessType access,                     Label* true_target, Label* false_target, bool force_cc);  void Load(Expression* x,            CodeGenState::AccessType access = CodeGenState::LOAD);  void LoadGlobal();  // Special code for typeof expressions: Unfortunately, we must  // be careful when loading the expression in 'typeof'  // expressions. We are not allowed to throw reference errors for  // non-existing properties of the global object, so we must make it  // look like an explicit property access, instead of an access  // through the context chain.  void LoadTypeofExpression(Expression* x);  // References  // Generate code to fetch the value of a reference.  The reference is  // expected to be on top of the expression stack.  It is left in place and  // its value is pushed on top of it.  void GetValue(Reference* ref) {    ASSERT(!has_cc());    ASSERT(!ref->is_illegal());    CodeGenState new_state(this, ref);    Visit(ref->expression());  }  // Generate code to store a value in a reference.  The stored value is  // expected on top of the expression stack, with the reference immediately  // below it.  The expression stack is left unchanged.  void SetValue(Reference* ref) {    ASSERT(!has_cc());    ASSERT(!ref->is_illegal());    ref->expression()->GenerateStoreCode(masm_, scope_, ref, NOT_CONST_INIT);  }  // Generate code to store a value in a reference.  The stored value is  // expected on top of the expression stack, with the reference immediately  // below it.  The expression stack is left unchanged.  void InitConst(Reference* ref) {    ASSERT(!has_cc());    ASSERT(!ref->is_illegal());    ref->expression()->GenerateStoreCode(masm_, scope_, ref, CONST_INIT);  }  // Generate code to fetch a value from a property of a reference.  The  // reference is expected on top of the expression stack.  It is left in  // place and its value is pushed on top of it.  void GetReferenceProperty(Expression* key);  // Generate code to store a value in a property of a reference.  The  // stored value is expected on top of the expression stack, with the  // reference immediately below it.  The expression stack is left  // unchanged.  static void SetReferenceProperty(MacroAssembler* masm,                                   Reference* ref,                                   Expression* key);  void ToBoolean(Label* true_target, Label* false_target);  void GenericBinaryOperation(Token::Value op);  void Comparison(Condition cc, bool strict = false);  void SmiOperation(Token::Value op, Handle<Object> value, bool reversed);  void CallWithArguments(ZoneList<Expression*>* arguments, int position);  // Declare global variables and functions in the given array of  // name/value pairs.  virtual void DeclareGlobals(Handle<FixedArray> pairs);  // Instantiate the function boilerplate.  void InstantiateBoilerplate(Handle<JSFunction> boilerplate);  // Control flow  void Branch(bool if_true, Label* L);  void CheckStack();  void CleanStack(int num_bytes);  // Node visitors#define DEF_VISIT(type)                         \  virtual void Visit##type(type* node);  NODE_LIST(DEF_VISIT)#undef DEF_VISIT  void RecordStatementPosition(Node* node);  // Activation frames  void EnterJSFrame();  void ExitJSFrame();  virtual void GenerateIsSmi(ZoneList<Expression*>* args);  virtual void GenerateIsNonNegativeSmi(ZoneList<Expression*>* args);  virtual void GenerateIsArray(ZoneList<Expression*>* args);  virtual void GenerateArgumentsLength(ZoneList<Expression*>* args);  virtual void GenerateArgumentsAccess(ZoneList<Expression*>* args);  virtual void GenerateValueOf(ZoneList<Expression*>* args);  virtual void GenerateSetValueOf(ZoneList<Expression*>* args);  virtual void GenerateFastCharCodeAt(ZoneList<Expression*>* args);  virtual void GenerateObjectEquals(ZoneList<Expression*>* args);  friend class Reference;  friend class Property;  friend class VariableProxy;  friend class Slot;};// -------------------------------------------------------------------------// CodeGenState implementation.CodeGenState::CodeGenState(ArmCodeGenerator* owner)    : owner_(owner),      access_(UNDEFINED),      ref_(NULL),      true_target_(NULL),      false_target_(NULL),      previous_(NULL) {  owner_->set_state(this);}CodeGenState::CodeGenState(ArmCodeGenerator* owner,                           AccessType access,                           Label* true_target,                           Label* false_target)    : owner_(owner),      access_(access),      ref_(NULL),      true_target_(true_target),      false_target_(false_target),      previous_(owner->state()) {  owner_->set_state(this);}CodeGenState::CodeGenState(ArmCodeGenerator* owner, Reference* ref)    : owner_(owner),      access_(LOAD),      ref_(ref),      true_target_(owner->state()->true_target_),      false_target_(owner->state()->false_target_),      previous_(owner->state()) {  owner_->set_state(this);}CodeGenState::~CodeGenState() {  ASSERT(owner_->state() == this);  owner_->set_state(previous_);}// -----------------------------------------------------------------------------// ArmCodeGenerator implementation#define __  masm_->Handle<Code> ArmCodeGenerator::MakeCode(FunctionLiteral* flit,                                        Handle<Script> script,                                        bool is_eval) {#ifdef ENABLE_DISASSEMBLER  bool print_code = FLAG_print_code && !Bootstrapper::IsActive();#endif  // ENABLE_DISASSEMBLER#ifdef DEBUG

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -