summaryrefslogtreecommitdiff
path: root/src/context/context.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/context/context.cpp')
-rw-r--r--src/context/context.cpp138
1 files changed, 125 insertions, 13 deletions
diff --git a/src/context/context.cpp b/src/context/context.cpp
index 05024430c..d371dc39a 100644
--- a/src/context/context.cpp
+++ b/src/context/context.cpp
@@ -10,9 +10,13 @@
** See the file COPYING in the top-level source directory for licensing
** information.
**
+ ** Implementation of base context operations.
**/
+#include <iostream>
+#include <vector>
+
#include "context/context.h"
#include "util/Assert.h"
@@ -54,7 +58,7 @@ Context::~Context() throw(AssertionException) {
void Context::push() {
- // FIXME: TRACE("pushpop", indentStr, "Push", " {");
+ Trace("pushpop") << std::string(2 * getLevel(), ' ') << "Push {" << std::endl;
// Create a new memory region
d_pCMM->push();
@@ -93,7 +97,7 @@ void Context::pop() {
pCNO = pCNO->d_pCNOnext;
}
- //FIXME: TRACE("pushpop", indentStr, "}", " Pop");
+ Trace("pushpop") << std::string(2 * getLevel(), ' ') << "} Pop" << std::endl;
}
@@ -124,16 +128,47 @@ void Context::addNotifyObjPost(ContextNotifyObj* pCNO) {
}
-void ContextObj::update() {
+void ContextObj::update() throw(AssertionException) {
+ Debug("context") << "before update(" << this << "):" << std::endl
+ << *getContext() << std::endl;
+
// Call save() to save the information in the current object
ContextObj* pContextObjSaved = save(d_pScope->getCMM());
+ Debug("context") << "in update(" << this << ") with restore "
+ << pContextObjSaved << ": waypoint 1" << std::endl
+ << *getContext() << std::endl;
+
// Check that base class data was saved
- Assert(pContextObjSaved->d_pContextObjNext == d_pContextObjNext &&
- pContextObjSaved->d_ppContextObjPrev == d_ppContextObjPrev &&
- pContextObjSaved->d_pContextObjRestore == d_pContextObjRestore &&
- pContextObjSaved->d_pScope == d_pScope,
- "save() did not properly copy information in base class");
+ Assert( ( pContextObjSaved->d_pContextObjNext == d_pContextObjNext &&
+ pContextObjSaved->d_ppContextObjPrev == d_ppContextObjPrev &&
+ pContextObjSaved->d_pContextObjRestore == d_pContextObjRestore &&
+ pContextObjSaved->d_pScope == d_pScope ),
+ "save() did not properly copy information in base class" );
+
+ // Link the "saved" object in place of this ContextObj in the scope
+ // we're moving it FROM.
+ Debug("context") << "in update(" << this
+ << "): next() == " << next() << std::endl;
+ if(next() != NULL) {
+ Debug("context") << "in update(" << this
+ << "): next()->prev() == " << next()->prev() << std::endl;
+ next()->prev() = &pContextObjSaved->next();
+ Debug("context") << "in update(" << this
+ << "): next()->prev() is now "
+ << next()->prev() << std::endl;
+ }
+ Debug("context") << "in update(" << this
+ << "): prev() == " << prev() << std::endl;
+ Debug("context") << "in update(" << this
+ << "): *prev() == " << *prev() << std::endl;
+ *prev() = pContextObjSaved;
+ Debug("context") << "in update(" << this
+ << "): *prev() is now " << *prev() << std::endl;
+
+ Debug("context") << "in update(" << this << ") with restore "
+ << pContextObjSaved << ": waypoint 3" << std::endl
+ << *getContext() << std::endl;
// Update Scope pointer to current top Scope
d_pScope = d_pScope->getContext()->getTopScope();
@@ -144,18 +179,27 @@ void ContextObj::update() {
// Insert object into the list of objects that need to be restored when this
// Scope is popped.
d_pScope->addToChain(this);
+
+ Debug("context") << "after update(" << this << ") with restore "
+ << pContextObjSaved << ":" << std::endl
+ << *getContext() << std::endl;
}
-ContextObj* ContextObj::restoreAndContinue() {
+ContextObj* ContextObj::restoreAndContinue() throw(AssertionException) {
// Variable to hold next object in list
ContextObj* pContextObjNext;
// Check the restore pointer. If NULL, this must be the bottom Scope
if(d_pContextObjRestore == NULL) {
- Assert(d_pScope == d_pScope->getContext()->getBottomScope(),
- "Expected bottom scope");
+ // might not be bottom scope, since objects allocated in context
+ // memory don't get linked to scope 0
+ //
+ // Assert(d_pScope == d_pScope->getContext()->getBottomScope(),
+ // "Expected bottom scope");
+
pContextObjNext = d_pContextObjNext;
+
// Nothing else to do
} else {
// Call restore to update the subclass data
@@ -169,13 +213,23 @@ ContextObj* ContextObj::restoreAndContinue() {
next() = d_pContextObjRestore->d_pContextObjNext;
prev() = d_pContextObjRestore->d_ppContextObjPrev;
d_pContextObjRestore = d_pContextObjRestore->d_pContextObjRestore;
+
+ // Re-link this ContextObj to the list in this scope
+ if(next() != NULL) {
+ next()->prev() = &next();
+ }
+ *prev() = this;
}
+
// Return the next object in the list
return pContextObjNext;
}
void ContextObj::destroy() throw(AssertionException) {
+ Debug("context") << "before destroy " << this
+ << " (level " << getLevel() << "):" << std::endl
+ << *getContext() << std::endl;
for(;;) {
// If valgrind reports invalid writes on the next few lines,
// here's a hint: make sure all classes derived from ContextObj in
@@ -184,12 +238,18 @@ void ContextObj::destroy() throw(AssertionException) {
if(next() != NULL) {
next()->prev() = prev();
}
- *(prev()) = next();
+ *prev() = next();
if(d_pContextObjRestore == NULL) {
break;
}
+ Debug("context") << "in destroy " << this << ", restore object is "
+ << d_pContextObjRestore << " at level "
+ << d_pContextObjRestore->getLevel() << ":" << std::endl
+ << *getContext() << std::endl;
restoreAndContinue();
}
+ Debug("context") << "after destroy " << this << ":" << std::endl
+ << *getContext() << std::endl;
}
@@ -198,11 +258,27 @@ ContextObj::ContextObj(Context* pContext) :
Assert(pContext != NULL, "NULL context pointer");
+ Debug("context") << "create new ContextObj(" << this << ")" << std::endl;
d_pScope = pContext->getBottomScope();
d_pScope->addToChain(this);
}
+ContextObj::ContextObj(bool allocatedInCMM, Context* pContext) :
+ d_pContextObjRestore(NULL) {
+
+ Assert(pContext != NULL, "NULL context pointer");
+
+ Debug("context") << "create new ContextObj(" << this << ")" << std::endl;
+ if(allocatedInCMM) {
+ d_pScope = pContext->getTopScope();
+ } else {
+ d_pScope = pContext->getBottomScope();
+ }
+ d_pScope->addToChain(this);
+}
+
+
ContextNotifyObj::ContextNotifyObj(Context* pContext, bool preNotify) {
if(preNotify) {
pContext->addNotifyObjPre(this);
@@ -217,8 +293,44 @@ ContextNotifyObj::~ContextNotifyObj() throw(AssertionException) {
d_pCNOnext->d_ppCNOprev = d_ppCNOprev;
}
if(d_ppCNOprev != NULL) {
- *(d_ppCNOprev) = d_pCNOnext;
+ *d_ppCNOprev = d_pCNOnext;
+ }
+}
+
+
+std::ostream& operator<<(std::ostream& out,
+ const Context& context) throw(AssertionException) {
+ const std::string separator(79, '-');
+
+ int level = context.d_scopeList.size() - 1;
+ typedef std::vector<Scope*>::const_reverse_iterator const_reverse_iterator;
+ for(const_reverse_iterator i = context.d_scopeList.rbegin();
+ i != context.d_scopeList.rend();
+ ++i, --level) {
+ Scope* pScope = *i;
+ Assert(pScope->getLevel() == level);
+ Assert(pScope->getContext() == &context);
+ out << separator << std::endl
+ << *pScope << std::endl;
+ }
+ return out << separator << std::endl;
+}
+
+
+std::ostream& operator<<(std::ostream& out,
+ const Scope& scope) throw(AssertionException) {
+ out << "Scope " << scope.d_level << ":";
+ ContextObj* pContextObj = scope.d_pContextObjList;
+ Assert(pContextObj == NULL ||
+ pContextObj->prev() == &scope.d_pContextObjList);
+ while(pContextObj != NULL) {
+ out << " <--> " << pContextObj;
+ Assert(pContextObj->d_pScope == &scope);
+ Assert(pContextObj->next() == NULL ||
+ pContextObj->next()->prev() == &pContextObj->next());
+ pContextObj = pContextObj->next();
}
+ return out << " --> NULL";
}
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback