/// <summary>
        /// Pushes the value of the reference onto the stack.
        /// </summary>
        /// <param name="generator"> The generator to output the CIL to. </param>
        /// <param name="optimizationInfo"> Information about any optimizations that should be performed. </param>
        /// <param name="throwIfUnresolvable"> <c>true</c> to throw a ReferenceError exception if
        /// the name is unresolvable; <c>false</c> to output <c>null</c> instead. </param>
        public void GenerateGet(ILGenerator generator, OptimizationInfo optimizationInfo, bool throwIfUnresolvable)
        {
            string             propertyName     = null;
            TypeOfMemberAccess memberAccessType = DetermineTypeOfMemberAccess(optimizationInfo, out propertyName);

            if (memberAccessType == TypeOfMemberAccess.ArrayIndex)
            {
                // Array indexer
                // -------------
                // xxx = object[index]

                // Call the indexer.
                generator.Call(ReflectionHelpers.ObjectInstance_Indexer_UInt);
            }
            else if (memberAccessType == TypeOfMemberAccess.Static)
            {
                // Named property access (e.g. x = y.property)
                // -------------------------------------------

                // Use a PropertyReference to speed up access if we are inside a loop.
                if (optimizationInfo.InsideLoop)
                {
                    // C#
                    // if (propertyReference != null)
                    //     propertyReference = new PropertyReference("property");
                    // value = object.GetPropertyValue(propertyReference)

                    ILLocalVariable propertyReference = optimizationInfo.GetPropertyReferenceVariable(generator, propertyName);
                    generator.LoadVariable(propertyReference);
                    generator.Duplicate();
                    var afterIf = generator.CreateLabel();
                    generator.BranchIfNotNull(afterIf);
                    generator.Pop();
                    generator.LoadString(propertyName);
                    generator.NewObject(ReflectionHelpers.PropertyName_Constructor);
                    generator.Duplicate();
                    generator.StoreVariable(propertyReference);
                    generator.DefineLabelPosition(afterIf);
                    generator.Call(ReflectionHelpers.ObjectInstance_GetPropertyValue_PropertyReference);
                }
                else
                {
                    // C#
                    // value = object.GetPropertyValue("property")

                    generator.LoadString(propertyName);
                    generator.Call(ReflectionHelpers.ObjectInstance_Indexer_Object);
                }
            }
            else
            {
                // Dynamic property access
                // -----------------------
                // x = y.GetPropertyValue("property")

                generator.Call(ReflectionHelpers.ObjectInstance_Indexer_Object);
            }
        }
        /// <summary>
        /// Stores the value on the top of the stack in the reference.
        /// </summary>
        /// <param name="generator"> The generator to output the CIL to. </param>
        /// <param name="optimizationInfo"> Information about any optimizations that should be performed. </param>
        /// <param name="valueType"> The primitive type of the value that is on the top of the stack. </param>
        public void GenerateSet(ILGenerator generator, OptimizationInfo optimizationInfo, PrimitiveType valueType)
        {
            string             propertyName     = null;
            TypeOfMemberAccess memberAccessType = DetermineTypeOfMemberAccess(optimizationInfo, out propertyName);

            if (memberAccessType == TypeOfMemberAccess.ArrayIndex)
            {
                // Array indexer
                // -------------
                // xxx = object[index]

                // Call the indexer.
                EmitConversion.ToAny(generator, valueType);
                generator.LoadBoolean(optimizationInfo.StrictMode);
                generator.Call(ReflectionHelpers.ObjectInstance_SetPropertyValue_Int);
                generator.Pop();
            }
            else if (memberAccessType == TypeOfMemberAccess.Static)
            {
                // Named property modification (e.g. object.property = value)
                // ----------------------------------------------------------
                // object.SetPropertyValue(property, value, strictMode)

                // Convert the value to an object and store it in a temporary variable.
                var value = generator.CreateTemporaryVariable(typeof(object));
                EmitConversion.ToAny(generator, valueType);
                generator.StoreVariable(value);

                // Use a PropertyReference to speed up access if we are inside a loop.
                if (optimizationInfo.InsideLoop)
                {
                    ILLocalVariable propertyReference = optimizationInfo.GetPropertyReferenceVariable(generator, propertyName);
                    generator.LoadVariable(propertyReference);
                    generator.Duplicate();
                    var afterIf = generator.CreateLabel();
                    generator.BranchIfNotNull(afterIf);
                    generator.Pop();
                    generator.LoadString(propertyName);
                    generator.NewObject(ReflectionHelpers.PropertyName_Constructor);
                    generator.Duplicate();
                    generator.StoreVariable(propertyReference);
                    generator.DefineLabelPosition(afterIf);

                    generator.LoadVariable(value);
                    generator.LoadBoolean(optimizationInfo.StrictMode);
                    generator.Call(ReflectionHelpers.ObjectInstance_SetPropertyValue_PropertyReference);
                    generator.Pop();
                }
                else
                {
                    generator.LoadString(propertyName);
                    generator.LoadVariable(value);
                    generator.LoadBoolean(optimizationInfo.StrictMode);
                    generator.Call(ReflectionHelpers.ObjectInstance_SetPropertyValue_Object);
                    generator.Pop();
                }

                generator.ReleaseTemporaryVariable(value);
            }
            else
            {
                // Dynamic property access
                // -----------------------
                // object.SetPropertyValue(property, value, strictMode)

                EmitConversion.ToAny(generator, valueType);
                generator.LoadBoolean(optimizationInfo.StrictMode);
                generator.Call(ReflectionHelpers.ObjectInstance_SetPropertyValue_Object);
                generator.Pop();
            }
        }