#ifndef SUIFKERNEL__GROUP_WALKER
#define SUIFKERNEL__GROUP_WALKER
#include "suif_walker.h"
#include "suif_object.h"
#include "common/sparse_vector.h"
#include "common/suif_hash_map.h"
class SelectiveWalker : public SuifWalker {
private:
bool is_visitable(Address address,const MetaClass *_meta) const;
public:
SelectiveWalker(SuifEnv *the_env,const LString &the_type);
Walker::ApplyStatus operator () (SuifObject *x) = 0;
const LString & get_type() const;
private:
const LString type;
};
/*
* The typeless implementation for the TypeBasedDispatch template.
*/
class TypeBasedDispatchHelper {
SparseVector<void *> _vector;
bool _locked;
public:
TypeBasedDispatchHelper();
void set_value(const LString &index, void *val);
void *lookup_value(SuifObject *x);
void *get_value(SuifObject *x) const;
};
template <class T>
class TypeBasedDispatch {
TypeBasedDispatchHelper _helper;
public:
TypeBasedDispatch() {}
void set_value(const LString &index, T val) {
_helper.set_value(index, (void*)val);
}
T lookup_value(SuifObject *x) {
return((T)_helper.lookup_value(x));
}
T get_value(SuifObject *x) const {
return((T)_helper.get_value(index));
}
};
class GroupWalker : public SuifWalker {
TypeBasedDispatch <SelectiveWalker*> *_vector;
protected:
Walker::ApplyStatus operator () (SuifObject *x);
public:
GroupWalker(SuifEnv *the_env);
virtual ~GroupWalker();
void append_walker(SelectiveWalker &x);
};
class ReplacingWalker : public GroupWalker {
suif_hash_map<Address,Object *> _map;
public:
ReplacingWalker(SuifEnv *the_env);
virtual bool is_walkable(Address address,bool is_owned,
const MetaClass *_meta);
Walker::ApplyStatus operator () (SuifObject *x);
void add_replacement(Object *from,Object *to);
Object *get_replacement(Object *x) const;
bool get_makes_changes() const;
bool is_changed(Address addr) const;
suif_hash_map<Address,Object *>::iterator get_map_begin() {return _map.begin();}
suif_hash_map<Address,Object *>::iterator get_map_end() {return _map.end();}
suif_hash_map<Address,Object *>::const_iterator get_map_begin() const {return _map.begin();}
suif_hash_map<Address,Object *>::const_iterator get_map_end() const {return _map.end();}
};
#endif