root/src/kits/debugger/dwarf/CfaContext.cpp
/*
 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
 * Distributed under the terms of the MIT License.
 */


#include <new>

#include "CfaContext.h"


CfaContext::CfaContext()
        :
        fTargetLocation(0),
        fLocation(0),
        fCodeAlignment(0),
        fDataAlignment(0),
        fReturnAddressRegister(0),
        fRuleSet(NULL),
        fInitialRuleSet(NULL),
        fRuleSetStack(10)
{
}


CfaContext::~CfaContext()
{
        delete fRuleSet;
        delete fInitialRuleSet;
}


void
CfaContext::SetLocation(target_addr_t targetLocation,
        target_addr_t initialLocation)
{
        fTargetLocation = targetLocation;
        fLocation = initialLocation;
}


status_t
CfaContext::Init(uint32 registerCount)
{
        fRuleSet = new(std::nothrow) CfaRuleSet;
        if (fRuleSet == NULL)
                return B_NO_MEMORY;

        return fRuleSet->Init(registerCount);
}


status_t
CfaContext::SaveInitialRuleSet()
{
        fInitialRuleSet = fRuleSet->Clone();
        if (fInitialRuleSet == NULL)
                return B_NO_MEMORY;
        return B_OK;
}


status_t
CfaContext::PushRuleSet()
{
        CfaRuleSet* ruleSet = fRuleSet->Clone();
        if (ruleSet == NULL || !fRuleSetStack.AddItem(ruleSet)) {
                delete ruleSet;
                return B_NO_MEMORY;
        }

        return B_OK;
}


status_t
CfaContext::PopRuleSet()
{
        if (fRuleSetStack.IsEmpty())
                return B_BAD_DATA;

        delete fRuleSet;
        fRuleSet = fRuleSetStack.RemoveItemAt(
                fRuleSetStack.CountItems() - 1);

        return B_OK;
}


void
CfaContext::SetLocation(target_addr_t location)
{
        fLocation = location;
}


void
CfaContext::SetCodeAlignment(uint32 alignment)
{
        fCodeAlignment = alignment;
}


void
CfaContext::SetDataAlignment(int32 alignment)
{
        fDataAlignment = alignment;
}


void
CfaContext::SetReturnAddressRegister(uint32 reg)
{
        fReturnAddressRegister = reg;
}


void
CfaContext::RestoreRegisterRule(uint32 reg)
{
        if (CfaRule* rule = RegisterRule(reg)) {
                if (fInitialRuleSet != NULL)
                        *rule = *fInitialRuleSet->RegisterRule(reg);
        }
}