Beispiel #1
0
        internal void AddSecurityTransparencyAttribute(List <ICustomAttribute> list, SecurityTransparencyStatus securityTransparencyStatus, ITypeReference containingType)
        {
            Microsoft.Cci.MethodReference ctor = null;
            switch (securityTransparencyStatus)
            {
            case SecurityTransparencyStatus.Critical:
                ctor = new Microsoft.Cci.MethodReference(this.host, containingType.PlatformType.SystemSecuritySecurityCriticalAttribute,    //FindType("System.Security.SecurityCriticalAttribute"),
                                                         CallingConvention.HasThis, this.host.PlatformType.SystemVoid, this.host.NameTable.Ctor, 0);
                break;

            case SecurityTransparencyStatus.SafeCritical:
                ctor = new Microsoft.Cci.MethodReference(this.host, containingType.PlatformType.SystemSecuritySecuritySafeCriticalAttribute,    //FindType("System.Security.SecuritySafeCriticalAttribute"),
                                                         CallingConvention.HasThis, this.host.PlatformType.SystemVoid, this.host.NameTable.Ctor, 0);
                break;

            case SecurityTransparencyStatus.Transparent:
                break;
            }

            if (ctor != null)
            {
                CustomAttribute securityAttribute = new CustomAttribute();
                securityAttribute.Constructor = ctor;
                list.Add(Rewrite(securityAttribute));
            }
        }
Beispiel #2
0
        private void AddFaaAttributeIfNeeded(Element element, List <ICustomAttribute> attributes, ITypeReference containingType)
        {
            if (element != null && element.IsFriendAccessAllowed)//typeHasFaaAttribute(attributes, containingType))
            {
                List <INamedTypeDefinition> types = new List <INamedTypeDefinition>(this.host.FindAssembly(this.host.CoreAssemblySymbolicIdentity).GetAllTypes());

                if (types == null || !types.Any())
                {
                    return; //Couldn't find any type on the assembly
                }
                IEnumerable <INamedTypeDefinition> faaAttributeType = types.Where(t => t.Name.Value == "FriendAccessAllowedAttribute");
                if (!faaAttributeType.Any())
                {
                    return; //Unable to find the FriendAccessAllowedAttribute
                }
                var faaAttributeResult = faaAttributeType.FirstOrDefault();
                if (!Util.HasAttribute(attributes, faaAttributeResult))
                {
                    Microsoft.Cci.MethodReference faaCtor = new Microsoft.Cci.MethodReference(this.host, faaAttributeResult,
                                                                                              CallingConvention.HasThis, this.host.PlatformType.SystemVoid, this.host.NameTable.Ctor, 0);
                    CustomAttribute faaAttribute = new CustomAttribute();
                    faaAttribute.Constructor = faaCtor;
                    attributes.Add(Rewrite(faaAttribute));
                }
            }
        }
    protected void AppendEmitExceptionThrow(ILGenerator generator) {
      var systemExceptionTypeReference = GarbageCollectHelper.CreateTypeReference(host, coreAssemblyReference, "System.Exception");

      IMethodReference exceptionConstructor = new Microsoft.Cci.MethodReference(
        host,
        systemExceptionTypeReference,
        CallingConvention.HasThis,
        host.PlatformType.SystemVoid,
        host.NameTable.Ctor,
        0);

      generator.Emit(OperationCode.Newobj, exceptionConstructor);
      generator.Emit(OperationCode.Throw);
    }
Beispiel #4
0
        protected void AppendEmitExceptionThrow(ILGenerator generator)
        {
            var systemExceptionTypeReference = GarbageCollectHelper.CreateTypeReference(host, coreAssemblyReference, "System.Exception");

            IMethodReference exceptionConstructor = new Microsoft.Cci.MethodReference(
                host,
                systemExceptionTypeReference,
                CallingConvention.HasThis,
                host.PlatformType.SystemVoid,
                host.NameTable.Ctor,
                0);

            generator.Emit(OperationCode.Newobj, exceptionConstructor);
            generator.Emit(OperationCode.Throw);
        }
Beispiel #5
0
        private NamespaceTypeDefinition CreateContractClass(UnitNamespace unitNamespace)
        {
            var contractTypeName      = this.host.NameTable.GetNameFor("Contract");
            var contractNamespaceName = this.host.NameTable.GetNameFor("System.Diagnostics.Contracts");

            Microsoft.Cci.MethodReference compilerGeneratedCtor =
                new Microsoft.Cci.MethodReference(
                    this.host,
                    this.compilerGeneratedAttributeType,
                    CallingConvention.HasThis,
                    this.systemVoidType,
                    this.host.NameTable.Ctor,
                    0);
            CustomAttribute compilerGeneratedAttribute = new CustomAttribute();

            compilerGeneratedAttribute.Constructor = compilerGeneratedCtor;

            var contractsNs = new NestedUnitNamespace()
            {
                ContainingUnitNamespace = unitNamespace,
                Name = contractNamespaceName,
            };
            NamespaceTypeDefinition result = new NamespaceTypeDefinition()
            {
                // NB: The string name must be kept in sync with the code that recognizes contract
                // methods!!
                Name       = contractTypeName,
                Attributes = new List <ICustomAttribute> {
                    compilerGeneratedAttribute
                },
                BaseClasses = new List <ITypeReference> {
                    this.systemObjectType
                },
                ContainingUnitNamespace = contractsNs,
                InternFactory           = this.host.InternFactory,
                IsBeforeFieldInit       = true,
                IsClass      = true,
                IsSealed     = true,
                Layout       = LayoutKind.Auto,
                StringFormat = StringFormatKind.Ansi,
            };

            return(result);
        }
        private void AddInterceptionTargets()
        {
            host.LoadUnit(host.CoreAssemblySymbolicIdentity);

            foreach (var method in registry.GetRegisteredReferences(ReplaceableReferenceTypes.Method))
            {
                var methodInfo = method as ReplaceableMethodInfo;

                var fullNamespace = methodInfo.DeclaringType.Namespace;
                var fullNamespaceWithType = methodInfo.DeclaringType.FullName;

                log.WriteTrace("Adding interception target for '{0}'.", fullNamespaceWithType);

                fakeNamespace.AddNamespaces(fullNamespace);
                fakeNamespace.AddClass(fullNamespace, methodInfo.DeclaringType.Name);

                var reflector = new UnitReflector(host);
                var methodType = reflector.Get(methodInfo.ReturnType.FullName);

                var actualMethod = methodInfo.Name == ".ctor" ?
                    reflector.From(fullNamespaceWithType).GetConstructor(methodInfo.Parameters.Select(p => reflector.Get(p.ParameterType.FullName)).ToArray()) :
                    reflector.From(fullNamespaceWithType).GetMethod(methodInfo.Name, methodInfo.Parameters.Select(p => reflector.Get(p.ParameterType.FullName)).ToArray());

                var methodClass = fakeNamespace.Classes[fullNamespaceWithType];
                var methodName = methodInfo.Name == ".ctor" ? "<constructor>" : methodInfo.Name;
                var fakeMethod = methodClass.AddPublicStaticMethod(methodName, methodType, host);

                // if it's an instance method, we add a parameter at the end for the target
                ushort extraParameters = 0;
                if (!actualMethod.ResolvedMethod.IsStatic && !actualMethod.ResolvedMethod.IsConstructor)
                {
                    fakeMethod.AddParameter(0, "target", actualMethod.ContainingType, host, false, false);
                    extraParameters = 1;
                }

                foreach (var parameter in actualMethod.Parameters)
                {
                    fakeMethod.AddParameter((ushort)(parameter.Index + extraParameters),
                        "p" + parameter.Index, parameter.Type, host, parameter.IsByReference/*IsOut*/, parameter.IsByReference);
                }

                if (actualMethod.ResolvedMethod.IsConstructor)
                {
                    fakeMethod.Type = actualMethod.ResolvedMethod.ContainingTypeDefinition;
                }

                var customAttribute = new CustomAttribute();
                customAttribute.Constructor = new UnitReflector(host)
                    .From<SharpMockGeneratedAttribute>().GetConstructor(Type.EmptyTypes);
                fakeMethod.Attributes = new List<ICustomAttribute>();
                fakeMethod.Attributes.Add(customAttribute);
                fakeMethod.Body = GetBody(fakeMethod, actualMethod);

                var parameterTypes = new List<ITypeDefinition>();
                foreach (var param in fakeMethod.Parameters)
                {
                    parameterTypes.Add(param.Type.ResolvedType);
                }

                var fakeCallReference = new Microsoft.Cci.MethodReference(host, fakeMethod.ContainingTypeDefinition,
                    fakeMethod.CallingConvention, fakeMethod.Type, fakeMethod.Name, 0, parameterTypes.ToArray());

                registry.RegisterReplacement(method, fakeCallReference);
            }

            foreach (var field in registry.GetRegisteredReferences(ReplaceableReferenceTypes.FieldAccessor))
            {
                var fieldReplacementBuilder = new FieldAccessorSourceWriter(fakeNamespace, host, log, field as ReplaceableFieldInfo);
                var fakeCallReference = fieldReplacementBuilder.GetReference();

                registry.RegisterReplacement(field, fakeCallReference);
            }

            foreach (var field in registry.GetRegisteredReferences(ReplaceableReferenceTypes.FieldAssignment))
            {
                var fieldReplacementBuilder = new FieldAssignmentSourceWriter(fakeNamespace, host, log, field as ReplaceableFieldInfo);
                var fakeCallReference = fieldReplacementBuilder.GetReference();

                registry.RegisterReplacement(field, fakeCallReference);
            }
        }
        private IMethodDefinition GetOrCreateFinalizer(ITypeDefinition type)
        {
            Contract.Requires(type != null);
            Contract.Requires(type != Dummy.Type);
            Contract.Ensures(Contract.Result <IMethodDefinition>() != null);
            Contract.Ensures(Contract.Result <IMethodDefinition>() != Dummy.Method);

            var finalizer = TypeHelper.GetMethod(type, base.host.NameTable.GetNameFor("Finalize"));

            if (finalizer == Dummy.Method)
            {
                // create a method:  virtual void Finalize()
                finalizer = new MethodDefinition()
                {
                    IsVirtual                = true,
                    CallingConvention        = CallingConvention.HasThis,
                    ContainingTypeDefinition = type,
                    InternFactory            = host.InternFactory,
                    IsCil      = true,
                    IsStatic   = false,
                    Name       = base.host.NameTable.GetNameFor("Finalize"),
                    Type       = host.PlatformType.SystemVoid,
                    Visibility = TypeMemberVisibility.Family,
                };

                // create a list of operations that holds (i) call to baseclass finalize if there is one and (ii) a return statement.
                var ops = new List <IOperation>();

                // call base class Finalize method
                var baseClass         = GetBaseClass(type);
                var baseClassFinalize = new Microsoft.Cci.MethodReference(
                    base.host,
                    baseClass,
                    CallingConvention.HasThis,
                    base.host.PlatformType.SystemVoid,
                    base.host.NameTable.GetNameFor("Finalize"),
                    0
                    );

                ops.Add(new Operation()
                {
                    Location      = Dummy.Location,
                    Offset        = 0,
                    OperationCode = OperationCode.Ldarg_0,
                    Value         = null
                });

                ops.Add(new Operation()
                {
                    Location      = Dummy.Location,
                    Offset        = 0,
                    OperationCode = OperationCode.Call,
                    Value         = baseClassFinalize
                });

                ops.Add(new Operation()
                {
                    Location      = Dummy.Location,
                    Offset        = 0,
                    OperationCode = OperationCode.Ret,
                    Value         = null
                });

                // create a method body with that single operation and no exception information
                var body = new MethodBody {
                    LocalsAreZeroed  = false,
                    LocalVariables   = null,
                    MaxStack         = 0,
                    MethodDefinition = finalizer,
                    OperationExceptionInformation = new List <IOperationExceptionInformation>(0),
                    Operations         = ops,
                    PrivateHelperTypes = null
                };

                // update the method definition and the body to point to each other.
                body.MethodDefinition = finalizer;
                ((MethodDefinition)finalizer).Body = body;

                // add it to this typeDefinition
                var containingType = type as NamedTypeDefinition;
                if (containingType != null)
                {
                    if (containingType.Methods == null)
                    {
                        containingType.Methods = new List <IMethodDefinition>();
                    }
                    containingType.Methods.Add(finalizer);
                }
                else
                {
                    var nestedContainingType = type as NestedTypeDefinition;
                    if (nestedContainingType != null)
                    {
                        if (nestedContainingType.Methods == null)
                        {
                            nestedContainingType.Methods = new List <IMethodDefinition>();
                        }
                        nestedContainingType.Methods.Add(finalizer);
                    }
                    else
                    {
                        var specializedContainingType = type as SpecializedNestedTypeDefinition;
                        if (specializedContainingType != null)
                        {
                            if (specializedContainingType.Methods == null)
                            {
                                specializedContainingType.Methods = new List <IMethodDefinition>();
                            }
                            specializedContainingType.Methods.Add(finalizer);
                        }
                        else
                        {
                            Contract.Assert(false);
                        }
                    }
                }
            }
            return(finalizer);
        }
Beispiel #8
0
        public void Compile(string fileName)
        {
            string appName = Path.GetFileNameWithoutExtension(fileName);
            string exeName = appName + ".exe";
            string src = "";
            using (TextReader file = new StreamReader(fileName))
            {
                src = file.ReadToEnd();
            }

            var nameTable = new NameTable();
            using (var host = new PeReader.DefaultHost(nameTable))
            {
                // Load Mirage types

                IModule module = host.LoadUnitFrom("Mirage.dll") as IModule;
                if (module == null || module is Dummy)
                {
                    return;
                }
                var machineType = module.GetAllTypes().First(x => x.Name.Value == "Machine");
                var inputType = module.GetAllTypes().First(x => x.Name.Value == "ConsoleInput");
                var outputType = module.GetAllTypes().First(x => x.Name.Value == "ConsoleOutput");

                // Create assembly

                var coreAssembly = host.LoadAssembly(host.CoreAssemblySymbolicIdentity);
                var assembly = new Assembly()
                {
                    Name = nameTable.GetNameFor(appName),
                    ModuleName = nameTable.GetNameFor(exeName),
                    PlatformType = host.PlatformType,
                    Kind = ModuleKind.ConsoleApplication,
                    RequiresStartupStub = host.PointerSize == 4,
                    TargetRuntimeVersion = coreAssembly.TargetRuntimeVersion,
                };
                assembly.AssemblyReferences.Add(coreAssembly);

                // Create namespace

                var rootUnitNamespace = new RootUnitNamespace();
                assembly.UnitNamespaceRoot = rootUnitNamespace;
                rootUnitNamespace.Unit = assembly;

                // Create module class

                var moduleClass = new NamespaceTypeDefinition()
                {
                    ContainingUnitNamespace = rootUnitNamespace,
                    InternFactory = host.InternFactory,
                    IsClass = true,
                    Name = nameTable.GetNameFor("<Module>"),
                };
                assembly.AllTypes.Add(moduleClass);

                // Create program class

                var programClass = new NamespaceTypeDefinition()
                {
                    ContainingUnitNamespace = rootUnitNamespace,
                    InternFactory = host.InternFactory,
                    IsClass = true,
                    IsPublic = true,
                    Methods = new List<IMethodDefinition>(1),
                    Name = nameTable.GetNameFor("Program"),
                };
                programClass.BaseClasses = new List<ITypeReference>() { host.PlatformType.SystemObject };
                rootUnitNamespace.Members.Add(programClass);

                // Add types to the assembly

                assembly.AllTypes.Add(machineType);
                foreach (var t in machineType.NestedTypes)
                {
                    assembly.AllTypes.Add(t);
                }
                assembly.AllTypes.Add(inputType);
                assembly.AllTypes.Add(outputType);
                assembly.AllTypes.Add(programClass);

                // Create main method

                var mainMethod = new MethodDefinition()
                {
                    ContainingTypeDefinition = programClass,
                    InternFactory = host.InternFactory,
                    IsCil = true,
                    IsStatic = true,
                    Name = nameTable.GetNameFor("Main"),
                    Type = host.PlatformType.SystemVoid,
                    Visibility = TypeMemberVisibility.Public,
                };
                assembly.EntryPoint = mainMethod;
                programClass.Methods.Add(mainMethod);

                // Create constructors and methods

                IMethodReference machineConstructor = new Microsoft.Cci.MethodReference(
                    host,
                    machineType,
                    CallingConvention.HasThis,
                    host.PlatformType.SystemVoid,
                    host.NameTable.Ctor,
                    0
                );

                IMethodReference inputConstructor = new Microsoft.Cci.MethodReference(
                    host,
                    inputType,
                    CallingConvention.HasThis,
                    host.PlatformType.SystemVoid,
                    host.NameTable.Ctor,
                    0
                );
                var inputCast = TypeHelper.GetMethod(inputType, nameTable.GetNameFor("op_Implicit"), inputType);

                IMethodReference outputConstructor = new Microsoft.Cci.MethodReference(
                    host,
                    outputType,
                    CallingConvention.HasThis,
                    host.PlatformType.SystemVoid,
                    host.NameTable.Ctor,
                    0
                );
                var outputCast = TypeHelper.GetMethod(outputType, nameTable.GetNameFor("op_Implicit"), outputType);

                var opIncPointers = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("IncPointers"));
                var opDecPointers = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("DecPointers"));
                var opIncHiPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("IncHiPointer"));
                var opDecHiPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("DecHiPointer"));
                var opReflectHiPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("ReflectHiPointer"));
                var opLoadHiPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("LoadHiPointer"));
                var opDragLoPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("DragLoPointer"));
                var opXchPointers = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("XchPointers"));

                var opClear = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Clear"));
                var opAdd = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Add"));
                var opDec = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Dec"));
                var opNot = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Not"));
                var opAnd = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("And"));
                var opOr = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Or"));
                var opXor = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Xor"));
                var opSal = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Sal"));
                var opSar = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Sar"));

                var opLoadData = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("LoadData"), host.PlatformType.SystemString);
                var opInput = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Input"), inputCast.Type);
                var opOutput = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Output"), outputCast.Type);

                var opJz = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Jz"));

                // Create program code

                var labels = new Stack<ILGeneratorLabel>(100);

                var ilGenerator = new ILGenerator(host, mainMethod);
                ilGenerator.Emit(OperationCode.Newobj, machineConstructor);
                ilGenerator.Emit(OperationCode.Stloc_0);
                ilGenerator.Emit(OperationCode.Newobj, inputConstructor);
                ilGenerator.Emit(OperationCode.Stloc_1);
                ilGenerator.Emit(OperationCode.Newobj, outputConstructor);
                ilGenerator.Emit(OperationCode.Stloc_2);

                int pc = 0;
                while (pc < src.Length)
                {
                    char opcode = src[pc++];

                    switch (opcode)
                    {
                        case '>':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opIncPointers);
                            break;
                        case '<':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opDecPointers);
                            break;
                        case ']':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opIncHiPointer);
                            break;
                        case '[':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opDecHiPointer);
                            break;
                        case '#':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opReflectHiPointer);
                            break;
                        case '$':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opLoadHiPointer);
                            break;
                        case '=':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opDragLoPointer);
                            break;
                        case '%':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opXchPointers);
                            break;
                        case '_':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opClear);
                            break;
                        case '+':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opAdd);
                            break;
                        case '-':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opDec);
                            break;
                        case '~':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opNot);
                            break;
                        case '&':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opAnd);
                            break;
                        case '|':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opOr);
                            break;
                        case '^':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opXor);
                            break;
                        case '*':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opSal);
                            break;
                        case '/':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opSar);
                            break;
                        case '(':
                            int dataStart = pc;
                            int dataEnd = dataStart;
                            while (src[pc++] != ')')
                            {
                                dataEnd = pc;
                            }
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Ldstr, src.Substring(dataStart, dataEnd - dataStart));
                            ilGenerator.Emit(OperationCode.Callvirt, opLoadData);
                            break;
                        case '?':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Ldloc_1);
                            ilGenerator.Emit(OperationCode.Call, inputCast);
                            ilGenerator.Emit(OperationCode.Callvirt, opInput);
                            break;
                        case '!':
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Ldloc_2);
                            ilGenerator.Emit(OperationCode.Call, outputCast);
                            ilGenerator.Emit(OperationCode.Callvirt, opOutput);
                            break;
                        case '{':
                            var cycleStart = new ILGeneratorLabel();
                            var cycleEnd = new ILGeneratorLabel();
                            labels.Push(cycleStart);
                            labels.Push(cycleEnd);
                            ilGenerator.Emit(OperationCode.Br, cycleEnd);
                            ilGenerator.MarkLabel(cycleStart);
                            break;
                        case '}':
                            ilGenerator.MarkLabel(labels.Pop());
                            ilGenerator.Emit(OperationCode.Ldloc_0);
                            ilGenerator.Emit(OperationCode.Callvirt, opJz);
                            ilGenerator.Emit(OperationCode.Ldc_I4_0);
                            ilGenerator.Emit(OperationCode.Ceq);
                            ilGenerator.Emit(OperationCode.Stloc_3);
                            ilGenerator.Emit(OperationCode.Ldloc_3);
                            ilGenerator.Emit(OperationCode.Brtrue, labels.Pop());
                            break;
                        default:
                            break;
                    }
                }

                ilGenerator.Emit(OperationCode.Ret);

                mainMethod.Body = new ILGeneratorMethodBody(
                    ilGenerator,
                    true,
                    8,
                    mainMethod,
                    new List<ILocalDefinition>() {
                        new LocalDefinition() { Type = machineType },
                        new LocalDefinition() { Type = inputType },
                        new LocalDefinition() { Type = outputType },
                        new LocalDefinition() { Type = host.PlatformType.SystemInt32 },
                    },
                    Enumerable<ITypeDefinition>.Empty
                );

                using (var peStream = File.Create(exeName))
                {
                    PeWriter.WritePeToStream(assembly, host, peStream);
                }
            }
        }
Beispiel #9
0
    private NamespaceTypeDefinition CreateContractClass(UnitNamespace unitNamespace) {

      var contractTypeName = this.host.NameTable.GetNameFor("Contract");
      var contractNamespaceName = this.host.NameTable.GetNameFor("System.Diagnostics.Contracts");

      Microsoft.Cci.MethodReference compilerGeneratedCtor =
        new Microsoft.Cci.MethodReference(
          this.host,
          this.compilerGeneratedAttributeType,
          CallingConvention.HasThis,
          this.systemVoidType,
          this.host.NameTable.Ctor,
          0);
      CustomAttribute compilerGeneratedAttribute = new CustomAttribute();
      compilerGeneratedAttribute.Constructor = compilerGeneratedCtor;

      var contractsNs = new NestedUnitNamespace() {
        ContainingUnitNamespace = unitNamespace,
        Name = contractNamespaceName,
      };
      NamespaceTypeDefinition result = new NamespaceTypeDefinition() {
        // NB: The string name must be kept in sync with the code that recognizes contract
        // methods!!
        Name = contractTypeName,
        Attributes = new List<ICustomAttribute>{ compilerGeneratedAttribute },
        BaseClasses = new List<ITypeReference>{ this.systemObjectType },
        ContainingUnitNamespace = contractsNs,
        InternFactory = this.host.InternFactory,
        IsBeforeFieldInit = true,
        IsClass = true,
        IsSealed = true,
        Layout = LayoutKind.Auto,
        StringFormat = StringFormatKind.Ansi,
      };
      return result;
    }
    private IMethodDefinition GetOrCreateFinalizer(ITypeDefinition type) {
      Contract.Requires(type != null);
      Contract.Requires(type != Dummy.Type);
      Contract.Ensures(Contract.Result<IMethodDefinition>() != null);
      Contract.Ensures(Contract.Result<IMethodDefinition>() != Dummy.Method);

      var finalizer = TypeHelper.GetMethod(type, base.host.NameTable.GetNameFor("Finalize"));
      if (finalizer == Dummy.Method) {
        // create a method:  virtual void Finalize()
        finalizer = new MethodDefinition() {
          IsVirtual = true,
          CallingConvention = CallingConvention.HasThis,
          ContainingTypeDefinition = type,
          InternFactory = host.InternFactory,
          IsCil = true,
          IsStatic = false,
          Name = base.host.NameTable.GetNameFor("Finalize"),
          Type = host.PlatformType.SystemVoid,
          Visibility = TypeMemberVisibility.Family,
        };

        // create a list of operations that holds (i) call to baseclass finalize if there is one and (ii) a return statement.
        var ops = new List<IOperation>();

        // call base class Finalize method    
        var baseClass = GetBaseClass(type);
        var baseClassFinalize = new Microsoft.Cci.MethodReference(
          base.host,
          baseClass,
          CallingConvention.HasThis,
          base.host.PlatformType.SystemVoid,
          base.host.NameTable.GetNameFor("Finalize"),
          0
        );

        ops.Add(new Operation() {
          Location = Dummy.Location,
          Offset = 0,
          OperationCode = OperationCode.Ldarg_0,
          Value = null
        });

        ops.Add(new Operation() {
          Location = Dummy.Location,
          Offset = 0,
          OperationCode = OperationCode.Call,
          Value = baseClassFinalize
        });

        ops.Add(new Operation() {
          Location = Dummy.Location,
          Offset = 0,
          OperationCode = OperationCode.Ret,
          Value = null
        });

        // create a method body with that single operation and no exception information
        var body = new MethodBody {
          LocalsAreZeroed = false,
          LocalVariables = null,
          MaxStack = 0,
          MethodDefinition = finalizer,
          OperationExceptionInformation = new List<IOperationExceptionInformation>(0),
          Operations = ops,
          PrivateHelperTypes = null
        };

        // update the method definition and the body to point to each other.
        body.MethodDefinition = finalizer;
        ((MethodDefinition)finalizer).Body = body;

        // add it to this typeDefinition
        var containingType = type as NamedTypeDefinition;
        if (containingType != null) {
          if (containingType.Methods == null) containingType.Methods = new List<IMethodDefinition>();
          containingType.Methods.Add(finalizer);
        } else {
          var nestedContainingType = type as NestedTypeDefinition;
          if (nestedContainingType != null) {
            if (nestedContainingType.Methods == null) nestedContainingType.Methods = new List<IMethodDefinition>();
            nestedContainingType.Methods.Add(finalizer);
          } else {
            var specializedContainingType = type as SpecializedNestedTypeDefinition;
            if (specializedContainingType != null) {
              if (specializedContainingType.Methods == null) specializedContainingType.Methods = new List<IMethodDefinition>();
              specializedContainingType.Methods.Add(finalizer);
            } else {
              Contract.Assert(false);
            }
          }
        }

      }
      return finalizer;
    }
Beispiel #11
0
        public void Compile(string fileName)
        {
            string appName = Path.GetFileNameWithoutExtension(fileName);
            string exeName = appName + ".exe";
            string src     = "";

            using (TextReader file = new StreamReader(fileName))
            {
                src = file.ReadToEnd();
            }

            var nameTable = new NameTable();

            using (var host = new PeReader.DefaultHost(nameTable))
            {
                // Load Mirage types

                IModule module = host.LoadUnitFrom("Mirage.dll") as IModule;
                if (module == null || module is Dummy)
                {
                    return;
                }
                var machineType = module.GetAllTypes().First(x => x.Name.Value == "Machine");
                var inputType   = module.GetAllTypes().First(x => x.Name.Value == "ConsoleInput");
                var outputType  = module.GetAllTypes().First(x => x.Name.Value == "ConsoleOutput");

                // Create assembly

                var coreAssembly = host.LoadAssembly(host.CoreAssemblySymbolicIdentity);
                var assembly     = new Assembly()
                {
                    Name                 = nameTable.GetNameFor(appName),
                    ModuleName           = nameTable.GetNameFor(exeName),
                    PlatformType         = host.PlatformType,
                    Kind                 = ModuleKind.ConsoleApplication,
                    RequiresStartupStub  = host.PointerSize == 4,
                    TargetRuntimeVersion = coreAssembly.TargetRuntimeVersion,
                };
                assembly.AssemblyReferences.Add(coreAssembly);

                // Create namespace

                var rootUnitNamespace = new RootUnitNamespace();
                assembly.UnitNamespaceRoot = rootUnitNamespace;
                rootUnitNamespace.Unit     = assembly;

                // Create module class

                var moduleClass = new NamespaceTypeDefinition()
                {
                    ContainingUnitNamespace = rootUnitNamespace,
                    InternFactory           = host.InternFactory,
                    IsClass = true,
                    Name    = nameTable.GetNameFor("<Module>"),
                };
                assembly.AllTypes.Add(moduleClass);

                // Create program class

                var programClass = new NamespaceTypeDefinition()
                {
                    ContainingUnitNamespace = rootUnitNamespace,
                    InternFactory           = host.InternFactory,
                    IsClass  = true,
                    IsPublic = true,
                    Methods  = new List <IMethodDefinition>(1),
                    Name     = nameTable.GetNameFor("Program"),
                };
                programClass.BaseClasses = new List <ITypeReference>()
                {
                    host.PlatformType.SystemObject
                };
                rootUnitNamespace.Members.Add(programClass);

                // Add types to the assembly

                assembly.AllTypes.Add(machineType);
                foreach (var t in machineType.NestedTypes)
                {
                    assembly.AllTypes.Add(t);
                }
                assembly.AllTypes.Add(inputType);
                assembly.AllTypes.Add(outputType);
                assembly.AllTypes.Add(programClass);

                // Create main method

                var mainMethod = new MethodDefinition()
                {
                    ContainingTypeDefinition = programClass,
                    InternFactory            = host.InternFactory,
                    IsCil      = true,
                    IsStatic   = true,
                    Name       = nameTable.GetNameFor("Main"),
                    Type       = host.PlatformType.SystemVoid,
                    Visibility = TypeMemberVisibility.Public,
                };
                assembly.EntryPoint = mainMethod;
                programClass.Methods.Add(mainMethod);

                // Create constructors and methods

                IMethodReference machineConstructor = new Microsoft.Cci.MethodReference(
                    host,
                    machineType,
                    CallingConvention.HasThis,
                    host.PlatformType.SystemVoid,
                    host.NameTable.Ctor,
                    0
                    );

                IMethodReference inputConstructor = new Microsoft.Cci.MethodReference(
                    host,
                    inputType,
                    CallingConvention.HasThis,
                    host.PlatformType.SystemVoid,
                    host.NameTable.Ctor,
                    0
                    );
                var inputCast = TypeHelper.GetMethod(inputType, nameTable.GetNameFor("op_Implicit"), inputType);

                IMethodReference outputConstructor = new Microsoft.Cci.MethodReference(
                    host,
                    outputType,
                    CallingConvention.HasThis,
                    host.PlatformType.SystemVoid,
                    host.NameTable.Ctor,
                    0
                    );
                var outputCast = TypeHelper.GetMethod(outputType, nameTable.GetNameFor("op_Implicit"), outputType);

                var opIncPointers      = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("IncPointers"));
                var opDecPointers      = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("DecPointers"));
                var opIncHiPointer     = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("IncHiPointer"));
                var opDecHiPointer     = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("DecHiPointer"));
                var opReflectHiPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("ReflectHiPointer"));
                var opLoadHiPointer    = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("LoadHiPointer"));
                var opDragLoPointer    = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("DragLoPointer"));
                var opXchPointers      = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("XchPointers"));

                var opClear = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Clear"));
                var opAdd   = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Add"));
                var opDec   = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Dec"));
                var opNot   = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Not"));
                var opAnd   = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("And"));
                var opOr    = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Or"));
                var opXor   = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Xor"));
                var opSal   = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Sal"));
                var opSar   = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Sar"));

                var opLoadData = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("LoadData"), host.PlatformType.SystemString);
                var opInput    = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Input"), inputCast.Type);
                var opOutput   = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Output"), outputCast.Type);

                var opJz = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Jz"));

                // Create program code

                var labels = new Stack <ILGeneratorLabel>(100);

                var ilGenerator = new ILGenerator(host, mainMethod);
                ilGenerator.Emit(OperationCode.Newobj, machineConstructor);
                ilGenerator.Emit(OperationCode.Stloc_0);
                ilGenerator.Emit(OperationCode.Newobj, inputConstructor);
                ilGenerator.Emit(OperationCode.Stloc_1);
                ilGenerator.Emit(OperationCode.Newobj, outputConstructor);
                ilGenerator.Emit(OperationCode.Stloc_2);

                int pc = 0;
                while (pc < src.Length)
                {
                    char opcode = src[pc++];

                    switch (opcode)
                    {
                    case '>':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opIncPointers);
                        break;

                    case '<':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opDecPointers);
                        break;

                    case ']':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opIncHiPointer);
                        break;

                    case '[':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opDecHiPointer);
                        break;

                    case '#':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opReflectHiPointer);
                        break;

                    case '$':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opLoadHiPointer);
                        break;

                    case '=':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opDragLoPointer);
                        break;

                    case '%':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opXchPointers);
                        break;

                    case '_':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opClear);
                        break;

                    case '+':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opAdd);
                        break;

                    case '-':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opDec);
                        break;

                    case '~':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opNot);
                        break;

                    case '&':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opAnd);
                        break;

                    case '|':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opOr);
                        break;

                    case '^':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opXor);
                        break;

                    case '*':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opSal);
                        break;

                    case '/':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opSar);
                        break;

                    case '(':
                        int dataStart = pc;
                        int dataEnd   = dataStart;
                        while (src[pc++] != ')')
                        {
                            dataEnd = pc;
                        }
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Ldstr, src.Substring(dataStart, dataEnd - dataStart));
                        ilGenerator.Emit(OperationCode.Callvirt, opLoadData);
                        break;

                    case '?':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Ldloc_1);
                        ilGenerator.Emit(OperationCode.Call, inputCast);
                        ilGenerator.Emit(OperationCode.Callvirt, opInput);
                        break;

                    case '!':
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Ldloc_2);
                        ilGenerator.Emit(OperationCode.Call, outputCast);
                        ilGenerator.Emit(OperationCode.Callvirt, opOutput);
                        break;

                    case '{':
                        var cycleStart = new ILGeneratorLabel();
                        var cycleEnd   = new ILGeneratorLabel();
                        labels.Push(cycleStart);
                        labels.Push(cycleEnd);
                        ilGenerator.Emit(OperationCode.Br, cycleEnd);
                        ilGenerator.MarkLabel(cycleStart);
                        break;

                    case '}':
                        ilGenerator.MarkLabel(labels.Pop());
                        ilGenerator.Emit(OperationCode.Ldloc_0);
                        ilGenerator.Emit(OperationCode.Callvirt, opJz);
                        ilGenerator.Emit(OperationCode.Ldc_I4_0);
                        ilGenerator.Emit(OperationCode.Ceq);
                        ilGenerator.Emit(OperationCode.Stloc_3);
                        ilGenerator.Emit(OperationCode.Ldloc_3);
                        ilGenerator.Emit(OperationCode.Brtrue, labels.Pop());
                        break;

                    default:
                        break;
                    }
                }

                ilGenerator.Emit(OperationCode.Ret);

                mainMethod.Body = new ILGeneratorMethodBody(
                    ilGenerator,
                    true,
                    8,
                    mainMethod,
                    new List <ILocalDefinition>()
                {
                    new LocalDefinition()
                    {
                        Type = machineType
                    },
                    new LocalDefinition()
                    {
                        Type = inputType
                    },
                    new LocalDefinition()
                    {
                        Type = outputType
                    },
                    new LocalDefinition()
                    {
                        Type = host.PlatformType.SystemInt32
                    },
                },
                    Enumerable <ITypeDefinition> .Empty
                    );

                using (var peStream = File.Create(exeName))
                {
                    PeWriter.WritePeToStream(assembly, host, peStream);
                }
            }
        }
Beispiel #12
0
        internal void AddSecurityTransparencyAttribute(List<ICustomAttribute> list, SecurityTransparencyStatus securityTransparencyStatus, ITypeReference containingType)
        {
            Microsoft.Cci.MethodReference ctor = null;
            switch (securityTransparencyStatus)
            {
                case SecurityTransparencyStatus.Critical:
                    ctor = new Microsoft.Cci.MethodReference(this.host, containingType.PlatformType.SystemSecuritySecurityCriticalAttribute,//FindType("System.Security.SecurityCriticalAttribute"),
                    CallingConvention.HasThis, this.host.PlatformType.SystemVoid, this.host.NameTable.Ctor, 0);
                    break;
                case SecurityTransparencyStatus.SafeCritical:
                    ctor = new Microsoft.Cci.MethodReference(this.host, containingType.PlatformType.SystemSecuritySecuritySafeCriticalAttribute,//FindType("System.Security.SecuritySafeCriticalAttribute"),
                    CallingConvention.HasThis, this.host.PlatformType.SystemVoid, this.host.NameTable.Ctor, 0);
                    break;
                case SecurityTransparencyStatus.Transparent:
                    break;
            }

            if (ctor != null)
            {
                CustomAttribute securityAttribute = new CustomAttribute();
                securityAttribute.Constructor = ctor;
                list.Add(Rewrite(securityAttribute));
            }
        }
Beispiel #13
0
        private void AddFaaAttributeIfNeeded(Element element, List<ICustomAttribute> attributes, ITypeReference containingType)
        {
            if (element != null && element.IsFriendAccessAllowed)//typeHasFaaAttribute(attributes, containingType))
            {
                List<INamedTypeDefinition> types = new List<INamedTypeDefinition>(this.host.FindAssembly(this.host.CoreAssemblySymbolicIdentity).GetAllTypes());

                if (types == null || !types.Any())
                    return; //Couldn't find any type on the assembly

                IEnumerable<INamedTypeDefinition> faaAttributeType = types.Where(t => t.Name.Value == "FriendAccessAllowedAttribute");
                if (!faaAttributeType.Any())
                    return; //Unable to find the FriendAccessAllowedAttribute
                var faaAttributeResult = faaAttributeType.FirstOrDefault();
                if (!Util.HasAttribute(attributes, faaAttributeResult))
                {
                    Microsoft.Cci.MethodReference faaCtor = new Microsoft.Cci.MethodReference(this.host, faaAttributeResult,
                      CallingConvention.HasThis, this.host.PlatformType.SystemVoid, this.host.NameTable.Ctor, 0);
                    CustomAttribute faaAttribute = new CustomAttribute();
                    faaAttribute.Constructor = faaCtor;
                    attributes.Add(Rewrite(faaAttribute));
                }
            }
        }
Beispiel #14
0
            public override void TraverseChildren(IMethodCall methodCall)
            {
                var resolvedMethod = Sink.Unspecialize(methodCall.MethodToCall).ResolvedMethod;

                var methodName = Microsoft.Cci.MemberHelper.GetMethodSignature(resolvedMethod);

                if (methodName.Equals("System.Object.GetHashCode") || methodName.Equals("System.Object.ToString"))
                {
                    base.TraverseChildren(methodCall);
                    return;
                }

                bool isEventAdd    = resolvedMethod.IsSpecialName && resolvedMethod.Name.Value.StartsWith("add_");
                bool isEventRemove = resolvedMethod.IsSpecialName && resolvedMethod.Name.Value.StartsWith("remove_");

                if (isEventAdd || isEventRemove)
                {
                    base.TraverseChildren(methodCall);
                    return;
                }

                if (!methodCall.IsVirtualCall)
                {
                    base.TraverseChildren(methodCall);
                    return;
                }
                var containingType = TypeHelper.UninstantiateAndUnspecialize(methodCall.MethodToCall.ContainingType);
                List <ITypeReference> subTypesOfContainingType;

                if (!this.subTypes.TryGetValue(containingType, out subTypesOfContainingType))
                {
                    base.TraverseChildren(methodCall);
                    return;
                }
                Contract.Assert(0 < subTypesOfContainingType.Count);
                Contract.Assert(!methodCall.IsStaticCall);
                Contract.Assert(!resolvedMethod.IsConstructor);
                var  overrides = FindOverrides(containingType, resolvedMethod);
                bool same      = true;

                foreach (var o in overrides)
                {
                    IMethodDefinition resolvedOverride = Sink.Unspecialize(o.Item2).ResolvedMethod;
                    if (resolvedOverride != resolvedMethod)
                    {
                        same = false;
                    }
                }
                if (!(containingType.ResolvedType.IsInterface) && (0 == overrides.Count || same))
                {
                    base.TraverseChildren(methodCall);
                    return;
                }

                Contract.Assume(1 <= overrides.Count);

                var getType = new Microsoft.Cci.MethodReference(
                    this.sink.host,
                    this.sink.host.PlatformType.SystemObject,
                    CallingConvention.HasThis,
                    this.sink.host.PlatformType.SystemType,
                    this.sink.host.NameTable.GetNameFor("GetType"), 0);
                var op_Type_Equality = new Microsoft.Cci.MethodReference(
                    this.sink.host,
                    this.sink.host.PlatformType.SystemType,
                    CallingConvention.Default,
                    this.sink.host.PlatformType.SystemBoolean,
                    this.sink.host.NameTable.GetNameFor("op_Equality"),
                    0,
                    this.sink.host.PlatformType.SystemType,
                    this.sink.host.PlatformType.SystemType);

                // Depending on whether the method is a void method or not
                // Turn into expression:
                //   (o.GetType() == typeof(T1)) ? ((T1)o).M(...) : ( (o.GetType() == typeof(T2)) ? ((T2)o).M(...) : ...
                // Or turn into statements:
                //   if (o.GetType() == typeof(T1)) ((T1)o).M(...) else if ...
                var        turnIntoStatements = resolvedMethod.Type.TypeCode == PrimitiveTypeCode.Void;
                IStatement elseStatement      = null;

                IExpression elseValue = new MethodCall()
                {
                    Arguments     = new List <IExpression>(methodCall.Arguments),
                    IsStaticCall  = false,
                    IsVirtualCall = false,
                    MethodToCall  = methodCall.MethodToCall,
                    ThisArgument  = methodCall.ThisArgument,
                    Type          = methodCall.Type,
                };

                if (turnIntoStatements)
                {
                    elseStatement = new ExpressionStatement()
                    {
                        Expression = elseValue,
                    }
                }
                ;

                Conditional          ifConditional = null;
                ConditionalStatement ifStatement   = null;

                foreach (var typeMethodPair in overrides)
                {
                    var t = typeMethodPair.Item1;
                    var m = typeMethodPair.Item2;

                    if (m.IsGeneric)
                    {
                        var baseMethod = m.ResolvedMethod;
                        m = new GenericMethodInstanceReference()
                        {
                            CallingConvention = baseMethod.CallingConvention,
                            ContainingType    = baseMethod.ContainingTypeDefinition,
                            GenericArguments  = new List <ITypeReference>(IteratorHelper.GetConversionEnumerable <IGenericMethodParameter, ITypeReference>(baseMethod.GenericParameters)),
                            GenericMethod     = baseMethod,
                            InternFactory     = this.sink.host.InternFactory,
                            Name       = baseMethod.Name,
                            Parameters = baseMethod.ParameterCount == 0 ? null : new List <IParameterTypeInformation>(baseMethod.Parameters),
                            Type       = baseMethod.Type,
                        };
                    }

                    var cond = new MethodCall()
                    {
                        Arguments = new List <IExpression>()
                        {
                            new MethodCall()
                            {
                                Arguments     = new List <IExpression>(),
                                IsStaticCall  = false,
                                IsVirtualCall = false,
                                MethodToCall  = getType,
                                ThisArgument  = methodCall.ThisArgument,
                            },
                            new TypeOf()
                            {
                                TypeToGet = t,
                            },
                        },
                        IsStaticCall  = true,
                        IsVirtualCall = false,
                        MethodToCall  = op_Type_Equality,
                        Type          = this.sink.host.PlatformType.SystemBoolean,
                    };
                    Expression thenValue = new MethodCall()
                    {
                        Arguments     = new List <IExpression>(methodCall.Arguments),
                        IsStaticCall  = false,
                        IsVirtualCall = false,
                        MethodToCall  = m,
                        ThisArgument  = methodCall.ThisArgument,
                        Type          = m.Type,
                    };
                    thenValue = new Conversion()
                    {
                        Type = m.Type,
                        TypeAfterConversion = methodCall.Type,
                        ValueToConvert      = thenValue,
                    };
                    if (turnIntoStatements)
                    {
                        ifStatement = new ConditionalStatement()
                        {
                            Condition   = cond,
                            FalseBranch = elseStatement,
                            TrueBranch  = new ExpressionStatement()
                            {
                                Expression = thenValue,
                            },
                        };
                        elseStatement = ifStatement;
                    }
                    else
                    {
                        ifConditional = new Conditional()
                        {
                            Condition     = cond,
                            ResultIfFalse = elseValue,
                            ResultIfTrue  = thenValue,
                        };
                        elseValue = ifConditional;
                    }
                }
                if (turnIntoStatements)
                {
                    Contract.Assume(ifStatement != null);
                    this.StmtTraverser.Traverse(ifStatement);
                }
                else
                {
                    Contract.Assume(ifConditional != null);
                    base.Traverse(ifConditional);
                }

                return;
            }