/*****************************************************************************/
/*!
*\file cdflags.cpp
*\brief Implementation for CDFlags class
*
* Author: Clark Barrett
*
* Created: Thu Jan 26 16:53:28 2006
*
* <hr>
*
* License to use, copy, modify, sell and/or distribute this software
* and its documentation for any purpose is hereby granted without
* royalty, subject to the terms and conditions defined in the \ref
* LICENSE file provided with this distribution.
*
* <hr>
*
*/
/*****************************************************************************/
#include "cdflags.h"
#include "memory_manager_context.h"
using namespace CVC3;
using namespace std;
void CDFlags::update(unsigned mask, int scope, bool setMask)
{
DebugAssert(mask && (mask & (mask-1)) == 0, "Expected single bit mask");
if (scope < 0 || d_scope->level() <= scope) {
makeCurrent(scope);
if (setMask) d_flags = d_flags | mask;
else d_flags = d_flags & ~mask;
}
else {
// Kind of ugly: have to "change the past", but that's the price we pay for
// keeping all the flags in one word for efficiency.
IF_DEBUG(bool on = (d_flags & mask) != 0;)
// Update current object
if (setMask) d_flags = d_flags | mask;
else d_flags = d_flags & ~mask;
ContextObjChain** lastPtr = &d_restore;
CDFlags* pastFlags;
Scope* lastScope = d_scope;
bool done = false;
// Update past objects
while (true) {
pastFlags = (CDFlags*)((*lastPtr)->d_data);
DebugAssert(pastFlags != NULL, "expected non-NULL data");
if (pastFlags->d_scope->level() >= scope) {
DebugAssert(on && (pastFlags->d_flags & mask) ||
!on && !(pastFlags->d_flags & mask),
"Expected no change in flag since scope");
if (setMask) {
pastFlags->d_flags = pastFlags->d_flags | mask;
}
else {
pastFlags->d_flags = pastFlags->d_flags & ~mask;
}
if (pastFlags->d_scope->level() == scope) {
done = true; break;
}
lastScope = pastFlags->d_scope;
} else break;
lastPtr = &((*lastPtr)->d_restore);
DebugAssert(*lastPtr != NULL, "Should always be object at scope 0");
}
if (done) return;
// No past object exists at the target scope: create one
DebugAssert(lastScope != NULL &&
lastScope->level() > scope,
"Expected lastScope to be above target scope");
while (lastScope->level() > scope) lastScope = lastScope->prevScope();
ContextObj* data = pastFlags->makeCopy(lastScope->getCMM());
pastFlags->d_scope = lastScope;
ContextObjChain* obj = new(lastScope->getCMM())
ContextObjChain(data, this, (*lastPtr)->d_restore);
(*lastPtr)->d_restore = obj;
lastScope->addToChain(obj);
// Update newly created past object
if (setMask) {
pastFlags->d_flags = pastFlags->d_flags | mask;
}
else {
pastFlags->d_flags = pastFlags->d_flags & ~mask;
}
}
}
syntax highlighted by Code2HTML, v. 0.9.1