public void StoreObject(Type type)
        {
            if (Index == null)
            {
                return;
            }
            if (type.IsValueType)
            {
                throw new InvalidOperationException("A reference type expected");
            }
            // Store in array of all references
            LoadContext();                        // stack: [context]
            Il.Ldfld(ReaderContext.ObjectsField); // stack: [context.objects]
            var doneLabel = Il.DefineLabel("done");

            Il.Brfalse(doneLabel);                                                                           // if(context.objects == null) goto done; stack: []

            LoadContext();                                                                                   // stack: [context]
            Il.Ldfld(ReaderContext.ObjectsField);                                                            // stack: [context.objects]
            Il.Ldloc(Index);                                                                                 // stack: [context.objects, index]
            LoadResult(type);                                                                                // stack: [context.objects, index, result]
            Il.Call(HackHelpers.GetMethodDefinition <Dictionary <int, object> >(dict => dict.Add(0, null))); // context.objects.Add(index, result)
            Il.MarkLabel(doneLabel);
        }
 /// <summary>
 ///     Loads the specified field onto the evaluation stack
 /// </summary>
 /// <param name="field">Field to load</param>
 public void LoadField(FieldInfo field)
 {
     Il.Ldfld(field);
 }
 /// <summary>
 ///     Loads <c>context.serializerId</c> onto the evaluation stack
 /// </summary>
 public void LoadSerializerId()
 {
     LoadContext();
     Il.Ldfld(ReaderContext.SerializerIdField);
 }
 /// <summary>
 ///     Loads <c>dataLength</c> onto the evaluation stack
 /// </summary>
 public void LoadDataLength()
 {
     LoadContext();
     Il.Ldfld(ReaderContext.LengthField);
 }
        public void EmitMemberAccess(Type type, MemberInfo member, ResultType whatReturn, out Type memberType)
        {
            switch (member.MemberType)
            {
            case MemberTypes.Property:
                var property = (PropertyInfo)member;
                var getter   = property.GetGetMethod(SkipVisibility);
                if (getter == null)
                {
                    throw new MissingMemberException(member.DeclaringType.Name, member.Name + "_get");
                }
                Il.Call(getter, type);
                Type propertyType = property.PropertyType;
                switch (whatReturn)
                {
                case ResultType.ByRefValueTypesOnly:
                    if (!propertyType.IsValueType)
                    {
                        memberType = propertyType;
                    }
                    else
                    {
                        using (var temp = DeclareLocal(propertyType))
                        {
                            Il.Stloc(temp);
                            Il.Ldloca(temp);
                            memberType = propertyType.MakeByRefType();
                        }
                    }
                    break;

                case ResultType.ByRefAll:
                    throw new InvalidOperationException("It's wierd to load a property by ref for a reference type");

                default:
                    memberType = propertyType;
                    break;
                }
                break;

            case MemberTypes.Field:
                var field = (FieldInfo)member;
                switch (whatReturn)
                {
                case ResultType.ByRefAll:
                    Il.Ldflda(field);
                    memberType = field.FieldType.MakeByRefType();
                    break;

                case ResultType.ByRefValueTypesOnly:
                    if (field.FieldType.IsValueType)
                    {
                        Il.Ldflda(field);
                        memberType = field.FieldType.MakeByRefType();
                    }
                    else
                    {
                        Il.Ldfld(field);
                        memberType = field.FieldType;
                    }
                    break;

                default:
                    Il.Ldfld(field);
                    memberType = field.FieldType;
                    break;
                }
                break;

            default:
                throw new NotSupportedException("Member type '" + member.MemberType + "' is not supported");
            }
        }
 /// <summary>
 ///     Loads <c>length</c> onto the evaluation stack
 /// </summary>
 public void LoadResultLength()
 {
     LoadContext();
     Il.Ldfld(WriterContext.LengthField);
 }