1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
|
#pragma once
#include "Content.h"
#include "OffsetSource.h"
#include "Size.h"
namespace code {
STORM_PKG(core.asm);
/**
* Offset references work similar to regular references (see Ref and Reference).
*
* The main difference is that OffsetRef and OffsetReference might not refer to any source,
* meaning they are simply the offset 0.
*
* Furthermore, these offsets also contain a regular offset, meaning that their final value is
* the sum of the contained offset and whatever offset the original offset is referring to.
*/
/**
* A weak reference to an offset. Might be 'null', meaning a zero offset.
*/
class OffsetRef {
STORM_VALUE;
friend class OffsetReference;
friend class Operand;
friend wostream &operator <<(wostream &to, const OffsetRef &r);
public:
STORM_CTOR OffsetRef();
STORM_CAST_CTOR OffsetRef(OffsetSource *to);
STORM_CAST_CTOR OffsetRef(OffsetReference *ref);
STORM_CTOR OffsetRef(OffsetSource *to, Offset offset);
void STORM_FN deepCopy(CloneEnv *env);
inline Bool STORM_FN operator ==(const OffsetRef &o) const {
return to == o.to && delta == o.delta;
}
inline Bool STORM_FN operator !=(const OffsetRef &o) const {
return !(*this == o);
}
// Add/subtract from the internal offset.
inline OffsetRef STORM_FN operator +(Offset o) const {
return OffsetRef(to, delta + o);
}
inline OffsetRef STORM_FN operator -(Offset o) const {
return OffsetRef(to, delta - o);
}
// Get the offset.
Offset STORM_FN offset() const;
// Get the source.
inline MAYBE(OffsetSource *) STORM_FN source() const { return to; }
// Get the current difference from the base offset.
inline Offset STORM_FN diff() const { return delta; }
// Output.
void STORM_FN toS(StrBuf *to) const ON(Compiler);
private:
// Referring to.
MAYBE(OffsetSource *) to;
// Our offset.
Offset delta;
};
wostream &operator <<(wostream &to, const OffsetRef &r);
/**
* Robust reference.
*/
class OffsetReference : public ObjectOn<Compiler> {
STORM_CLASS;
friend class OffsetRef;
friend class OffsetSource;
friend class Operand;
public:
// First parameter is what the reference should refer to, second is who is referring.
STORM_CTOR OffsetReference(OffsetSource *to, Content *inside);
STORM_CTOR OffsetReference(OffsetSource *to, Offset offset, Content *inside);
STORM_CTOR OffsetReference(OffsetRef to, Content *inside);
// Get the content we're associated with, ie. who's referring to something.
inline Content *referrer() const { return owner; }
// Notification of changed offset.
virtual void moved(Offset newOffset);
// Get current offset.
Offset STORM_FN offset() const;
// Get the source.
inline MAYBE(OffsetSource *) STORM_FN source() const { return to; }
// ToS.
virtual void STORM_FN toS(StrBuf *to) const;
private:
// Owner = referrer
Content *owner;
// Who are we referring to?
MAYBE(OffsetSource *) to;
// Offset related to 'to'.
Offset delta;
// Called by OffsetSource.
void onMoved(Offset newOffset);
};
}
|