A Property is similar to a
Field.
However, instead of holding a place to store data, it holds
functions that are used to set and retrieve the
data. This way, some operation may be performed on
the data before it is stored or retrieved, or multiple data
fields may be kept in sync automatically simply by referencing
the property. A property is always a member of a
class; it may not be stored directly in an assembly.
While properties can have variably long argument lists which can
be used to 'index' the property, the normal case is that the
function which 'gets' the value takes no arguments and returns a
value of the appropriate type. The function which
'sets' the value takes one argument, which is the value to set.
Generally, once a property is defined it can be treated like a
field, except that instead of using LDFLD/LDSFLD STFLD/STSFLD to
store and load the data, one would call the appropriate getter
or setter. The Property object will create these
calls, and has functions for generating the call instructions.
The Property object may be constructed either directly or
through an
Allocator
object. In the normal case one would pass an empty
vector for the 'indices' parameter.
Property(PELib
&peLib, std::string name, Type *type, std::vector<Type
*>& indices, bool hasSetter = true);
Set the parent container. Usually done automatically
when the Property is added to a class.
void
SetContainer(DataContainer *parent, bool add = true);
Access whether or not this is a static property.
void Instance(bool
instance);
bool
Instance() const { return instance_; }
Get the property name.
const
std::string &Name() const { return name_; }
Access the type of the data the property represents
void
SetType(Type *type) { type_ = type; }
Type
*GetType() const { return type_; }
Call the property's getter. One should push the
class instance on the stack first if this is not a static
property.
void CallGet(PELib
&peLib, CodeContainer *code);
Call the property's setter. One should
optionally push the class instance on the stack, then push the
data to be set
void
CallSet(PELib &peLib, CodeContainer *code);
Retrieve the getter or setter functions. When
creating a property this is necessary so that you can add code
to these functions.
Method
*Getter() { return getter_; }
Method
*Setter() { return setter_; }