Updates.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "klee/Expr.h"
00011
00012 #include <cassert>
00013
00014 using namespace klee;
00015
00017
00018 UpdateNode::UpdateNode(const UpdateNode *_next,
00019 const ref<Expr> &_index,
00020 const ref<Expr> &_value)
00021 : refCount(0),
00022 stpArray(0),
00023 next(_next),
00024 index(_index),
00025 value(_value) {
00026 assert(_value->getWidth() == Expr::Int8 &&
00027 "Update value should be 8-bit wide.");
00028 computeHash();
00029 if (next) {
00030 ++next->refCount;
00031 size = 1 + next->size;
00032 }
00033 else size = 1;
00034 }
00035
00036 extern "C" void vc_DeleteExpr(void*);
00037
00038 UpdateNode::~UpdateNode() {
00039
00040 if (stpArray)
00041 ::vc_DeleteExpr(stpArray);
00042 }
00043
00044 int UpdateNode::compare(const UpdateNode &b) const {
00045 if (int i = index.compare(b.index))
00046 return i;
00047 return value.compare(b.value);
00048 }
00049
00050 unsigned UpdateNode::computeHash() {
00051 hashValue = index->hash() ^ value->hash();
00052 if (next)
00053 hashValue ^= next->hash();
00054 return hashValue;
00055 }
00056
00058
00059 UpdateList::UpdateList(const Array *_root, bool _isRooted,
00060 const UpdateNode *_head)
00061 : root(_root),
00062 head(_head),
00063 isRooted(_isRooted) {
00064 if (head) ++head->refCount;
00065 }
00066
00067 UpdateList::UpdateList(const UpdateList &b)
00068 : root(b.root),
00069 head(b.head),
00070 isRooted(b.isRooted) {
00071 if (head) ++head->refCount;
00072 }
00073
00074 UpdateList::~UpdateList() {
00075
00076
00077
00078 while (head && --head->refCount==0) {
00079 const UpdateNode *n = head->next;
00080 delete head;
00081 head = n;
00082 }
00083 }
00084
00085 UpdateList &UpdateList::operator=(const UpdateList &b) {
00086 if (b.head) ++b.head->refCount;
00087 if (head && --head->refCount==0) delete head;
00088 root = b.root;
00089 head = b.head;
00090 isRooted = b.isRooted;
00091 return *this;
00092 }
00093
00094 void UpdateList::extend(const ref<Expr> &index, const ref<Expr> &value) {
00095 if (head) --head->refCount;
00096 head = new UpdateNode(head, index, value);
00097 ++head->refCount;
00098 }
00099
00100 int UpdateList::compare(const UpdateList &b) const {
00101
00102 if (root->id != b.root->id)
00103 return root->id < b.root->id ? -1 : 1;
00104
00105 if (getSize() < b.getSize()) return -1;
00106 else if (getSize() > b.getSize()) return 1;
00107
00108
00109 const UpdateNode *an=head, *bn=b.head;
00110 for (; an && bn; an=an->next,bn=bn->next) {
00111 if (an==bn) {
00112 return 0;
00113 } else {
00114 if (int res = an->compare(*bn))
00115 return res;
00116 }
00117 }
00118 assert(!an && !bn);
00119 return 0;
00120 }
00121
00122 unsigned UpdateList::hash() const {
00123 unsigned res = root->id * Expr::MAGIC_HASH_CONSTANT;
00124 if (head)
00125 res ^= head->hash();
00126 return res;
00127 }