// 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.

#ifndef V8_CODEGEN_H_
#define V8_CODEGEN_H_

#include "ast.h"
#include "code-stubs.h"
#include "runtime.h"

// Include the declaration of the architecture defined class CodeGenerator.
// The contract  to the shared code is that the the CodeGenerator is a subclass
// of Visitor and that the following methods are available publicly:
//   MakeCode
//   MakeCodePrologue
//   MakeCodeEpilogue
//   masm
//   frame
//   script
//   has_valid_frame
//   SetFrame
//   DeleteFrame
//   allocator
//   AddDeferred
//   in_spilled_code
//   set_in_spilled_code
//   RecordPositions
//
// These methods are either used privately by the shared code or implemented as
// shared code:
//   CodeGenerator
//   ~CodeGenerator
//   ProcessDeferred
//   Generate
//   ComputeLazyCompile
//   BuildBoilerplate
//   ComputeCallInitialize
//   ComputeCallInitializeInLoop
//   ProcessDeclarations
//   DeclareGlobals
//   FindInlineRuntimeLUT
//   CheckForInlineRuntimeCall
//   PatchInlineRuntimeEntry
//   AnalyzeCondition
//   CodeForFunctionPosition
//   CodeForReturnPosition
//   CodeForStatementPosition
//   CodeForDoWhileConditionPosition
//   CodeForSourcePosition


// Mode to overwrite BinaryExpression values.
enum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT };

// Types of uncatchable exceptions.
enum UncatchableExceptionType { OUT_OF_MEMORY, TERMINATION };


#if V8_TARGET_ARCH_IA32
#include "ia32/codegen-ia32.h"
#elif V8_TARGET_ARCH_X64
#include "x64/codegen-x64.h"
#elif V8_TARGET_ARCH_ARM
#include "arm/codegen-arm.h"
#elif V8_TARGET_ARCH_MIPS
#include "mips/codegen-mips.h"
#else
#error Unsupported target architecture.
#endif

#include "register-allocator.h"

namespace v8 {
namespace internal {


// Support for "structured" code comments.
#ifdef DEBUG

class Comment BASE_EMBEDDED {
 public:
  Comment(MacroAssembler* masm, const char* msg);
  ~Comment();

 private:
  MacroAssembler* masm_;
  const char* msg_;
};

#else

class Comment BASE_EMBEDDED {
 public:
  Comment(MacroAssembler*, const char*)  {}
};

#endif  // DEBUG


// Code generation can be nested.  Code generation scopes form a stack
// of active code generators.
class CodeGeneratorScope BASE_EMBEDDED {
 public:
  explicit CodeGeneratorScope(CodeGenerator* cgen) {
    previous_ = top_;
    top_ = cgen;
  }

  ~CodeGeneratorScope() {
    top_ = previous_;
  }

  static CodeGenerator* Current() {
    ASSERT(top_ != NULL);
    return top_;
  }

 private:
  static CodeGenerator* top_;
  CodeGenerator* previous_;
};


// Deferred code objects are small pieces of code that are compiled
// out of line. They are used to defer the compilation of uncommon
// paths thereby avoiding expensive jumps around uncommon code parts.
class DeferredCode: public ZoneObject {
 public:
  DeferredCode();
  virtual ~DeferredCode() { }

  virtual void Generate() = 0;

  MacroAssembler* masm() { return masm_; }

  int statement_position() const { return statement_position_; }
  int position() const { return position_; }

  Label* entry_label() { return &entry_label_; }
  Label* exit_label() { return &exit_label_; }

#ifdef DEBUG
  void set_comment(const char* comment) { comment_ = comment; }
  const char* comment() const { return comment_; }
#else
  void set_comment(const char* comment) { }
  const char* comment() const { return ""; }
#endif

  inline void Jump();
  inline void Branch(Condition cc);
  void BindExit() { masm_->bind(&exit_label_); }

  void SaveRegisters();
  void RestoreRegisters();

 protected:
  MacroAssembler* masm_;

 private:
  // Constants indicating special actions.  They should not be multiples
  // of kPointerSize so they will not collide with valid offsets from
  // the frame pointer.
  static const int kIgnore = -1;
  static const int kPush = 1;

  // This flag is ored with a valid offset from the frame pointer, so
  // it should fit in the low zero bits of a valid offset.
  static const int kSyncedFlag = 2;

  int statement_position_;
  int position_;

  Label entry_label_;
  Label exit_label_;

  int registers_[RegisterAllocator::kNumRegisters];

#ifdef DEBUG
  const char* comment_;
#endif
  DISALLOW_COPY_AND_ASSIGN(DeferredCode);
};

class StackCheckStub : public CodeStub {
 public:
  StackCheckStub() { }

  void Generate(MacroAssembler* masm);

 private:

  const char* GetName() { return "StackCheckStub"; }

  Major MajorKey() { return StackCheck; }
  int MinorKey() { return 0; }
};


class FastNewClosureStub : public CodeStub {
 public:
  void Generate(MacroAssembler* masm);

 private:
  const char* GetName() { return "FastNewClosureStub"; }
  Major MajorKey() { return FastNewClosure; }
  int MinorKey() { return 0; }
};


class FastNewContextStub : public CodeStub {
 public:
  static const int kMaximumSlots = 64;

  explicit FastNewContextStub(int slots) : slots_(slots) {
    ASSERT(slots_ > 0 && slots <= kMaximumSlots);
  }

  void Generate(MacroAssembler* masm);

 private:
  int slots_;

  const char* GetName() { return "FastNewContextStub"; }
  Major MajorKey() { return FastNewContext; }
  int MinorKey() { return slots_; }
};


class FastCloneShallowArrayStub : public CodeStub {
 public:
  static const int kMaximumLength = 8;

  explicit FastCloneShallowArrayStub(int length) : length_(length) {
    ASSERT(length >= 0 && length <= kMaximumLength);
  }

  void Generate(MacroAssembler* masm);

 private:
  int length_;

  const char* GetName() { return "FastCloneShallowArrayStub"; }
  Major MajorKey() { return FastCloneShallowArray; }
  int MinorKey() { return length_; }
};


class InstanceofStub: public CodeStub {
 public:
  InstanceofStub() { }

  void Generate(MacroAssembler* masm);

 private:
  Major MajorKey() { return Instanceof; }
  int MinorKey() { return 0; }
};


class GenericUnaryOpStub : public CodeStub {
 public:
  GenericUnaryOpStub(Token::Value op, bool overwrite)
      : op_(op), overwrite_(overwrite) { }

 private:
  Token::Value op_;
  bool overwrite_;

  class OverwriteField: public BitField<int, 0, 1> {};
  class OpField: public BitField<Token::Value, 1, kMinorBits - 1> {};

  Major MajorKey() { return GenericUnaryOp; }
  int MinorKey() {
    return OpField::encode(op_) | OverwriteField::encode(overwrite_);
  }

  void Generate(MacroAssembler* masm);

  const char* GetName();
};


enum NaNInformation {
  kBothCouldBeNaN,
  kCantBothBeNaN
};


class CompareStub: public CodeStub {
 public:
  CompareStub(Condition cc,
              bool strict,
              NaNInformation nan_info = kBothCouldBeNaN) :
      cc_(cc), strict_(strict), never_nan_nan_(nan_info == kCantBothBeNaN) { }

  void Generate(MacroAssembler* masm);

 private:
  Condition cc_;
  bool strict_;
  // Only used for 'equal' comparisons.  Tells the stub that we already know
  // that at least one side of the comparison is not NaN.  This allows the
  // stub to use object identity in the positive case.  We ignore it when
  // generating the minor key for other comparisons to avoid creating more
  // stubs.
  bool never_nan_nan_;

  Major MajorKey() { return Compare; }

  int MinorKey();

  // Branch to the label if the given object isn't a symbol.
  void BranchIfNonSymbol(MacroAssembler* masm,
                         Label* label,
                         Register object,
                         Register scratch);

  // Unfortunately you have to run without snapshots to see most of these
  // names in the profile since most compare stubs end up in the snapshot.
  const char* GetName();
#ifdef DEBUG
  void Print() {
    PrintF("CompareStub (cc %d), (strict %s)\n",
           static_cast<int>(cc_),
           strict_ ? "true" : "false");
  }
#endif
};


class CEntryStub : public CodeStub {
 public:
  explicit CEntryStub(int result_size,
                      ExitFrame::Mode mode = ExitFrame::MODE_NORMAL)
      : result_size_(result_size), mode_(mode) { }

  void Generate(MacroAssembler* masm);

 private:
  void GenerateCore(MacroAssembler* masm,
                    Label* throw_normal_exception,
                    Label* throw_termination_exception,
                    Label* throw_out_of_memory_exception,
                    bool do_gc,
                    bool always_allocate_scope);
  void GenerateThrowTOS(MacroAssembler* masm);
  void GenerateThrowUncatchable(MacroAssembler* masm,
                                UncatchableExceptionType type);

  // Number of pointers/values returned.
  const int result_size_;
  const ExitFrame::Mode mode_;

  // Minor key encoding
  class ExitFrameModeBits: public BitField<ExitFrame::Mode, 0, 1> {};
  class IndirectResultBits: public BitField<bool, 1, 1> {};

  Major MajorKey() { return CEntry; }
  // Minor key must differ if different result_size_ values means different
  // code is generated.
  int MinorKey();

  const char* GetName() { return "CEntryStub"; }
};


class ApiGetterEntryStub : public CodeStub {
 public:
  ApiGetterEntryStub(Handle<AccessorInfo> info,
                     ApiFunction* fun)
      : info_(info),
        fun_(fun) { }
  void Generate(MacroAssembler* masm);
  virtual bool has_custom_cache() { return true; }
  virtual bool GetCustomCache(Code** code_out);
  virtual void SetCustomCache(Code* value);

  static const int kStackSpace = 6;
  static const int kArgc = 4;
 private:
  Handle<AccessorInfo> info() { return info_; }
  ApiFunction* fun() { return fun_; }
  Major MajorKey() { return NoCache; }
  int MinorKey() { return 0; }
  const char* GetName() { return "ApiEntryStub"; }
  // The accessor info associated with the function.
  Handle<AccessorInfo> info_;
  // The function to be called.
  ApiFunction* fun_;
};


// Mark the debugger statement to be recognized by debugger (by the MajorKey)
class DebuggerStatementStub : public CodeStub {
 public:
  DebuggerStatementStub() { }

  void Generate(MacroAssembler* masm);

 private:
  Major MajorKey() { return DebuggerStatement; }
  int MinorKey() { return 0; }

  const char* GetName() { return "DebuggerStatementStub"; }
};


class JSEntryStub : public CodeStub {
 public:
  JSEntryStub() { }

  void Generate(MacroAssembler* masm) { GenerateBody(masm, false); }

 protected:
  void GenerateBody(MacroAssembler* masm, bool is_construct);

 private:
  Major MajorKey() { return JSEntry; }
  int MinorKey() { return 0; }

  const char* GetName() { return "JSEntryStub"; }
};


class JSConstructEntryStub : public JSEntryStub {
 public:
  JSConstructEntryStub() { }

  void Generate(MacroAssembler* masm) { GenerateBody(masm, true); }

 private:
  int MinorKey() { return 1; }

  const char* GetName() { return "JSConstructEntryStub"; }
};


class ArgumentsAccessStub: public CodeStub {
 public:
  enum Type {
    READ_LENGTH,
    READ_ELEMENT,
    NEW_OBJECT
  };

  explicit ArgumentsAccessStub(Type type) : type_(type) { }

 private:
  Type type_;

  Major MajorKey() { return ArgumentsAccess; }
  int MinorKey() { return type_; }

  void Generate(MacroAssembler* masm);
  void GenerateReadLength(MacroAssembler* masm);
  void GenerateReadElement(MacroAssembler* masm);
  void GenerateNewObject(MacroAssembler* masm);

  const char* GetName() { return "ArgumentsAccessStub"; }

#ifdef DEBUG
  void Print() {
    PrintF("ArgumentsAccessStub (type %d)\n", type_);
  }
#endif
};


class RegExpExecStub: public CodeStub {
 public:
  RegExpExecStub() { }

 private:
  Major MajorKey() { return RegExpExec; }
  int MinorKey() { return 0; }

  void Generate(MacroAssembler* masm);

  const char* GetName() { return "RegExpExecStub"; }

#ifdef DEBUG
  void Print() {
    PrintF("RegExpExecStub\n");
  }
#endif
};


class CallFunctionStub: public CodeStub {
 public:
  CallFunctionStub(int argc, InLoopFlag in_loop, CallFunctionFlags flags)
      : argc_(argc), in_loop_(in_loop), flags_(flags) { }

  void Generate(MacroAssembler* masm);

 private:
  int argc_;
  InLoopFlag in_loop_;
  CallFunctionFlags flags_;

#ifdef DEBUG
  void Print() {
    PrintF("CallFunctionStub (args %d, in_loop %d, flags %d)\n",
           argc_,
           static_cast<int>(in_loop_),
           static_cast<int>(flags_));
  }
#endif

  // Minor key encoding in 31 bits AAAAAAAAAAAAAAAAAAAAAFI A(rgs)F(lag)I(nloop).
  class InLoopBits: public BitField<InLoopFlag, 0, 1> {};
  class FlagBits: public BitField<CallFunctionFlags, 1, 1> {};
  class ArgcBits: public BitField<int, 2, 29> {};

  Major MajorKey() { return CallFunction; }
  int MinorKey() {
    // Encode the parameters in a unique 31 bit value.
    return InLoopBits::encode(in_loop_)
           | FlagBits::encode(flags_)
           | ArgcBits::encode(argc_);
  }

  InLoopFlag InLoop() { return in_loop_; }
  bool ReceiverMightBeValue() {
    return (flags_ & RECEIVER_MIGHT_BE_VALUE) != 0;
  }

 public:
  static int ExtractArgcFromMinorKey(int minor_key) {
    return ArgcBits::decode(minor_key);
  }
};


class ToBooleanStub: public CodeStub {
 public:
  ToBooleanStub() { }

  void Generate(MacroAssembler* masm);

 private:
  Major MajorKey() { return ToBoolean; }
  int MinorKey() { return 0; }
};


}  // namespace internal
}  // namespace v8

#endif  // V8_CODEGEN_H_
