Exemple #1
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);
        }
Exemple #2
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);
        }
Exemple #3
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);
        }