/* -*- 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_IonFrameIterator_inl_h
#define jit_IonFrameIterator_inl_h

#ifdef JS_ION

#include "jit/BaselineFrame.h"
#include "jit/IonFrameIterator.h"
#include "jit/Bailouts.h"
#include "jit/Ion.h"

namespace js {
namespace jit {

template <class Op>
inline void
SnapshotIterator::readFrameArgs(Op &op, const Value *argv, Value *scopeChain, Value *thisv,
                                unsigned start, unsigned formalEnd, unsigned iterEnd,
                                JSScript *script)
{
    if (scopeChain)
        *scopeChain = read();
    else
        skip();

    // Skip slot for arguments object.
    if (script->argumentsHasVarBinding())
        skip();

    if (thisv)
        *thisv = read();
    else
        skip();

    unsigned i = 0;
    if (formalEnd < start)
        i = start;

    for (; i < start; i++)
        skip();
    for (; i < formalEnd && i < iterEnd; i++) {
        // We are not always able to read values from the snapshots, some values
        // such as non-gc things may still be live in registers and cause an
        // error while reading the machine state.
        Value v = maybeRead();
        op(v);
    }
    if (iterEnd >= formalEnd) {
        for (; i < iterEnd; i++)
            op(argv[i]);
    }
}

template <AllowGC allowGC>
inline
InlineFrameIteratorMaybeGC<allowGC>::InlineFrameIteratorMaybeGC(
                                JSContext *cx, const IonFrameIterator *iter)
  : callee_(cx),
    script_(cx)
{
    resetOn(iter);
}

template <AllowGC allowGC>
inline
InlineFrameIteratorMaybeGC<allowGC>::InlineFrameIteratorMaybeGC(
        JSContext *cx,
        const InlineFrameIteratorMaybeGC<allowGC> *iter)
  : frame_(iter ? iter->frame_ : NULL),
    framesRead_(0),
    callee_(cx),
    script_(cx)
{
    if (frame_) {
        start_ = SnapshotIterator(*frame_);
        // findNextFrame will iterate to the next frame and init. everything.
        // Therefore to settle on the same frame, we report one frame less readed.
        framesRead_ = iter->framesRead_ - 1;
        findNextFrame();
    }
}

template <AllowGC allowGC>
template <class Op>
inline void
InlineFrameIteratorMaybeGC<allowGC>::forEachCanonicalActualArg(
                JSContext *cx, Op op, unsigned start, unsigned count) const
{
    unsigned nactual = numActualArgs();
    if (count == unsigned(-1))
        count = nactual - start;

    unsigned end = start + count;
    unsigned nformal = callee()->nargs;

    JS_ASSERT(start <= end && end <= nactual);

    if (more()) {
        // There is still a parent frame of this inlined frame.
        // The not overflown arguments are taken from the inlined frame,
        // because it will have the updated value when JSOP_SETARG is done.
        // All arguments (also the overflown) are the last pushed values in the parent frame.
        // To get the overflown arguments, we need to take them from there.

        // Get the non overflown arguments
        unsigned formal_end = (end < nformal) ? end : nformal;
        SnapshotIterator s(si_);
        s.readFrameArgs(op, NULL, NULL, NULL, start, nformal, formal_end, script());

        // The overflown arguments are not available in current frame.
        // They are the last pushed arguments in the parent frame of this inlined frame.
        InlineFrameIteratorMaybeGC it(cx, this);
        ++it;
        unsigned argsObjAdj = it.script()->argumentsHasVarBinding() ? 1 : 0;
        SnapshotIterator parent_s(it.snapshotIterator());

        // Skip over all slots untill we get to the last slots (= arguments slots of callee)
        // the +2 is for [this] and [scopechain], and maybe +1 for [argsObj]
        JS_ASSERT(parent_s.slots() >= nactual + 2 + argsObjAdj);
        unsigned skip = parent_s.slots() - nactual - 2 - argsObjAdj;
        for (unsigned j = 0; j < skip; j++)
            parent_s.skip();

        // Get the overflown arguments
        parent_s.readFrameArgs(op, NULL, NULL, NULL, nformal, nactual, end, it.script());
    } else {
        SnapshotIterator s(si_);
        Value *argv = frame_->actualArgs();
        s.readFrameArgs(op, argv, NULL, NULL, start, nformal, end, script());
    }
}
 
template <AllowGC allowGC>
inline JSObject *
InlineFrameIteratorMaybeGC<allowGC>::scopeChain() const
{
    SnapshotIterator s(si_);

    // scopeChain
    Value v = s.read();
    if (v.isObject()) {
        JS_ASSERT_IF(script()->hasAnalysis(), script()->analysis()->usesScopeChain());
        return &v.toObject();
    }

    return callee()->environment();
}

template <AllowGC allowGC>
inline JSObject *
InlineFrameIteratorMaybeGC<allowGC>::thisObject() const
{
    // JS_ASSERT(isConstructing(...));
    SnapshotIterator s(si_);

    // scopeChain
    s.skip();

    // Arguments object.
    if (script()->argumentsHasVarBinding())
        s.skip();

    // In strict modes, |this| may not be an object and thus may not be
    // readable which can either segv in read or trigger the assertion.
    Value v = s.read();
    JS_ASSERT(v.isObject());
    return &v.toObject();
}

template <AllowGC allowGC>
inline unsigned
InlineFrameIteratorMaybeGC<allowGC>::numActualArgs() const
{
    // The number of actual arguments of inline frames is recovered by the
    // iteration process. It is recovered from the bytecode because this
    // property still hold since the for inlined frames. This property does not
    // hold for the parent frame because it can have optimize a call to
    // js_fun_call or js_fun_apply.
    if (more())
        return numActualArgs_;

    return frame_->numActualArgs();
}

template <AllowGC allowGC>
inline
InlineFrameIteratorMaybeGC<allowGC>::InlineFrameIteratorMaybeGC(
                                                JSContext *cx, const IonBailoutIterator *iter)
  : frame_(iter),
    framesRead_(0),
    callee_(cx),
    script_(cx)
{
    if (iter) {
        start_ = SnapshotIterator(*iter);
        findNextFrame();
    }
}

template <AllowGC allowGC>
inline InlineFrameIteratorMaybeGC<allowGC> &
InlineFrameIteratorMaybeGC<allowGC>::operator++()
{
    findNextFrame();
    return *this;
}

template <class Op>
inline void
IonFrameIterator::forEachCanonicalActualArg(Op op, unsigned start, unsigned count) const
{
    JS_ASSERT(isBaselineJS());

    unsigned nactual = numActualArgs();
    if (count == unsigned(-1))
        count = nactual - start;

    unsigned end = start + count;
    JS_ASSERT(start <= end && end <= nactual);

    Value *argv = actualArgs();
    for (unsigned i = start; i < end; i++)
        op(argv[i]);
}

inline BaselineFrame *
IonFrameIterator::baselineFrame() const
{
    JS_ASSERT(isBaselineJS());
    return (BaselineFrame *)(fp() - BaselineFrame::FramePointerOffset - BaselineFrame::Size());
}

} // namespace jit
} // namespace js

#endif // JS_ION

#endif /* jit_IonFrameIterator_inl_h */
