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

#include "jsanalyze.h"

#include "jsopcodeinlines.h"

namespace js {
namespace analyze {

inline const SSAValue &
ScriptAnalysis::poppedValue(uint32_t offset, uint32_t which)
{
    JS_ASSERT(offset < script_->length);
    JS_ASSERT(which < GetUseCount(script_, offset) +
              (ExtendedUse(script_->code + offset) ? 1 : 0));
    return getCode(offset).poppedValues[which];
}

inline const SSAValue &
ScriptAnalysis::poppedValue(const jsbytecode *pc, uint32_t which)
{
    return poppedValue(pc - script_->code, which);
}

inline types::StackTypeSet *
ScriptAnalysis::pushedTypes(uint32_t offset, uint32_t which)
{
    JS_ASSERT(offset < script_->length);
    JS_ASSERT(which < GetDefCount(script_, offset) +
              (ExtendedDef(script_->code + offset) ? 1 : 0));
    types::StackTypeSet *array = getCode(offset).pushedTypes;
    JS_ASSERT(array);
    return array + which;
}

inline types::StackTypeSet *
ScriptAnalysis::pushedTypes(const jsbytecode *pc, uint32_t which)
{
    return pushedTypes(pc - script_->code, which);
}

inline types::StackTypeSet *
ScriptAnalysis::getValueTypes(const SSAValue &v)
{
    switch (v.kind()) {
      case SSAValue::PUSHED:
        return pushedTypes(v.pushedOffset(), v.pushedIndex());
      case SSAValue::VAR:
        JS_ASSERT(!slotEscapes(v.varSlot()));
        if (v.varInitial()) {
            if (v.varSlot() < LocalSlot(script_, 0))
                return types::TypeScript::SlotTypes(script_, v.varSlot());
            return undefinedTypeSet;
        } else {
            /*
             * Results of intermediate assignments have the same type as
             * the first type pushed by the assignment op. Note that this
             * may not be the exact same value as was pushed, due to
             * post-inc/dec ops.
             */
            return pushedTypes(v.varOffset(), 0);
        }
      case SSAValue::PHI:
        return &v.phiNode()->types;
      default:
        /* Cannot compute types for empty SSA values. */
        JS_NOT_REACHED("Bad SSA value");
        return NULL;
    }
}

inline types::StackTypeSet *
ScriptAnalysis::poppedTypes(uint32_t offset, uint32_t which)
{
    return getValueTypes(poppedValue(offset, which));
}

inline types::StackTypeSet *
ScriptAnalysis::poppedTypes(const jsbytecode *pc, uint32_t which)
{
    return getValueTypes(poppedValue(pc, which));
}

inline SSAUseChain *&
ScriptAnalysis::useChain(const SSAValue &v)
{
    JS_ASSERT(trackUseChain(v));
    if (v.kind() == SSAValue::PUSHED)
        return getCode(v.pushedOffset()).pushedUses[v.pushedIndex()];
    if (v.kind() == SSAValue::VAR)
        return getCode(v.varOffset()).pushedUses[GetDefCount(script_, v.varOffset())];
    return v.phiNode()->uses;
}

inline jsbytecode *
ScriptAnalysis::getCallPC(jsbytecode *pc)
{
    SSAUseChain *uses = useChain(SSAValue::PushedValue(pc - script_->code, 0));
    JS_ASSERT(uses && uses->popped);
    JS_ASSERT(js_CodeSpec[script_->code[uses->offset]].format & JOF_INVOKE);
    return script_->code + uses->offset;
}

inline types::StackTypeSet *
CrossScriptSSA::getValueTypes(const CrossSSAValue &cv)
{
    return getFrame(cv.frame).script->analysis()->getValueTypes(cv.v);
}

} /* namespace analyze */
} /* namespace js */

#endif /* jsanalyzeinlines_h */
