00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef FRAME_HH
00019 # define FRAME_HH
00020
00021 # include "../memory/pool_allocator.hh"
00022
00023 namespace aurelia {
00024 namespace llstack {
00025
00026 struct real_frame {
00027 virtual real_frame* clone() const = 0;
00028 virtual unsigned hash() const = 0;
00029 virtual bool operator==(const real_frame& other) const = 0;
00030 virtual ~real_frame() {
00031 }
00032 virtual std::string toString() const = 0;
00033 };
00034
00035 template <typename T>
00036 struct real_frame_helper: public real_frame {
00037 void* operator new
00038 #ifdef NDEBUG
00039 (size_t) {
00040 #else
00041 (size_t t) {
00042 #endif
00043 assert(t == sizeof(T));
00044 return chunk_alloc<T>::alloc();
00045 }
00046
00047 void operator delete(void *p) {
00048 chunk_alloc<T>::del((T*) p);
00049 }
00050
00051 virtual real_frame* clone() const {
00052 return new T(*static_cast<const T*>(this));
00053 }
00054
00055 virtual bool operator==(const real_frame& other) const {
00056 const T* rother = dynamic_cast<const T*>(&other);
00057 if (rother == NULL)
00058 return false;
00059 return static_cast<const T*>(this)->opeq_impl(*rother);
00060 }
00061 };
00062
00063 struct empty_frame: real_frame_helper<empty_frame> {
00064 virtual unsigned hash() const {
00065 return 4182910;
00066 }
00067 bool opeq_impl(const empty_frame&) const {
00068 return true;
00069 }
00070 virtual std::string toString() const {
00071 return "empty_frame";
00072 }
00073 };
00074
00075 struct frame {
00076 private:
00077 std::shared_ptr<real_frame> rf;
00078 unsigned _hash;
00079
00080 public:
00081 std::string toString() const {
00082 return rf->toString();
00083 }
00084
00085 frame(const real_frame& rf): rf(rf.clone()), _hash(rf.hash()) {}
00086 frame(const frame& other): rf(other.rf), _hash(other._hash) {}
00087 frame(frame&& other): rf(std::move(other.rf)), _hash(std::move(other._hash)) {
00088 }
00089
00090 frame(): rf(), _hash(0) {
00091 }
00092
00093 frame& operator=(const frame& other) {
00094 return *this = frame(other);
00095 }
00096
00097 frame& operator=(frame&& other) {
00098 std::swap(rf, other.rf);
00099 std::swap(_hash, other._hash);
00100 return *this;
00101 }
00102
00103 struct hash_op {
00104 unsigned operator()(const frame& a) const {
00105 return a._hash;
00106 }
00107 };
00108
00109 struct eq {
00110 unsigned operator()(const frame& a, const frame& b) const {
00111 return *(a.rf) == *(b.rf);
00112 }
00113 };
00114
00115 unsigned hash() const {
00116 return _hash;
00117 }
00118
00119 bool operator==(const frame& other) const {
00120 if (&*rf == &*other.rf)
00121 return true;
00122 return *rf == *(other.rf);
00123 }
00124
00125 template <typename T>
00126 const T& as() const {
00127 #if NDEBUG
00128 return *static_cast<const T*>(&*rf);
00129 #else
00130 const T* ret = dynamic_cast<const T*>(&*rf);
00131 assert(ret != NULL);
00132 return *ret;
00133 #endif
00134 }
00135 };
00136
00137 template <typename T>
00138 struct ret_frame: real_frame_helper<ret_frame<T> > {
00139 frame parent;
00140 T t;
00141 ret_frame(const frame& f, const T& t): parent(f), t(t) {}
00142 ret_frame(const ret_frame& other): parent(other.parent), t(other.t) {}
00143 bool opeq_impl(const ret_frame& other) const {
00144 return (parent == other.parent) && (other.t == t);
00145 }
00146 virtual unsigned hash() const {
00147 unsigned h = parent.hash();
00148 h = (h << 1) | (h >> 31);
00149 h ^= t.hash();
00150 return h;
00151 }
00152 virtual std::string toString() const {
00153 std::stringstream ss;
00154 ss << t;
00155 return "ret_frame(" + parent.toString() + "," + ss.str() + ")";
00156 }
00157 };
00158
00159 struct void_return {
00160 unsigned hash() const {
00161 return 201293;
00162 }
00163 bool operator==(const void_return&) const {
00164 return true;
00165 }
00166 };
00167
00168 template <typename Stream>
00169 Stream& operator<<(Stream& s, const void_return&) {
00170 s << "Void";
00171 return s;
00172 }
00173
00174 }
00175 }
00176
00177 #endif