Beispiel #1
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
            });
        }
Beispiel #2
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
            });
        }
Beispiel #3
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);
        }
Beispiel #4
0
        public CilExpression Translate(RecompilerContext context, ILVCallExpression expression)
        {
            var metadata = (FieldAnnotation)expression.Annotation;

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

            var field = (FieldDefinition)metadata.Field.Resolve();

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

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

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

            if (!field.IsStatic)
            {
                // 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);

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

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

            return(result);
        }
Beispiel #5
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);
        }
Beispiel #6
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));
        }
        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);
        }
Beispiel #8
0
 public string VisitVCallExpression(ILVCallExpression expression) => expression.Annotation.ToString();
Beispiel #9
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);
        }
        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);
        }
Beispiel #11
0
 public virtual bool VisitVCallExpression(ILVCallExpression expression)
 {
     return(TryOptimiseArguments(expression));
 }