Property
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_;  }