예제 #1
0
 public void Import(Instruction instruction, ImportContext context, IILImporterProxy importer)
 {
     importer.PushExpression(new StringConstantEntry(instruction.OperandAs <string>()));
 }
예제 #2
0
 public void Import(Instruction instruction, ImportContext context, IILImporterProxy importer)
 {
     // Nothing to do
 }
예제 #3
0
        public static void ImportCall(Instruction instruction, ImportContext context, IILImporterProxy importer, StackEntry?newObjThis = null)
        {
            var methodDefOrRef = instruction.Operand as IMethodDefOrRef;
            var methodToCall   = methodDefOrRef.ResolveMethodDefThrow();

            var arguments     = new List <StackEntry>();
            var firstArgIndex = newObjThis != null ? 1 : 0;

            for (var i = firstArgIndex; i < methodToCall.Parameters.Count; i++)
            {
                var argument = importer.PopExpression();
                arguments.Add(argument);
            }
            // Add the this pointer if required, e.g. if part of newobj
            if (newObjThis != null)
            {
                arguments.Add(newObjThis);
            }
            arguments.Reverse();

            // Intrinsic calls
            if (methodToCall.IsIntrinsic())
            {
                if (!ImportIntrinsicCall(methodToCall, arguments, importer))
                {
                    throw new NotSupportedException("Unknown intrinsic");
                }
                return;
            }

            string targetMethod;

            if (methodToCall.IsPinvokeImpl)
            {
                targetMethod = methodToCall.ImplMap.Name;
            }
            else
            {
                targetMethod = context.NameMangler.GetMangledMethodName(methodToCall);
            }

            int returnBufferArgIndex = 0;
            var returnType           = methodToCall.ReturnType;

            if (methodToCall.HasReturnType)
            {
                if (returnType.IsStruct())
                {
                    returnBufferArgIndex = FixupCallStructReturn(returnType, arguments, importer, methodToCall.HasThis);
                }
            }

            int?returnTypeSize = methodToCall.HasReturnType ? returnType.GetExactSize() : null;

            var callNode = new CallEntry(targetMethod, arguments, returnType.GetStackValueKind(), returnTypeSize);

            if (!methodToCall.HasReturnType)
            {
                importer.ImportAppendTree(callNode);
            }
            else
            {
                if (returnType.IsStruct())
                {
                    importer.ImportAppendTree(callNode);

                    // Load return buffer to stack
                    var loadTemp = new LocalVariableEntry(returnBufferArgIndex, returnType.GetStackValueKind(), returnType.GetExactSize());
                    importer.PushExpression(loadTemp);
                }
                else
                {
                    importer.PushExpression(callNode);
                }
            }
        }
예제 #4
0
 public void Import(Instruction instruction, ImportContext context, IILImporterProxy importer)
 {
     ImportCall(instruction, context, importer);
 }
예제 #5
0
        public void Import(Instruction instruction, ImportContext context, IILImporterProxy importer)
        {
            var code = instruction.OpCode.Code;

            switch (code)
            {
            case Code.Br_S:
            case Code.Blt_S:
            case Code.Bgt_S:
            case Code.Ble_S:
            case Code.Bge_S:
            case Code.Beq_S:
            case Code.Bne_Un_S:
            case Code.Brfalse_S:
            case Code.Brtrue_S:
                code += (Code.Br - Code.Br_S);
                break;
            }
            var target = instruction.OperandAs <Instruction>();

            var targetBlock      = importer.BasicBlocks[(int)target.Offset];
            var fallthroughBlock = (code != Code.Br) ? context.FallThroughBlock : null;

            if (code != Code.Br)
            {
                var op2 = importer.PopExpression();
                if (op2.Kind != StackValueKind.Int32 && op2.Kind != StackValueKind.NativeInt)
                {
                    throw new NotSupportedException("Boolean comparisons only supported using int and nativeint as underlying type");
                }

                StackEntry op1;
                Operation  op;
                if (code != Code.Brfalse && code != Code.Brtrue)
                {
                    op1 = importer.PopExpression();
                    op  = Operation.Eq + (code - Code.Beq);

                    // If one of the values is a native int then cast the other to be native int too
                    if (op1.Kind == StackValueKind.NativeInt && op2.Kind == StackValueKind.Int32)
                    {
                        op2 = new CastEntry(Common.TypeSystem.WellKnownType.Object, op2, op1.Kind);
                    }
                    else if (op1.Kind == StackValueKind.Int32 && op2.Kind == StackValueKind.NativeInt)
                    {
                        op1 = new CastEntry(Common.TypeSystem.WellKnownType.Object, op1, op2.Kind);
                    }
                }
                else
                {
                    op1 = new Int32ConstantEntry(0);
                    op  = (code == Code.Brfalse) ? Operation.Eq : Operation.Ne;
                }
                op1 = new BinaryOperator(op, isComparison: true, op1, op2, op1.Kind);
                importer.ImportAppendTree(new JumpTrueEntry(targetBlock.Label, op1));
            }
            else
            {
                importer.ImportAppendTree(new JumpEntry(targetBlock.Label));
            }

            // Fall through handling
            importer.ImportFallThrough(targetBlock);

            if (fallthroughBlock != null)
            {
                importer.ImportFallThrough(fallthroughBlock);
            }

            context.StopImporting = true;
        }
예제 #6
0
        public void Import(Instruction instruction, ImportContext context, IILImporterProxy importer)
        {
            var unaryOp = Operation.Neg + (instruction.OpCode.Code - Code.Neg);

            importer.PushExpression(new UnaryOperator(unaryOp, importer.PopExpression()));
        }