/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 * vim: set ts=8 sts=4 et sw=4 tw=99:
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef jit_BaselineFrameInfo_h
#define jit_BaselineFrameInfo_h

#include "mozilla/Alignment.h"

#include "jit/BaselineFrame.h"
#include "jit/FixedList.h"
#include "jit/MacroAssembler.h"
#include "jit/SharedICRegisters.h"

namespace js {
namespace jit {

struct BytecodeInfo;

// FrameInfo overview.
//
// FrameInfo is used by the compiler to track values stored in the frame. This
// includes locals, arguments and stack values. Locals and arguments are always
// fully synced. Stack values can either be synced, stored as constant, stored in
// a Value register or refer to a local slot. Syncing a StackValue ensures it's
// stored on the stack, e.g. kind == Stack.
//
// To see how this works, consider the following statement:
//
//    var y = x + 9;
//
// Here two values are pushed: StackValue(LocalSlot(0)) and StackValue(Int32Value(9)).
// Only when we reach the ADD op, code is generated to load the operands directly
// into the right operand registers and sync all other stack values.
//
// For stack values, the following invariants hold (and are checked between ops):
//
// (1) If a value is synced (kind == Stack), all values below it must also be synced.
//     In other words, values with kind other than Stack can only appear on top of the
//     abstract stack.
//
// (2) When we call a stub or IC, all values still on the stack must be synced.

// Represents a value pushed on the stack. Note that StackValue is not used for
// locals or arguments since these are always fully synced.
class StackValue
{
  public:
    enum Kind {
        Constant,
        Register,
        Stack,
        LocalSlot,
        ArgSlot,
        ThisSlot,
        EvalNewTargetSlot
#ifdef DEBUG
        // In debug builds, assert Kind is initialized.
        , Uninitialized
#endif
    };

  private:
    Kind kind_;

    union {
        struct {
            Value v;
        } constant;
        struct {
            mozilla::AlignedStorage2<ValueOperand> reg;
        } reg;
        struct {
            uint32_t slot;
        } local;
        struct {
            uint32_t slot;
        } arg;
    } data;

    JSValueType knownType_;

  public:
    StackValue() {
        reset();
    }

    Kind kind() const {
        return kind_;
    }
    bool hasKnownType() const {
        return knownType_ != JSVAL_TYPE_UNKNOWN;
    }
    bool hasKnownType(JSValueType type) const {
        MOZ_ASSERT(type != JSVAL_TYPE_UNKNOWN);
        return knownType_ == type;
    }
    bool isKnownBoolean() const {
        return hasKnownType(JSVAL_TYPE_BOOLEAN);
    }
    JSValueType knownType() const {
        MOZ_ASSERT(hasKnownType());
        return knownType_;
    }
    void reset() {
#ifdef DEBUG
        kind_ = Uninitialized;
        knownType_ = JSVAL_TYPE_UNKNOWN;
#endif
    }
    Value constant() const {
        MOZ_ASSERT(kind_ == Constant);
        return data.constant.v;
    }
    ValueOperand reg() const {
        MOZ_ASSERT(kind_ == Register);
        return *data.reg.reg.addr();
    }
    uint32_t localSlot() const {
        MOZ_ASSERT(kind_ == LocalSlot);
        return data.local.slot;
    }
    uint32_t argSlot() const {
        MOZ_ASSERT(kind_ == ArgSlot);
        return data.arg.slot;
    }

    void setConstant(const Value& v) {
        kind_ = Constant;
        data.constant.v = v;
        knownType_ = v.isDouble() ? JSVAL_TYPE_DOUBLE : v.extractNonDoubleType();
    }
    void setRegister(const ValueOperand& val, JSValueType knownType = JSVAL_TYPE_UNKNOWN) {
        kind_ = Register;
        *data.reg.reg.addr() = val;
        knownType_ = knownType;
    }
    void setLocalSlot(uint32_t slot) {
        kind_ = LocalSlot;
        data.local.slot = slot;
        knownType_ = JSVAL_TYPE_UNKNOWN;
    }
    void setArgSlot(uint32_t slot) {
        kind_ = ArgSlot;
        data.arg.slot = slot;
        knownType_ = JSVAL_TYPE_UNKNOWN;
    }
    void setThis() {
        kind_ = ThisSlot;
        knownType_ = JSVAL_TYPE_UNKNOWN;
    }
    void setEvalNewTarget() {
        kind_ = EvalNewTargetSlot;
        knownType_ = JSVAL_TYPE_UNKNOWN;
    }
    void setStack() {
        kind_ = Stack;
        knownType_ = JSVAL_TYPE_UNKNOWN;
    }
};

enum StackAdjustment { AdjustStack, DontAdjustStack };

class FrameInfo
{
    JSScript* script;
    MacroAssembler& masm;

    FixedList<StackValue> stack;
    size_t spIndex;

  public:
    FrameInfo(JSScript* script, MacroAssembler& masm)
      : script(script),
        masm(masm),
        stack(),
        spIndex(0)
    { }

    bool init(TempAllocator& alloc);

    size_t nlocals() const {
        return script->nfixed();
    }
    size_t nargs() const {
        return script->functionNonDelazifying()->nargs();
    }
    size_t nvars() const {
        return script->nfixedvars();
    }
    size_t nlexicals() const {
        return script->fixedLexicalEnd() - script->fixedLexicalBegin();
    }

  private:
    inline StackValue* rawPush() {
        StackValue* val = &stack[spIndex++];
        val->reset();
        return val;
    }

  public:
    inline size_t stackDepth() const {
        return spIndex;
    }
    inline void setStackDepth(uint32_t newDepth) {
        if (newDepth <= stackDepth()) {
            spIndex = newDepth;
        } else {
            uint32_t diff = newDepth - stackDepth();
            for (uint32_t i = 0; i < diff; i++) {
                StackValue* val = rawPush();
                val->setStack();
            }

            MOZ_ASSERT(spIndex == newDepth);
        }
    }
    inline StackValue* peek(int32_t index) const {
        MOZ_ASSERT(index < 0);
        return const_cast<StackValue*>(&stack[spIndex + index]);
    }

    inline void pop(StackAdjustment adjust = AdjustStack) {
        spIndex--;
        StackValue* popped = &stack[spIndex];

        if (adjust == AdjustStack && popped->kind() == StackValue::Stack)
            masm.addToStackPtr(Imm32(sizeof(Value)));

        // Assert when anything uses this value.
        popped->reset();
    }
    inline void popn(uint32_t n, StackAdjustment adjust = AdjustStack) {
        uint32_t poppedStack = 0;
        for (uint32_t i = 0; i < n; i++) {
            if (peek(-1)->kind() == StackValue::Stack)
                poppedStack++;
            pop(DontAdjustStack);
        }
        if (adjust == AdjustStack && poppedStack > 0)
            masm.addToStackPtr(Imm32(sizeof(Value) * poppedStack));
    }
    inline void push(const Value& val) {
        StackValue* sv = rawPush();
        sv->setConstant(val);
    }
    inline void push(const ValueOperand& val, JSValueType knownType=JSVAL_TYPE_UNKNOWN) {
        StackValue* sv = rawPush();
        sv->setRegister(val, knownType);
    }
    inline void pushLocal(uint32_t local) {
        MOZ_ASSERT(local < nlocals());
        StackValue* sv = rawPush();
        sv->setLocalSlot(local);
    }
    inline void pushArg(uint32_t arg) {
        StackValue* sv = rawPush();
        sv->setArgSlot(arg);
    }
    inline void pushThis() {
        StackValue* sv = rawPush();
        sv->setThis();
    }
    inline void pushEvalNewTarget() {
        MOZ_ASSERT(script->isForEval());
        StackValue* sv = rawPush();
        sv->setEvalNewTarget();
    }

    inline void pushScratchValue() {
        masm.pushValue(addressOfScratchValue());
        StackValue* sv = rawPush();
        sv->setStack();
    }
    inline Address addressOfLocal(size_t local) const {
        MOZ_ASSERT(local < nlocals());
        return Address(BaselineFrameReg, BaselineFrame::reverseOffsetOfLocal(local));
    }
    Address addressOfArg(size_t arg) const {
        MOZ_ASSERT(arg < nargs());
        return Address(BaselineFrameReg, BaselineFrame::offsetOfArg(arg));
    }
    Address addressOfThis() const {
        return Address(BaselineFrameReg, BaselineFrame::offsetOfThis());
    }
    Address addressOfEvalNewTarget() const {
        return Address(BaselineFrameReg, BaselineFrame::offsetOfEvalNewTarget());
    }
    Address addressOfCalleeToken() const {
        return Address(BaselineFrameReg, BaselineFrame::offsetOfCalleeToken());
    }
    Address addressOfScopeChain() const {
        return Address(BaselineFrameReg, BaselineFrame::reverseOffsetOfScopeChain());
    }
    Address addressOfFlags() const {
        return Address(BaselineFrameReg, BaselineFrame::reverseOffsetOfFlags());
    }
    Address addressOfEvalScript() const {
        return Address(BaselineFrameReg, BaselineFrame::reverseOffsetOfEvalScript());
    }
    Address addressOfReturnValue() const {
        return Address(BaselineFrameReg, BaselineFrame::reverseOffsetOfReturnValue());
    }
    Address addressOfArgsObj() const {
        return Address(BaselineFrameReg, BaselineFrame::reverseOffsetOfArgsObj());
    }
    Address addressOfStackValue(const StackValue* value) const {
        MOZ_ASSERT(value->kind() == StackValue::Stack);
        size_t slot = value - &stack[0];
        MOZ_ASSERT(slot < stackDepth());
        return Address(BaselineFrameReg, BaselineFrame::reverseOffsetOfLocal(nlocals() + slot));
    }
    Address addressOfScratchValue() const {
        return Address(BaselineFrameReg, BaselineFrame::reverseOffsetOfScratchValue());
    }

    void popValue(ValueOperand dest);

    void sync(StackValue* val);
    void syncStack(uint32_t uses);
    uint32_t numUnsyncedSlots();
    void popRegsAndSync(uint32_t uses);

    inline void assertSyncedStack() const {
        MOZ_ASSERT_IF(stackDepth() > 0, peek(-1)->kind() == StackValue::Stack);
    }

#ifdef DEBUG
    // Assert the state is valid before excuting "pc".
    void assertValidState(const BytecodeInfo& info);
#else
    inline void assertValidState(const BytecodeInfo& info) {}
#endif
};

} // namespace jit
} // namespace js

#endif /* jit_BaselineFrameInfo_h */
