/// <inheritdoc />
        public bool Equals(TypeSignature x, TypeSignature y)
        {
            if (ReferenceEquals(x, y))
            {
                return(true);
            }
            if (ReferenceEquals(x, null) || ReferenceEquals(y, null))
            {
                return(false);
            }

            return(x switch
            {
                CorLibTypeSignature corLibType => Equals(corLibType, y as CorLibTypeSignature),
                TypeDefOrRefSignature typeDefOrRef => Equals(typeDefOrRef, y as TypeDefOrRefSignature),
                SzArrayTypeSignature szArrayType => Equals(szArrayType, y as SzArrayTypeSignature),
                ArrayTypeSignature arrayType => Equals(arrayType, y as ArrayTypeSignature),
                ByReferenceTypeSignature byRefType => Equals(byRefType, y as ByReferenceTypeSignature),
                BoxedTypeSignature boxedType => Equals(boxedType, y as BoxedTypeSignature),
                GenericInstanceTypeSignature genericInstanceType => Equals(genericInstanceType, y as GenericInstanceTypeSignature),
                GenericParameterSignature genericParameter => Equals(genericParameter, y as GenericParameterSignature),
                PointerTypeSignature pointerType => Equals(pointerType, y as PointerTypeSignature),
                PinnedTypeSignature pinnedType => Equals(pinnedType, y as PinnedTypeSignature),
                CustomModifierTypeSignature modifierType => Equals(modifierType, y as CustomModifierTypeSignature),
                _ => throw new NotSupportedException()
            });
예제 #2
0
 private ByReferenceTypeSignature ImportByRefTypeSignature(ByReferenceTypeSignature signature)
 {
     return(new ByReferenceTypeSignature(ImportTypeSignature(signature.BaseType))
     {
         IsValueType = signature.IsValueType
     });
 }
예제 #3
0
        public CilExpression Translate(RecompilerContext context, ILVCallExpression expression)
        {
            var metadata = (FieldAnnotation)expression.Annotation;

            // Enter generic context for member.
            context.EnterMember(metadata.Field);

            var  fieldDef = metadata.Field.Resolve();
            bool hasThis  = !fieldDef?.IsStatic ?? metadata.Field.Signature.HasThis;

            // Select opcode and expression type.
            var       expressionType = metadata.Field.Signature.FieldType;
            CilOpCode opCode;

            if (metadata.IsAddress)
            {
                expressionType = new ByReferenceTypeSignature(expressionType);
                opCode         = hasThis ? CilOpCodes.Ldflda : CilOpCodes.Ldsflda;
            }
            else
            {
                opCode = hasThis ? CilOpCodes.Ldfld : CilOpCodes.Ldsfld;
            }

            // Construct CIL expression.
            var result = new CilInstructionExpression(opCode, metadata.Field)
            {
                ExpressionType = expressionType.InstantiateGenericTypes(context.GenericContext)
            };

            if (hasThis)
            {
                // Recompile object expression if field is an instance field.
                var objectExpression = (CilExpression)expression.Arguments[expression.Arguments.Count - 1]
                                       .AcceptVisitor(context.Recompiler);

                var objectType = metadata.Field.DeclaringType
                                 .ToTypeSignature()
                                 .InstantiateGenericTypes(context.GenericContext);

                if (metadata.IsAddress)
                {
                    objectType = new ByReferenceTypeSignature(objectType);
                }

                objectExpression.ExpectedType = objectType;
                result.Arguments.Add(objectExpression);
            }

            // Leave generic context.
            context.ExitMember();

            return(result);
        }
예제 #4
0
        /// <summary>
        /// Determines whether two types are considered equal according to their signature.
        /// </summary>
        /// <param name="signature1">The first type to compare.</param>
        /// <param name="signature2">The second type to compare.</param>
        /// <returns><c>True</c> if the types are considered equal, <c>False</c> otherwise.</returns>
        public bool Equals(ByReferenceTypeSignature signature1, ByReferenceTypeSignature signature2)
        {
            if (signature1 == null && signature2 == null)
            {
                return(true);
            }
            if (signature1 == null || signature2 == null)
            {
                return(false);
            }

            return(Equals(signature1.BaseType, signature2.BaseType));
        }
예제 #5
0
        public IList <CilExpression> RecompileCallArguments(
            IMethodDescriptor method,
            IList <ILExpression> arguments,
            VMECallOpCode opCode,
            ITypeDescriptor constrainedType = null)
        {
            var methodSig = method.Signature;
            var result    = new List <CilExpression>();

            // Emit arguments.
            for (var i = 0; i < arguments.Count; i++)
            {
                // Recompile argument.
                var cilArgument = (CilExpression)arguments[i].AcceptVisitor(Recompiler);

                // Figure out expected argument type.
                TypeSignature argumentType;
                if (methodSig.HasThis && opCode != VMECallOpCode.NEWOBJ)
                {
                    // Instance method invocation.

                    if (i == 0)
                    {
                        // First parameter is the object instance that this method is called on (implicit this parameter).
                        argumentType = constrainedType?.ToTypeSignature() ?? method.DeclaringType.ToTypeSignature();

                        // Calls on instance methods of value types need the this parameter to be passed on by-ref.
                        if (argumentType.IsValueType)
                        {
                            argumentType = new ByReferenceTypeSignature(argumentType);
                        }
                    }
                    else
                    {
                        argumentType = methodSig.ParameterTypes[i - 1];
                    }
                }
                else
                {
                    // Static method invocation.
                    argumentType = methodSig.ParameterTypes[i];
                }

                cilArgument.ExpectedType = argumentType.InstantiateGenericTypes(GenericContext);
                result.Add(cilArgument);
            }
            return(result);
        }
예제 #6
0
        public CilExpression Translate(RecompilerContext context, ILVCallExpression expression)
        {
            var metadata  = (FieldAnnotation)expression.Annotation;
            var fieldType = metadata.Field.Signature.FieldType;

            // Enter generic context.
            context.EnterMember(metadata.Field);

            var  fieldDef = metadata.Field.Resolve();
            bool hasThis  = !fieldDef?.IsStatic ?? metadata.Field.Signature.HasThis;

            // Construct CIL expression.
            var result = new CilInstructionExpression(hasThis ? CilOpCodes.Stfld : CilOpCodes.Stsfld, metadata.Field);

            if (hasThis)
            {
                // Recompile object expression if field is an instance field.
                var objectExpression = (CilExpression)expression.Arguments[expression.Arguments.Count - 2]
                                       .AcceptVisitor(context.Recompiler);

                var objectType = metadata.Field.DeclaringType
                                 .ToTypeSignature()
                                 .InstantiateGenericTypes(context.GenericContext);

                // Struct members can only be accessed when the object is passed on by reference.
                if (metadata.Field.DeclaringType.IsValueType)
                {
                    objectType = new ByReferenceTypeSignature(objectType);
                }

                objectExpression.ExpectedType = objectType;
                result.Arguments.Add(objectExpression);
            }

            // Recompile value.
            var valueExpression = (CilExpression)expression.Arguments[expression.Arguments.Count - 1]
                                  .AcceptVisitor(context.Recompiler);

            valueExpression.ExpectedType = fieldType.InstantiateGenericTypes(context.GenericContext);
            result.Arguments.Add(valueExpression);

            // Exit generic context.
            context.ExitMember();

            return(result);
        }
예제 #7
0
        public CilMethodBody(MethodDefinition method)
        {
            Method                 = method;
            MaxStack               = 8;
            Instructions           = new CilInstructionCollection(this);
            ExceptionHandlers      = new List <ExceptionHandler>();
            ComputeMaxStackOnBuild = true;

            _thisParameter = new LazyValue <ParameterSignature>(() =>
            {
                if (method.DeclaringType == null)
                {
                    return(null);
                }

                var typeSig = method.DeclaringType.ToTypeSignature();
                if (method.DeclaringType.IsValueType)
                {
                    typeSig = new ByReferenceTypeSignature(typeSig);
                }

                return(new ParameterSignature(typeSig));
            });
        }
예제 #8
0
 /// <inheritdoc />
 public int GetHashCode(ByReferenceTypeSignature obj) =>
 GetHashCode(obj as TypeSpecificationSignature);
예제 #9
0
 /// <inheritdoc />
 public bool Equals(ByReferenceTypeSignature x, ByReferenceTypeSignature y) =>
 Equals(x as TypeSpecificationSignature, y);
예제 #10
0
 /// <inheritdoc />
 public object VisitByReferenceType(ByReferenceTypeSignature signature)
 {
     signature.BaseType.AcceptVisitor(this);
     _writer.Write('&');
     return(null);
 }
예제 #11
0
 public uint VisitByReferenceType(ByReferenceTypeSignature signature) => PointerSize;
예제 #12
0
 /// <inheritdoc />
 public TypeMemoryLayout VisitByReferenceType(ByReferenceTypeSignature signature) =>
 new TypeMemoryLayout(signature, PointerSize);