// Copyright 2009 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_IA32_VIRTUAL_FRAME_IA32_H_
#define V8_IA32_VIRTUAL_FRAME_IA32_H_

#include "codegen.h"
#include "register-allocator.h"
#include "scopes.h"
#include "type-info.h"

namespace v8 {
namespace internal {

// -------------------------------------------------------------------------
// Virtual frames
//
// The virtual frame is an abstraction of the physical stack frame.  It
// encapsulates the parameters, frame-allocated locals, and the expression
// stack.  It supports push/pop operations on the expression stack, as well
// as random access to the expression stack elements, locals, and
// parameters.

class VirtualFrame: public ZoneObject {
 public:
  // A utility class to introduce a scope where the virtual frame is
  // expected to remain spilled.  The constructor spills the code
  // generator's current frame, but no attempt is made to require it
  // to stay spilled.  It is intended as documentation while the code
  // generator is being transformed.
  class SpilledScope BASE_EMBEDDED {
   public:
    SpilledScope() : previous_state_(cgen()->in_spilled_code()) {
      ASSERT(cgen()->has_valid_frame());
      cgen()->frame()->SpillAll();
      cgen()->set_in_spilled_code(true);
    }

    ~SpilledScope() {
      cgen()->set_in_spilled_code(previous_state_);
    }

   private:
    bool previous_state_;

    CodeGenerator* cgen() {return CodeGeneratorScope::Current();}
  };

  // An illegal index into the virtual frame.
  static const int kIllegalIndex = -1;

  // Construct an initial virtual frame on entry to a JS function.
  inline VirtualFrame();

  // Construct a virtual frame as a clone of an existing one.
  explicit inline VirtualFrame(VirtualFrame* original);

  CodeGenerator* cgen() { return CodeGeneratorScope::Current(); }

  MacroAssembler* masm() { return cgen()->masm(); }

  // Create a duplicate of an existing valid frame element.
  FrameElement CopyElementAt(int index,
    TypeInfo info = TypeInfo::Uninitialized());

  // The number of elements on the virtual frame.
  int element_count() { return elements_.length(); }

  // The height of the virtual expression stack.
  int height() { return element_count() - expression_base_index(); }

  int register_location(int num) {
    ASSERT(num >= 0 && num < RegisterAllocator::kNumRegisters);
    return register_locations_[num];
  }

  inline int register_location(Register reg);

  inline void set_register_location(Register reg, int index);

  bool is_used(int num) {
    ASSERT(num >= 0 && num < RegisterAllocator::kNumRegisters);
    return register_locations_[num] != kIllegalIndex;
  }

  inline bool is_used(Register reg);

  // Add extra in-memory elements to the top of the frame to match an actual
  // frame (eg, the frame after an exception handler is pushed).  No code is
  // emitted.
  void Adjust(int count);

  // Forget count elements from the top of the frame all in-memory
  // (including synced) and adjust the stack pointer downward, to
  // match an external frame effect (examples include a call removing
  // its arguments, and exiting a try/catch removing an exception
  // handler).  No code will be emitted.
  void Forget(int count) {
    ASSERT(count >= 0);
    ASSERT(stack_pointer_ == element_count() - 1);
    stack_pointer_ -= count;
    ForgetElements(count);
  }

  // Forget count elements from the top of the frame without adjusting
  // the stack pointer downward.  This is used, for example, before
  // merging frames at break, continue, and return targets.
  void ForgetElements(int count);

  // Spill all values from the frame to memory.
  inline void SpillAll();

  // Spill all occurrences of a specific register from the frame.
  void Spill(Register reg) {
    if (is_used(reg)) SpillElementAt(register_location(reg));
  }

  // Make the two registers distinct and spill them.  Returns the second
  // register.  If the registers were not distinct then it returns the new
  // second register.
  Result MakeDistinctAndSpilled(Result* left, Result* right) {
    Spill(left->reg());
    Spill(right->reg());
    if (left->reg().is(right->reg())) {
      RegisterAllocator* allocator = cgen()->allocator();
      Result fresh = allocator->Allocate();
      ASSERT(fresh.is_valid());
      masm()->mov(fresh.reg(), right->reg());
      return fresh;
    }
    return *right;
  }

  // Spill all occurrences of an arbitrary register if possible.  Return the
  // register spilled or no_reg if it was not possible to free any register
  // (ie, they all have frame-external references).
  Register SpillAnyRegister();

  // Spill the top element of the frame.
  void SpillTop() { SpillElementAt(element_count() - 1); }

  // Sync the range of elements in [begin, end] with memory.
  void SyncRange(int begin, int end);

  // Make this frame so that an arbitrary frame of the same height can
  // be merged to it.  Copies and constants are removed from the frame.
  void MakeMergable();

  // Prepare this virtual frame for merging to an expected frame by
  // performing some state changes that do not require generating
  // code.  It is guaranteed that no code will be generated.
  void PrepareMergeTo(VirtualFrame* expected);

  // Make this virtual frame have a state identical to an expected virtual
  // frame.  As a side effect, code may be emitted to make this frame match
  // the expected one.
  void MergeTo(VirtualFrame* expected);

  // Detach a frame from its code generator, perhaps temporarily.  This
  // tells the register allocator that it is free to use frame-internal
  // registers.  Used when the code generator's frame is switched from this
  // one to NULL by an unconditional jump.
  void DetachFromCodeGenerator() {
    RegisterAllocator* cgen_allocator = cgen()->allocator();
    for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
      if (is_used(i)) cgen_allocator->Unuse(i);
    }
  }

  // (Re)attach a frame to its code generator.  This informs the register
  // allocator that the frame-internal register references are active again.
  // Used when a code generator's frame is switched from NULL to this one by
  // binding a label.
  void AttachToCodeGenerator() {
    RegisterAllocator* cgen_allocator = cgen()->allocator();
    for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
      if (is_used(i)) cgen_allocator->Use(i);
    }
  }

  // Emit code for the physical JS entry and exit frame sequences.  After
  // calling Enter, the virtual frame is ready for use; and after calling
  // Exit it should not be used.  Note that Enter does not allocate space in
  // the physical frame for storing frame-allocated locals.
  void Enter();
  void Exit();

  // Prepare for returning from the frame by spilling locals.  This
  // avoids generating unnecessary merge code when jumping to the
  // shared return site.  Emits code for spills.
  inline void PrepareForReturn();

  // Number of local variables after when we use a loop for allocating.
  static const int kLocalVarBound = 10;

  // Allocate and initialize the frame-allocated locals.
  void AllocateStackSlots();

  // An element of the expression stack as an assembly operand.
  Operand ElementAt(int index) const {
    return Operand(esp, index * kPointerSize);
  }

  // Random-access store to a frame-top relative frame element.  The result
  // becomes owned by the frame and is invalidated.
  void SetElementAt(int index, Result* value);

  // Set a frame element to a constant.  The index is frame-top relative.
  inline void SetElementAt(int index, Handle<Object> value);

  void PushElementAt(int index) {
    PushFrameSlotAt(element_count() - index - 1);
  }

  void StoreToElementAt(int index) {
    StoreToFrameSlotAt(element_count() - index - 1);
  }

  // A frame-allocated local as an assembly operand.
  Operand LocalAt(int index) {
    ASSERT(0 <= index);
    ASSERT(index < local_count());
    return Operand(ebp, kLocal0Offset - index * kPointerSize);
  }

  // Push a copy of the value of a local frame slot on top of the frame.
  void PushLocalAt(int index) {
    PushFrameSlotAt(local0_index() + index);
  }

  // Push a copy of the value of a local frame slot on top of the frame.
  void UntaggedPushLocalAt(int index) {
    UntaggedPushFrameSlotAt(local0_index() + index);
  }

  // Push the value of a local frame slot on top of the frame and invalidate
  // the local slot.  The slot should be written to before trying to read
  // from it again.
  void TakeLocalAt(int index) {
    TakeFrameSlotAt(local0_index() + index);
  }

  // Store the top value on the virtual frame into a local frame slot.  The
  // value is left in place on top of the frame.
  void StoreToLocalAt(int index) {
    StoreToFrameSlotAt(local0_index() + index);
  }

  // Push the address of the receiver slot on the frame.
  void PushReceiverSlotAddress();

  // Push the function on top of the frame.
  void PushFunction() {
    PushFrameSlotAt(function_index());
  }

  // Save the value of the esi register to the context frame slot.
  void SaveContextRegister();

  // Restore the esi register from the value of the context frame
  // slot.
  void RestoreContextRegister();

  // A parameter as an assembly operand.
  Operand ParameterAt(int index) {
    ASSERT(-1 <= index);  // -1 is the receiver.
    ASSERT(index < parameter_count());
    return Operand(ebp, (1 + parameter_count() - index) * kPointerSize);
  }

  // Push a copy of the value of a parameter frame slot on top of the frame.
  void PushParameterAt(int index) {
    PushFrameSlotAt(param0_index() + index);
  }

  // Push a copy of the value of a parameter frame slot on top of the frame.
  void UntaggedPushParameterAt(int index) {
    UntaggedPushFrameSlotAt(param0_index() + index);
  }

  // Push the value of a paramter frame slot on top of the frame and
  // invalidate the parameter slot.  The slot should be written to before
  // trying to read from it again.
  void TakeParameterAt(int index) {
    TakeFrameSlotAt(param0_index() + index);
  }

  // Store the top value on the virtual frame into a parameter frame slot.
  // The value is left in place on top of the frame.
  void StoreToParameterAt(int index) {
    StoreToFrameSlotAt(param0_index() + index);
  }

  // The receiver frame slot.
  Operand Receiver() {
    return ParameterAt(-1);
  }

  // Push a try-catch or try-finally handler on top of the virtual frame.
  void PushTryHandler(HandlerType type);

  // Call stub given the number of arguments it expects on (and
  // removes from) the stack.
  inline Result CallStub(CodeStub* stub, int arg_count);

  // Call stub that takes a single argument passed in eax.  The
  // argument is given as a result which does not have to be eax or
  // even a register.  The argument is consumed by the call.
  Result CallStub(CodeStub* stub, Result* arg);

  // Call stub that takes a pair of arguments passed in edx (arg0) and
  // eax (arg1).  The arguments are given as results which do not have
  // to be in the proper registers or even in registers.  The
  // arguments are consumed by the call.
  Result CallStub(CodeStub* stub, Result* arg0, Result* arg1);

  // Call JS function from top of the stack with arguments
  // taken from the stack.
  Result CallJSFunction(int arg_count);

  // Call runtime given the number of arguments expected on (and
  // removed from) the stack.
  Result CallRuntime(Runtime::Function* f, int arg_count);
  Result CallRuntime(Runtime::FunctionId id, int arg_count);

#ifdef ENABLE_DEBUGGER_SUPPORT
  void DebugBreak();
#endif

  // Invoke builtin given the number of arguments it expects on (and
  // removes from) the stack.
  Result InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag, int arg_count);

  // Call load IC.  Name and receiver are found on top of the frame.
  // Both are dropped.
  Result CallLoadIC(RelocInfo::Mode mode);

  // Call keyed load IC.  Key and receiver are found on top of the
  // frame.  Both are dropped.
  Result CallKeyedLoadIC(RelocInfo::Mode mode);

  // Call store IC.  If the load is contextual, value is found on top of the
  // frame.  If not, value and receiver are on the frame.  Both are dropped.
  Result CallStoreIC(Handle<String> name, bool is_contextual,
                     StrictModeFlag strict_mode);

  // Call keyed store IC.  Value, key, and receiver are found on top
  // of the frame.  All three are dropped.
  Result CallKeyedStoreIC(StrictModeFlag strict_mode);

  // Call call IC.  Function name, arguments, and receiver are found on top
  // of the frame and dropped by the call.  The argument count does not
  // include the receiver.
  Result CallCallIC(RelocInfo::Mode mode, int arg_count, int loop_nesting);

  // Call keyed call IC.  Same calling convention as CallCallIC.
  Result CallKeyedCallIC(RelocInfo::Mode mode, int arg_count, int loop_nesting);

  // Allocate and call JS function as constructor.  Arguments,
  // receiver (global object), and function are found on top of the
  // frame.  Function is not dropped.  The argument count does not
  // include the receiver.
  Result CallConstructor(int arg_count);

  // Drop a number of elements from the top of the expression stack.  May
  // emit code to affect the physical frame.  Does not clobber any registers
  // excepting possibly the stack pointer.
  void Drop(int count);

  // Drop one element.
  void Drop() {
    Drop(1);
  }

  // Duplicate the top element of the frame.
  void Dup() {
    PushFrameSlotAt(element_count() - 1);
  }

  // Pop an element from the top of the expression stack.  Returns a
  // Result, which may be a constant or a register.
  Result Pop();

  // Pop and save an element from the top of the expression stack and
  // emit a corresponding pop instruction.
  void EmitPop(Register reg);
  void EmitPop(Operand operand);

  // Push an element on top of the expression stack and emit a
  // corresponding push instruction.
  void EmitPush(Register reg,
                TypeInfo info = TypeInfo::Unknown());
  void EmitPush(Operand operand,
                TypeInfo info = TypeInfo::Unknown());
  void EmitPush(Immediate immediate,
                TypeInfo info = TypeInfo::Unknown());

  inline bool ConstantPoolOverflowed();

  // Push an element on the virtual frame.
  void Push(Handle<Object> value);
  inline void Push(Register reg, TypeInfo info = TypeInfo::Unknown());
  inline void Push(Smi* value);

  void PushUntaggedElement(Handle<Object> value);

  // Pushing a result invalidates it (its contents become owned by the
  // frame).
  void Push(Result* result) {
    // This assert will trigger if you try to push the same value twice.
    ASSERT(result->is_valid());
    if (result->is_register()) {
      Push(result->reg(), result->type_info());
    } else {
      ASSERT(result->is_constant());
      Push(result->handle());
    }
    if (cgen()->in_safe_int32_mode()) {
      ASSERT(result->is_untagged_int32());
      elements_[element_count() - 1].set_untagged_int32(true);
    }
    result->Unuse();
  }

  // Pushing an expression expects that the expression is trivial (according
  // to Expression::IsTrivial).
  void Push(Expression* expr);

  // Nip removes zero or more elements from immediately below the top
  // of the frame, leaving the previous top-of-frame value on top of
  // the frame.  Nip(k) is equivalent to x = Pop(), Drop(k), Push(x).
  inline void Nip(int num_dropped);

  // Check that the frame has no elements containing untagged int32 elements.
  bool HasNoUntaggedInt32Elements() {
    for (int i = 0; i < element_count(); ++i) {
      if (elements_[i].is_untagged_int32()) return false;
    }
    return true;
  }

  // Update the type information of a variable frame element directly.
  inline void SetTypeForLocalAt(int index, TypeInfo info);
  inline void SetTypeForParamAt(int index, TypeInfo info);

 private:
  static const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset;
  static const int kFunctionOffset = JavaScriptFrameConstants::kFunctionOffset;
  static const int kContextOffset = StandardFrameConstants::kContextOffset;

  static const int kHandlerSize = StackHandlerConstants::kSize / kPointerSize;
  static const int kPreallocatedElements = 5 + 8;  // 8 expression stack slots.

  ZoneList<FrameElement> elements_;

  // The index of the element that is at the processor's stack pointer
  // (the esp register).
  int stack_pointer_;

  // The index of the register frame element using each register, or
  // kIllegalIndex if a register is not on the frame.
  int register_locations_[RegisterAllocator::kNumRegisters];

  // The number of frame-allocated locals and parameters respectively.
  inline int parameter_count();

  inline int local_count();

  // The index of the element that is at the processor's frame pointer
  // (the ebp register).  The parameters, receiver, and return address
  // are below the frame pointer.
  int frame_pointer() {
    return parameter_count() + 2;
  }

  // The index of the first parameter.  The receiver lies below the first
  // parameter.
  int param0_index() {
    return 1;
  }

  // The index of the context slot in the frame.  It is immediately
  // above the frame pointer.
  int context_index() {
    return frame_pointer() + 1;
  }

  // The index of the function slot in the frame.  It is above the frame
  // pointer and the context slot.
  int function_index() {
    return frame_pointer() + 2;
  }

  // The index of the first local.  Between the frame pointer and the
  // locals lie the context and the function.
  int local0_index() {
    return frame_pointer() + 3;
  }

  // The index of the base of the expression stack.
  int expression_base_index() {
    return local0_index() + local_count();
  }

  // Convert a frame index into a frame pointer relative offset into the
  // actual stack.
  int fp_relative(int index) {
    ASSERT(index < element_count());
    ASSERT(frame_pointer() < element_count());  // FP is on the frame.
    return (frame_pointer() - index) * kPointerSize;
  }

  // Record an occurrence of a register in the virtual frame.  This has the
  // effect of incrementing the register's external reference count and
  // of updating the index of the register's location in the frame.
  void Use(Register reg, int index) {
    ASSERT(!is_used(reg));
    set_register_location(reg, index);
    cgen()->allocator()->Use(reg);
  }

  // Record that a register reference has been dropped from the frame.  This
  // decrements the register's external reference count and invalidates the
  // index of the register's location in the frame.
  void Unuse(Register reg) {
    ASSERT(is_used(reg));
    set_register_location(reg, kIllegalIndex);
    cgen()->allocator()->Unuse(reg);
  }

  // Spill the element at a particular index---write it to memory if
  // necessary, free any associated register, and forget its value if
  // constant.
  void SpillElementAt(int index);

  // Sync the element at a particular index.  If it is a register or
  // constant that disagrees with the value on the stack, write it to memory.
  // Keep the element type as register or constant, and clear the dirty bit.
  void SyncElementAt(int index);

  // Sync a single unsynced element that lies beneath or at the stack pointer.
  void SyncElementBelowStackPointer(int index);

  // Sync a single unsynced element that lies just above the stack pointer.
  void SyncElementByPushing(int index);

  // Push a copy of a frame slot (typically a local or parameter) on top of
  // the frame.
  inline void PushFrameSlotAt(int index);

  // Push a copy of a frame slot (typically a local or parameter) on top of
  // the frame, at an untagged int32 value.  Bails out if the value is not
  // an int32.
  void UntaggedPushFrameSlotAt(int index);

  // Push a the value of a frame slot (typically a local or parameter) on
  // top of the frame and invalidate the slot.
  void TakeFrameSlotAt(int index);

  // Store the value on top of the frame to a frame slot (typically a local
  // or parameter).
  void StoreToFrameSlotAt(int index);

  // Spill all elements in registers. Spill the top spilled_args elements
  // on the frame.  Sync all other frame elements.
  // Then drop dropped_args elements from the virtual frame, to match
  // the effect of an upcoming call that will drop them from the stack.
  void PrepareForCall(int spilled_args, int dropped_args);

  // Move frame elements currently in registers or constants, that
  // should be in memory in the expected frame, to memory.
  void MergeMoveRegistersToMemory(VirtualFrame* expected);

  // Make the register-to-register moves necessary to
  // merge this frame with the expected frame.
  // Register to memory moves must already have been made,
  // and memory to register moves must follow this call.
  // This is because some new memory-to-register moves are
  // created in order to break cycles of register moves.
  // Used in the implementation of MergeTo().
  void MergeMoveRegistersToRegisters(VirtualFrame* expected);

  // Make the memory-to-register and constant-to-register moves
  // needed to make this frame equal the expected frame.
  // Called after all register-to-memory and register-to-register
  // moves have been made.  After this function returns, the frames
  // should be equal.
  void MergeMoveMemoryToRegisters(VirtualFrame* expected);

  // Invalidates a frame slot (puts an invalid frame element in it).
  // Copies on the frame are correctly handled, and if this slot was
  // the backing store of copies, the index of the new backing store
  // is returned.  Otherwise, returns kIllegalIndex.
  // Register counts are correctly updated.
  int InvalidateFrameSlotAt(int index);

  // This function assumes that a and b are the only results that could be in
  // the registers a_reg or b_reg.  Other results can be live, but must not
  //  be in the registers a_reg or b_reg.  The results a and b are invalidated.
  void MoveResultsToRegisters(Result* a,
                              Result* b,
                              Register a_reg,
                              Register b_reg);

  // Call a code stub that has already been prepared for calling (via
  // PrepareForCall).
  Result RawCallStub(CodeStub* stub);

  // Calls a code object which has already been prepared for calling
  // (via PrepareForCall).
  Result RawCallCodeObject(Handle<Code> code, RelocInfo::Mode rmode);

  inline bool Equals(VirtualFrame* other);

  // Classes that need raw access to the elements_ array.
  friend class FrameRegisterState;
  friend class JumpTarget;
};

} }  // namespace v8::internal

#endif  // V8_IA32_VIRTUAL_FRAME_IA32_H_
