Ejemplo n.º 1
0
        public override CilExpression Translate(RecompilerContext context, ILInstructionExpression expression)
        {
            var result = base.Translate(context, expression);

            result.ExpressionType = null;
            return(result);
        }
Ejemplo n.º 2
0
        public CilExpression Translate(RecompilerContext context, ILVCallExpression expression)
        {
            var annotation = (LdftnAnnotation)expression.Annotation;

            IMethodDescriptor method;

            if (!annotation.IsIntraLinked)
            {
                method = annotation.Method;
            }
            else
            {
                method = context.ExportResolver.ResolveMethod(annotation.Function.EntrypointAddress);
                if (method == null)
                {
                    throw new RecompilerException(
                              $"Could not resolve function_{annotation.Function.EntrypointAddress:X4} to a physical method.");
                }
            }

            var result = new CilInstructionExpression(CilOpCodes.Ldftn, method)
            {
                ExpressionType = context.TargetModule.CorLibTypeFactory.IntPtr
            };

            if (annotation.IsVirtual)
            {
                var callingObject = (CilExpression)expression.Arguments[expression.Arguments.Count - 1]
                                    .AcceptVisitor(context.Recompiler);
                result.Instructions[0].OpCode = CilOpCodes.Ldvirtftn;
                result.Arguments.Add(callingObject);
            }

            return(result);
        }
Ejemplo n.º 3
0
        public CilExpression Translate(RecompilerContext context, ILInstructionExpression expression)
        {
            switch (expression.OpCode.Code)
            {
            case ILCode.PUSHR_OBJECT:
            case ILCode.PUSHR_BYTE:
            case ILCode.PUSHR_WORD:
            case ILCode.PUSHR_DWORD:
            case ILCode.PUSHR_QWORD:
                return(CompileRegisterPush(context, expression));

            case ILCode.PUSHI_DWORD:
                return(new CilInstructionExpression(CilOpCodes.Ldc_I4,
                                                    unchecked ((int)(uint)expression.Operand))
                {
                    ExpressionType = context.TargetImage.TypeSystem.Int32
                });

            case ILCode.PUSHI_QWORD:
                return(new CilInstructionExpression(CilOpCodes.Ldc_I8,
                                                    unchecked ((long)(ulong)expression.Operand))
                {
                    ExpressionType = context.TargetImage.TypeSystem.Int64
                });

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Ejemplo n.º 4
0
        public CilExpression Translate(RecompilerContext context, ILVCallExpression expression)
        {
            var boxMetadata = (BoxAnnotation)expression.Annotation;

            switch (boxMetadata.ReturnType)
            {
            case VMType.Object:
                switch (boxMetadata.Value)
                {
                case string stringValue:
                    return(new CilInstructionExpression(CilOpCodes.Ldstr, stringValue)
                    {
                        ExpressionType = context.TargetImage.TypeSystem.String
                    });

                case null:
                    var argument = (CilExpression)expression.Arguments[expression.Arguments.Count - 1]
                                   .AcceptVisitor(context.Recompiler);
                    argument.ExpectedType = boxMetadata.Type;
                    return(new CilInstructionExpression(CilOpCodes.Box, boxMetadata.Type, argument)
                    {
                        ExpressionType = context.TargetImage.TypeSystem.Object,
                    });

                default:
                    throw new NotImplementedException();
                }

            case VMType.Byte:
            case VMType.Word:
            case VMType.Dword:
                return(new CilInstructionExpression(CilOpCodes.Ldc_I4, Convert.ToInt32(boxMetadata.Value))
                {
                    ExpressionType = context.TargetImage.TypeSystem.Int32,
                });

            case VMType.Qword:
                return(new CilInstructionExpression(CilOpCodes.Ldc_I8, Convert.ToInt64(boxMetadata.Value))
                {
                    ExpressionType = context.TargetImage.TypeSystem.Int64,
                });

            case VMType.Real32:
                return(new CilInstructionExpression(CilOpCodes.Ldc_R4, Convert.ToSingle(boxMetadata.Value))
                {
                    ExpressionType = context.TargetImage.TypeSystem.Single,
                });

            case VMType.Real64:
                return(new CilInstructionExpression(CilOpCodes.Ldc_R8, Convert.ToDouble(boxMetadata.Value))
                {
                    ExpressionType = context.TargetImage.TypeSystem.Double,
                });

            case VMType.Unknown:
            case VMType.Pointer:
            default:
                throw new NotImplementedException();
            }
        }
Ejemplo n.º 5
0
        public CilExpression Translate(RecompilerContext context, ILVCallExpression expression)
        {
            var annotation = (LdftnAnnotation)expression.Annotation;

            ICallableMemberReference method;

            if (!annotation.IsIntraLinked)
            {
                method = annotation.Method;
            }
            else
            {
                method = context.ExportResolver.ResolveMethod(annotation.Function.EntrypointAddress);
                if (method == null)
                {
                    throw new RecompilerException(
                              $"Could not resolve function_{annotation.Function.EntrypointAddress:X4} to a physical method.");
                }
            }

            var result = new CilInstructionExpression(CilOpCodes.Ldftn, method)
            {
                ExpressionType = context.TargetImage.TypeSystem.IntPtr
            };

            return(result);
        }
Ejemplo n.º 6
0
        public CilExpression Translate(RecompilerContext context, ILVCallExpression expression)
        {
            var metadata = (TypeAnnotation)expression.Annotation;

            return(new CilInstructionExpression(CilOpCodes.Sizeof, metadata.Type)
            {
                ExpressionType = context.TargetModule.CorLibTypeFactory.Int32
            });
        }
Ejemplo n.º 7
0
        public CilExpression Translate(RecompilerContext context, ILVCallExpression expression)
        {
            var argument = (CilExpression)expression.Arguments.Last().AcceptVisitor(context.Recompiler);

            argument.ExpectedType = context.TargetModule.CorLibTypeFactory.UIntPtr;

            return(new CilInstructionExpression(CilOpCodes.Localloc, null, argument)
            {
                ExpressionType = new PointerTypeSignature(context.TargetModule.CorLibTypeFactory.Byte)
            });
        }
Ejemplo n.º 8
0
        public CilExpression Translate(RecompilerContext context, ILVCallExpression expression)
        {
            var annotation = (TokenAnnotation)expression.Annotation;

            var member = annotation.Member;

            string typeName;

            switch (member.MetadataToken.Table)
            {
            case TableIndex.TypeDef:
            case TableIndex.TypeRef:
            case TableIndex.TypeSpec:
                typeName = nameof(RuntimeTypeHandle);
                break;

            case TableIndex.Method:
            case TableIndex.MethodSpec:
                typeName = nameof(RuntimeMethodHandle);
                break;

            case TableIndex.Field:
                typeName = nameof(RuntimeFieldHandle);
                break;

            case TableIndex.MemberRef:
                var reference = (MemberReference)member;
                if (reference.Signature.IsMethod)
                {
                    typeName = nameof(RuntimeMethodHandle);
                }
                else if (reference.Signature.IsField)
                {
                    typeName = nameof(RuntimeFieldHandle);
                }
                else
                {
                    throw new RecompilerException("Detected a reference to a MemberRef that is not a method or a field.");
                }
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            return(new CilInstructionExpression(CilOpCodes.Ldtoken, annotation.Member)
            {
                ExpressionType = new TypeReference(
                    context.TargetModule,
                    context.TargetModule.CorLibTypeFactory.CorLibScope,
                    "System",
                    typeName)
            });
        }
Ejemplo n.º 9
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);
        }
Ejemplo n.º 10
0
        public CilExpression Translate(RecompilerContext context, ILInstructionExpression expression)
        {
            CilOpCode code;

            switch (expression.OpCode.Code)
            {
            case ILCode.SIND_PTR:
                code = CilOpCodes.Stind_I;
                break;

            case ILCode.SIND_BYTE:
                code = CilOpCodes.Stind_I1;
                break;

            case ILCode.SIND_WORD:
                code = CilOpCodes.Stind_I2;
                break;

            case ILCode.SIND_DWORD:
                code = CilOpCodes.Stind_I4;
                break;

            case ILCode.SIND_QWORD:
                code = CilOpCodes.Stind_I8;
                break;

            case ILCode.SIND_OBJECT:
                code = CilOpCodes.Stind_Ref;
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(expression));
            }

            var value       = (CilExpression)expression.Arguments[0].AcceptVisitor(context.Recompiler);
            var destination = (CilExpression)expression.Arguments[1].AcceptVisitor(context.Recompiler);

            switch (destination.ExpressionType)
            {
            case PointerTypeSignature pointerType:
                value.ExpectedType = pointerType.BaseType;
                break;

            case ByReferenceTypeSignature byRefType:
                value.ExpectedType = byRefType.BaseType;
                break;
            }


            return(new CilInstructionExpression(code, null, destination, value)
            {
                ExpressionType = null
            });
        }
Ejemplo n.º 11
0
        public virtual bool ApplyTransformation(RecompilerContext context, CilCompilationUnit unit)
        {
            bool changed = false;

            while (unit.AcceptVisitor(this))
            {
                changed = true;
                // Repeat until no more changes.
            }

            return(changed);
        }
Ejemplo n.º 12
0
        public CilExpression Translate(RecompilerContext context, ILVCallExpression expression)
        {
            var metadata = (CastAnnotation)expression.Annotation;

            var opCode = metadata.IsSafeCast ? CilOpCodes.Isinst : CilOpCodes.Castclass;
            var value  = (CilExpression)expression.Arguments[expression.Arguments.Count - 1]
                         .AcceptVisitor(context.Recompiler);

            return(new CilInstructionExpression(opCode, metadata.Type, value)
            {
                ExpressionType = metadata.Type
            });
        }
Ejemplo n.º 13
0
        public CilExpression Translate(RecompilerContext context, ILVCallExpression expression)
        {
            var annotation = (ThrowAnnotation)expression.Annotation;

            var argument = (CilExpression)expression.Arguments[2].AcceptVisitor(context.Recompiler);

            argument.ExpectedType = context.ReferenceImporter.ImportType(typeof(Exception));

            var result = new CilInstructionExpression(annotation.IsRethrow ? CilOpCodes.Rethrow :  CilOpCodes.Throw,
                                                      null,
                                                      argument);

            return(result);
        }
Ejemplo n.º 14
0
        public CilExpression Translate(RecompilerContext context, ILVCallExpression expression)
        {
            var annotation = (UnboxAnnotation)expression.Annotation;

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

            value.ExpectedType = context.TargetImage.TypeSystem.Object;

            return(new CilUnboxToVmExpression(annotation.Type, value)
            {
                ExpressionType = context.TargetImage.TypeSystem.Object
            });
        }
Ejemplo n.º 15
0
        public CilExpression Translate(RecompilerContext context, ILVCallExpression expression)
        {
            var annotation = (TokenAnnotation)expression.Annotation;

            var             member = annotation.Member;
            ITypeDescriptor expressionType;

            switch (member.MetadataToken.TokenType)
            {
            case MetadataTokenType.TypeDef:
            case MetadataTokenType.TypeRef:
            case MetadataTokenType.TypeSpec:
                expressionType = context.ReferenceImporter.ImportType(typeof(RuntimeTypeHandle));
                break;

            case MetadataTokenType.Method:
            case MetadataTokenType.MethodSpec:
                expressionType = context.ReferenceImporter.ImportType(typeof(RuntimeMethodHandle));
                break;

            case MetadataTokenType.Field:
                expressionType = context.ReferenceImporter.ImportType(typeof(RuntimeFieldHandle));
                break;

            case MetadataTokenType.MemberRef:
                var reference = (ICallableMemberReference)member;
                if (reference.Signature.IsMethod)
                {
                    expressionType = context.ReferenceImporter.ImportType(typeof(RuntimeMethodHandle));
                }
                else if (reference.Signature.IsField)
                {
                    expressionType = context.ReferenceImporter.ImportType(typeof(RuntimeFieldHandle));
                }
                else
                {
                    throw new RecompilerException("Detected a reference to a MemberRef that is not a method or a field.");
                }
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }


            return(new CilInstructionExpression(CilOpCodes.Ldtoken, annotation.Member)
            {
                ExpressionType = expressionType
            });
        }
Ejemplo n.º 16
0
        public virtual CilExpression Translate(RecompilerContext context, ILInstructionExpression expression)
        {
            if (!SupportedOpCodes.Contains(expression.OpCode.Code))
            {
                throw new NotSupportedException();
            }

            var result = new CilInstructionExpression();

            // Copy instructions
            foreach (var instruction in NewInstructions)
            {
                result.Instructions.Add(new CilInstruction(0, instruction.OpCode, instruction.Operand));
            }

            // Create arguments
            for (var i = 0; i < expression.Arguments.Count; i++)
            {
                // Convert argument.
                var argument    = expression.Arguments[i];
                var cilArgument = (CilExpression)argument.AcceptVisitor(context.Recompiler);

                // Check type.
                cilArgument.ExpectedType = expression.OpCode.StackBehaviourPop
                                           .GetArgumentType(i)
                                           .ToMetadataType(context.TargetImage);

                // Convert if necessary, and add to argument list.
                result.Arguments.Add(cilArgument);
            }

            // Determine expression type from opcode.
            if (expression.OpCode.StackBehaviourPush != ILStackBehaviour.None)
            {
                result.ExpressionType = expression.OpCode.StackBehaviourPush
                                        .GetResultType()
                                        .ToMetadataType(context.TargetImage);
            }

            result.ShouldEmitFlagsUpdate = expression.IsFlagDataSource;
            if (expression.IsFlagDataSource)
            {
                result.AffectedFlags       = expression.OpCode.AffectedFlags;
                result.InvertedFlagsUpdate = InvertedFlagsUpdate;
            }

            return(result);
        }
Ejemplo n.º 17
0
        public CilExpression Translate(RecompilerContext context, ILVCallExpression expression)
        {
            var annotation = (TypeAnnotation)expression.Annotation;

            var argument = (CilExpression)expression.Arguments[expression.Arguments.Count - 1]
                           .AcceptVisitor(context.Recompiler);

            argument.ExpectedType = new ByReferenceTypeSignature(
                context.ReferenceImporter.ImportTypeSignature(annotation.Type.ToTypeSignature()));

            var result = new CilInstructionExpression(CilOpCodes.Initobj, annotation.Type, argument)
            {
                ExpressionType = null
            };

            return(result);
        }
Ejemplo n.º 18
0
        /// <inheritdoc />
        public CilExpression Translate(RecompilerContext context, ILVCallExpression expression)
        {
            // CKOVERFLOW is currently not supported. This is in most cases not a big issue as the extra properties of
            // the overflow checked instructions are not really used all that often in real world applications.
            // We therefore just emit a NOP for now.

            var method = context.MethodBody.Owner;

            string displayName = method.MetadataToken != 0
                ? method.MetadataToken.ToInt32().ToString("X8")
                : method.Name;

            context.Logger.Warning(Tag,
                                   $"Virtualized method {displayName} contains overflow checks which are not supported by OldRod. Resulting code might be inaccurate.");

            return(new CilInstructionExpression(CilOpCodes.Nop));
        }
Ejemplo n.º 19
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);
        }
Ejemplo n.º 20
0
        public CilExpression Translate(RecompilerContext context, ILInstructionExpression expression)
        {
            var callMetadata = (CallAnnotation)expression.Annotation;

            // Convert entrypoint address to physical method def.
            var method    = context.ExportResolver.ResolveMethod(callMetadata.Function.EntrypointAddress);
            var methodSig = ((MethodSignature)method.Signature);

            // Create call instruction.
            CilExpression result = new CilInstructionExpression(CilOpCodes.Call, method,
                                                                context.RecompileCallArguments(method, expression.Arguments.Skip(1).ToArray(), VMECallOpCode.CALL))
            {
                ExpressionType = methodSig.ReturnType
            };

            // Make sure the resulting object is converted to an unsigned integer if necessary.
            return(result);
        }
 public override bool ApplyTransformation(RecompilerContext context, CilCompilationUnit unit)
 {
     _context = context;
     return(base.ApplyTransformation(context, unit));
 }
        public CilExpression Translate(RecompilerContext context, ILInstructionExpression expression)
        {
            var arguments = expression.Arguments
                            .Select(a => (CilExpression)a.AcceptVisitor(context.Recompiler))
                            .ToArray();

            CilOpCode opCode;

            switch (expression.OpCode.Code)
            {
            case ILCode.__EQUALS_OBJECT:
                opCode = CilOpCodes.Ceq;
                break;

            case ILCode.__EQUALS_R32:
            case ILCode.__EQUALS_R64:
            case ILCode.__EQUALS_DWORD:
            case ILCode.__EQUALS_QWORD:
                opCode = CilOpCodes.Ceq;
                break;

            case ILCode.__GT_R32:
            case ILCode.__GT_R64:
                opCode = CilOpCodes.Cgt;
                break;

            case ILCode.__GT_DWORD:
            case ILCode.__GT_QWORD:
                opCode = CilOpCodes.Cgt_Un;
                break;

            case ILCode.__LT_R32:
            case ILCode.__LT_R64:
                opCode = CilOpCodes.Clt;
                break;

            case ILCode.__LT_DWORD:
            case ILCode.__LT_QWORD:
                opCode = CilOpCodes.Clt_Un;
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(expression));
            }

            var argumentType = expression.OpCode.StackBehaviourPop.GetArgumentType(0)
                               .ToMetadataType(context.TargetModule)
                               .ToTypeSignature();

            var result = new CilInstructionExpression(opCode)
            {
                ExpressionType = context.TargetModule.CorLibTypeFactory.Boolean
            };

            foreach (var argument in arguments)
            {
                argument.ExpectedType = argumentType;
                result.Arguments.Add(argument);
            }

            return(result);
        }
Ejemplo n.º 23
0
        private static CilExpression CompileRegisterPush(RecompilerContext context, ILInstructionExpression expression)
        {
            var cilExpression = (CilExpression)expression.Arguments[0].AcceptVisitor(context.Recompiler);

            var resultType = expression.OpCode.StackBehaviourPush.GetResultType();

            if (cilExpression is CilUnboxToVmExpression)
            {
                // HACK: Unbox expressions unbox the value from the stack, but also convert it to their unsigned
                //       variant and box it again into an object. We need to unpack it again, however, we do not
                //       know the actual type of the value inside the box, as this is determined at runtime.
                //
                //       For now, we just make use of the Convert class provided by .NET, which works but would rather
                //       see a true "native" CIL conversion instead.

                MethodBase convertMethod;
                switch (resultType)
                {
                case VMType.Byte:
                    convertMethod = typeof(Convert).GetMethod("ToByte", new[] { typeof(object) });
                    break;

                case VMType.Word:
                    convertMethod = typeof(Convert).GetMethod("ToUInt16", new[] { typeof(object) });
                    break;

                case VMType.Dword:
                    convertMethod = typeof(Convert).GetMethod("ToUInt32", new[] { typeof(object) });
                    break;

                case VMType.Qword:
                    convertMethod = typeof(Convert).GetMethod("ToUInt64", new[] { typeof(object) });
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                cilExpression.ExpectedType = context.TargetImage.TypeSystem.Object;
                cilExpression = new CilInstructionExpression(
                    CilOpCodes.Call,
                    context.ReferenceImporter.ImportMethod(convertMethod),
                    cilExpression);
            }

            if (resultType == VMType.Object)
            {
                if (cilExpression.ExpressionType.IsValueType)
                {
                    if (cilExpression is CilInstructionExpression instructionExpression &&
                        instructionExpression.Instructions.Count == 1 &&
                        instructionExpression.Instructions[0].IsLdcI4 &&
                        instructionExpression.Instructions[0].GetLdcValue() == 0)
                    {
                        cilExpression = new CilInstructionExpression(CilOpCodes.Ldnull);
                    }
                    else
                    {
                        // If expression returns a value type, we have to box it to an object.
                        cilExpression = new CilInstructionExpression(CilOpCodes.Box,
                                                                     context.ReferenceImporter.ImportType(cilExpression.ExpressionType.ToTypeDefOrRef()),
                                                                     cilExpression);
                    }
                }
                else
                {
                    // Use the reference type of the expression instead of System.Object.
                    cilExpression.ExpressionType = cilExpression.ExpressionType;
                }
            }
Ejemplo n.º 24
0
 public void ApplyTransformation(RecompilerContext context, CilCompilationUnit unit)
 {
     _context = context;
     VisitCompilationUnit(unit);
 }
Ejemplo n.º 25
0
 public CilExpression Translate(RecompilerContext context, ILInstructionExpression expression)
 {
     return(new CilInstructionExpression(CilOpCodes.Nop));
 }
Ejemplo n.º 26
0
        public CilExpression Translate(RecompilerContext context, ILVCallExpression expression)
        {
            var ecall     = (ECallAnnotation)expression.Annotation;
            var methodSig = ecall.Method.Signature;

            // Select calling instruction, return type and call prefix.
            CilInstruction prefix = null;
            TypeSignature  resultType;
            CilOpCode      opcode;
            object         operand = ecall.Method;

            switch (ecall.OpCode)
            {
            case VMECallOpCode.CALL:
                opcode     = CilOpCodes.Call;
                resultType = methodSig.ReturnType;
                break;

            case VMECallOpCode.CALLVIRT:
                opcode     = CilOpCodes.Callvirt;
                resultType = methodSig.ReturnType;
                break;

            case VMECallOpCode.NEWOBJ:
                opcode     = CilOpCodes.Newobj;
                resultType = ecall.Method.DeclaringType.ToTypeSignature();

                // KoiVM translates "newarr ElementType" instructions to "newobj ElementType[]::.ctor(int32)".
                // Revert this operation if necessary:
                if (resultType is SzArrayTypeSignature arrayType)
                {
                    opcode  = CilOpCodes.Newarr;
                    operand = context.ReferenceImporter.ImportType(arrayType.BaseType.ToTypeDefOrRef());
                }

                break;

            case VMECallOpCode.CALLVIRT_CONSTRAINED:
                prefix     = new CilInstruction(CilOpCodes.Constrained, ecall.ConstrainedType);
                opcode     = CilOpCodes.Callvirt;
                resultType = methodSig.ReturnType;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            // Enter generic context of method.
            context.EnterMember(ecall.Method);

            // Collect arguments.
            var arguments = expression.Arguments
                            .Skip(ecall.IsConstrained ? 3 : 2)
                            .ToArray();

            // Build call expression.
            var result = new CilInstructionExpression(opcode, operand,
                                                      context.RecompileCallArguments(ecall.Method, arguments, ecall.OpCode, ecall.ConstrainedType))
            {
                ExpressionType = resultType.InstantiateGenericTypes(context.GenericContext)
            };

            // Add prefix when necessary.
            if (prefix != null)
            {
                result.Instructions.Insert(0, prefix);
            }

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

            return(result);
        }
Ejemplo n.º 27
0
        public CilExpression Translate(RecompilerContext context, ILVCallExpression expression)
        {
            var ecall     = (ECallAnnotation)expression.Annotation;
            var methodSig = (MethodSignature)ecall.Method.Signature;

            // Select calling instruction, return type and call prefix.
            CilInstruction prefix = null;
            TypeSignature  resultType;
            CilOpCode      opcode;

            switch (ecall.OpCode)
            {
            case VMECallOpCode.CALL:
                opcode     = CilOpCodes.Call;
                resultType = methodSig.ReturnType;
                break;

            case VMECallOpCode.CALLVIRT:
                opcode     = CilOpCodes.Callvirt;
                resultType = methodSig.ReturnType;
                break;

            case VMECallOpCode.NEWOBJ:
                opcode     = CilOpCodes.Newobj;
                resultType = ecall.Method.DeclaringType.ToTypeSignature();
                break;

            case VMECallOpCode.CALLVIRT_CONSTRAINED:
                prefix     = CilInstruction.Create(CilOpCodes.Constrained, ecall.ConstrainedType);
                opcode     = CilOpCodes.Callvirt;
                resultType = methodSig.ReturnType;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            // Enter generic context of method.
            context.EnterMember(ecall.Method);

            // Collect arguments.
            var arguments = expression.Arguments
                            .Skip(ecall.IsConstrained ? 3 : 2)
                            .ToArray();

            // Build call expression.
            var result = new CilInstructionExpression(opcode, ecall.Method,
                                                      context.RecompileCallArguments(ecall.Method, arguments, ecall.OpCode == VMECallOpCode.NEWOBJ))
            {
                ExpressionType = resultType.InstantiateGenericTypes(context.GenericContext)
            };

            // Add prefix when necessary.
            if (prefix != null)
            {
                result.Arguments[0].ExpectedType = ecall.ConstrainedType;
                result.Instructions.Insert(0, prefix);
            }

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

            return(result);
        }
Ejemplo n.º 28
0
 public override bool ApplyTransformation(RecompilerContext context, CilCompilationUnit unit)
 {
     _context = context;
     _helper  = new TypeHelper(context.ReferenceImporter);
     return(base.ApplyTransformation(context, unit));
 }
Ejemplo n.º 29
0
 void ICilAstTransform.ApplyTransformation(RecompilerContext context, CilCompilationUnit unit)
 {
     ApplyTransformation(context, unit);
 }