Exemple #1
0
        static DmdFieldInfo?TryGetBuilderFieldByType(DmdType type)
        {
            DmdFieldInfo?builderField = null;

            foreach (var field in type.Fields)
            {
                var fieldType = field.FieldType;
                if (fieldType.IsNested)
                {
                    continue;
                }
                if (fieldType.IsConstructedGenericType)
                {
                    fieldType = fieldType.GetGenericTypeDefinition();
                }
                foreach (var info in builderWellKnownTypeNames)
                {
                    if (fieldType.MetadataNamespace == info.@namespace && fieldType.MetadataName == info.name)
                    {
                        return(field);
                    }
                }
                if (builderField is null && fieldType.MetadataName is not null &&
                    (fieldType.MetadataName.EndsWith("MethodBuilder", StringComparison.Ordinal) ||
                     fieldType.MetadataName.EndsWith("MethodBuilder`1", StringComparison.Ordinal)))
                {
                    builderField = field;
                }
            }

            return(builderField);
        }
Exemple #2
0
        /// <summary>
        /// Gets the builder instance. It's assumed to be stored in a field in the current 'this' instance.
        ///
        /// The decompiler should already know the field. If that info isn't available, we'll try to find
        /// the field by name, and if that fails, by field type.
        ///
        /// null is returned if we couldn't find the field or if we failed to read the field.
        /// </summary>
        /// <param name="evalInfo">Evaluation info</param>
        /// <param name="builderFieldModule">Module of builder field or null if unknown</param>
        /// <param name="builderFieldToken">Token of builder field or 0 if unknown</param>
        /// <returns></returns>
        public static DbgDotNetValue?TryGetBuilder(DbgEvaluationInfo evalInfo, DmdModule?builderFieldModule, uint builderFieldToken)
        {
            DbgDotNetValueResult thisArg   = default;
            DbgDotNetValueResult tmpResult = default;

            try {
                var runtime = evalInfo.Runtime.GetDotNetRuntime();
                thisArg = runtime.GetParameterValue(evalInfo, 0);
                if (!thisArg.IsNormalResult || thisArg.Value !.IsNull)
                {
                    return(null);
                }
                if (thisArg.Value.Type.IsByRef)
                {
                    tmpResult = thisArg.Value.LoadIndirect();
                    if (!tmpResult.IsNormalResult || tmpResult.Value !.IsNull)
                    {
                        return(null);
                    }
                    thisArg.Value?.Dispose();
                    thisArg   = tmpResult;
                    tmpResult = default;
                }

                DmdFieldInfo?builderField = null;
                if (builderFieldModule is not null && builderFieldToken != 0)
                {
                    builderField = thisArg.Value.Type.GetField(builderFieldModule, (int)builderFieldToken);
                }
                if (builderField is null)
                {
                    builderField = TryGetBuilderField(thisArg.Value.Type);
                }
                if (builderField is null)
                {
                    return(null);
                }
                Debug.Assert((object)builderField == TryGetBuilderFieldByType(thisArg.Value.Type));
                Debug2.Assert(TryGetBuilderFieldByname(thisArg.Value.Type) is null ||
                              (object?)TryGetBuilderFieldByname(thisArg.Value.Type) == TryGetBuilderFieldByType(thisArg.Value.Type));
                tmpResult = runtime.LoadField(evalInfo, thisArg.Value, builderField);
                if (!tmpResult.IsNormalResult || tmpResult.Value !.IsNull)
                {
                    return(null);
                }
                var fieldValue = tmpResult.Value;
                tmpResult = default;
                return(fieldValue);
            }
            finally {
                thisArg.Value?.Dispose();
                tmpResult.Value?.Dispose();
            }
        }
Exemple #3
0
        /// <summary>
        /// Compares two fields
        /// </summary>
        /// <param name="a">First field</param>
        /// <param name="b">Second field</param>
        /// <returns></returns>
        public bool Equals(DmdFieldInfo?a, DmdFieldInfo?b)
        {
            if ((object?)a == b)
            {
                return(true);
            }
            if (a is null || b is null)
            {
                return(false);
            }

            return(MemberNameEquals(a.Name, b.Name) &&
                   Equals(a.FieldType, b.FieldType) &&
                   (!CompareDeclaringType || Equals(a.DeclaringType, b.DeclaringType)));
        }
Exemple #4
0
        /// <summary>
        /// Gets the hash code of a field
        /// </summary>
        /// <param name="a">Field</param>
        /// <returns></returns>
        public int GetHashCode(DmdFieldInfo?a)
        {
            if (a is null)
            {
                return(0);
            }

            int hc = MemberNameGetHashCode(a.Name);

            hc ^= GetHashCode(a.FieldType);
            if (CompareDeclaringType)
            {
                hc ^= GetHashCode(a.DeclaringType);
            }
            return(hc);
        }
Exemple #5
0
        public static (DmdFieldInfo?hasValueField, DmdFieldInfo?valueField) TryGetNullableFields(DmdType type)
        {
            Debug.Assert(type.IsNullable);

            DmdFieldInfo?hasValueField = null;
            DmdFieldInfo?valueField    = null;
            var          fields        = type.DeclaredFields;

            for (int i = 0; i < fields.Count; i++)
            {
                var field = fields[i];
                if (field.IsStatic || field.IsLiteral)
                {
                    continue;
                }
                switch (field.Name)
                {
                case KnownMemberNames.Nullable_HasValue_FieldName:
                case KnownMemberNames.Nullable_HasValue_FieldName_Mono:
                    if (!(hasValueField is null))
                    {
                        return(null, null);
                    }
                    hasValueField = field;
                    break;

                case KnownMemberNames.Nullable_Value_FieldName:
                    if (!(valueField is null))
                    {
                        return(null, null);
                    }
                    valueField = field;
                    break;

                default:
                    return(null, null);
                }
            }

            if (hasValueField is null || valueField is null)
            {
                return(null, null);
            }
            return(hasValueField, valueField);
        }
Exemple #6
0
        public static (DmdFieldInfo?keyField, DmdFieldInfo?valueField) TryGetFields(DmdType type, string keyFieldName, string valueFieldName)
        {
            DmdFieldInfo?keyField   = null;
            DmdFieldInfo?valueField = null;
            var          fields     = type.DeclaredFields;

            for (int i = 0; i < fields.Count; i++)
            {
                var field = fields[i];
                if (field.IsStatic || field.IsLiteral)
                {
                    continue;
                }
                if (field.Name == keyFieldName)
                {
                    if (!(keyField is null))
                    {
                        return(null, null);
                    }
                    keyField = field;
                }
                else if (field.Name == valueFieldName)
                {
                    if (!(valueField is null))
                    {
                        return(null, null);
                    }
                    valueField = field;
                }
                else
                {
                    return(null, null);
                }
            }

            if (keyField is null || valueField is null)
            {
                return(null, null);
            }
            return(keyField, valueField);
        }