/// <summary>
        /// Get the number of values removed on the stack for this instruction.
        /// </summary>
        /// <param name="self">The Instruction on which the extension method can be called.</param>
        /// <param name="method">The method inside which the instruction comes from (needed for StackBehaviour.Varpop).</param>
        /// <param name="currentstacksize">This method returns this value when stack behaviour is StackBehaviour.PopAll.</param>
        /// <returns>The number of values removed (pop) from the stack for this instruction.</returns>
        public static int GetPopCount(this Instruction self, MethodReference method, int currentstacksize = 0)
		{
			if (self == null)
				throw new ArgumentException("self");
            if (method == null)
				throw new ArgumentException("method");

            var sbp = self.OpCode.StackBehaviourPop;

			if (sbp != StackBehaviour.Varpop)
				return sbp != StackBehaviour.PopAll ? StackBehaviourCache[(int)sbp] : currentstacksize;

			if (self.OpCode.FlowControl == FlowControl.Return)
				return method.ReturnType.FullName == "System.Void" ? 0 : 1;

			var calledMethod = self.Operand as MethodReference;

			// avoid allocating empty ParameterDefinitionCollection
			var n = calledMethod.HasParameters ? calledMethod.Parameters.Count : 0;
		    if (self.OpCode.Code == Code.Newobj)
                return n;
		    if (calledMethod.HasThis)
		        n++;
		    return n;
		}
Beispiel #2
0
        public Instruction Create(OpCode opcode, MethodReference meth)
        {
            if (opcode.OperandType != OperandType.InlineMethod &&
                opcode.OperandType != OperandType.InlineTok)
                throw new ArgumentException ("opcode");

            return FinalCreate (opcode, meth);
        }
		public GenericContext (IGenericParameterProvider provider)
		{
			if (provider is TypeReference)
				m_type = provider as TypeReference;
			else if (provider is MethodReference) {
				MethodReference meth = provider as MethodReference;
				m_method = meth;
				m_type = meth.DeclaringType;
			}
		}
    internal LockReplacer(SourceMethodBody sourceMethodBody) {
      Contract.Requires(sourceMethodBody != null);
      this.host = sourceMethodBody.host; Contract.Assume(sourceMethodBody.host != null);
      this.sourceLocationProvider = sourceMethodBody.sourceLocationProvider;
      this.numberOfReferencesToLocal = sourceMethodBody.numberOfReferencesToLocal; Contract.Assume(sourceMethodBody.numberOfReferencesToLocal != null);
      this.numberOfAssignmentsToLocal = sourceMethodBody.numberOfAssignmentsToLocal; Contract.Assume(sourceMethodBody.numberOfAssignmentsToLocal != null);
      this.bindingsThatMakeALastUseOfALocalVersion = sourceMethodBody.bindingsThatMakeALastUseOfALocalVersion; Contract.Assume(sourceMethodBody.bindingsThatMakeALastUseOfALocalVersion != null);
      var systemThreading = new Immutable.NestedUnitNamespaceReference(this.host.PlatformType.SystemObject.ContainingUnitNamespace,
        this.host.NameTable.GetNameFor("Threading"));
      var systemThreadingMonitor = new Immutable.NamespaceTypeReference(this.host, systemThreading, this.host.NameTable.GetNameFor("Monitor"), 0,
        isEnum: false, isValueType: false, typeCode: PrimitiveTypeCode.NotPrimitive);
      var parameters = new IParameterTypeInformation[2];
      this.monitorEnter = new MethodReference(this.host, systemThreadingMonitor, CallingConvention.Default, this.host.PlatformType.SystemVoid,
        this.host.NameTable.GetNameFor("Enter"), 0, parameters);
      parameters[0] = new SimpleParameterTypeInformation(monitorEnter, 0, this.host.PlatformType.SystemObject);
      parameters[1] = new SimpleParameterTypeInformation(monitorEnter, 1, this.host.PlatformType.SystemBoolean, isByReference: true);
      this.monitorExit = new MethodReference(this.host, systemThreadingMonitor, CallingConvention.Default, this.host.PlatformType.SystemVoid,
        this.host.NameTable.GetNameFor("Exit"), 0, this.host.PlatformType.SystemObject);

    }
		private static PropertyDefinition GetMethodDeclaringProperty(MethodReference method)
		{
			if (method == null)
			{
				return null;
			}

			TypeDefinition type = method.DeclaringType.Resolve();
			if (type != null)
			{
				foreach (PropertyDefinition property in type.Properties)
				{
					if ((property.GetMethod != null && property.GetMethod.HasSameSignatureWith(method)) ||
						(property.SetMethod != null && property.SetMethod.HasSameSignatureWith(method)))
					{
						return property;
					}
				}
			}

			return null;
		}
 public static bool HasCopyConstructor(this TypeDefinition type, out MethodReference constructor)
 {
     constructor = type.GetConstructors().SingleOrDefault(c => c.HasSingleParameter(type));
     return(constructor != null);
 }
 internal MethodRefSignatureConverter(PEFileToObjectModel peFileToObjectModel, MethodReference moduleMethodRef, MemoryReader signatureMemoryReader)
   : base(peFileToObjectModel, signatureMemoryReader, moduleMethodRef) {
   //  TODO: Check minimum required size of the signature...
   byte firstByte = this.SignatureMemoryReader.ReadByte();
   if (SignatureHeader.IsGeneric(firstByte)) {
     this.GenericParamCount = (ushort)this.SignatureMemoryReader.ReadCompressedUInt32();
   }
   int paramCount = this.SignatureMemoryReader.ReadCompressedUInt32();
   bool dummyPinned;
   this.ReturnCustomModifiers = this.GetCustomModifiers(out dummyPinned);
   byte retByte = this.SignatureMemoryReader.PeekByte(0);
   if (retByte == ElementType.Void) {
     this.ReturnTypeReference = peFileToObjectModel.PlatformType.SystemVoid;
     this.SignatureMemoryReader.SkipBytes(1);
   } else if (retByte == ElementType.TypedReference) {
     this.ReturnTypeReference = peFileToObjectModel.PlatformType.SystemTypedReference;
     this.SignatureMemoryReader.SkipBytes(1);
   } else {
     if (retByte == ElementType.ByReference) {
       this.IsReturnByReference = true;
       this.SignatureMemoryReader.SkipBytes(1);
     }
     this.ReturnTypeReference = this.GetTypeReference();
   }
   if (paramCount > 0) {
     this.RequiredParameters = this.GetModuleParameterTypeInformations(moduleMethodRef, paramCount);
     if (this.RequiredParameters.Length < paramCount)
       this.VarArgParameters = this.GetModuleParameterTypeInformations(moduleMethodRef, paramCount - this.RequiredParameters.Length);
   }
 }
		public Instruction Emit (OpCode opcode, MethodReference meth)
		{
			Instruction instr = Create (opcode, meth);
			Append (instr);
			return instr;
		}
Beispiel #9
0
		public CustomAttrib (MethodReference ctor)
		{
			Constructor = ctor;
		}
Beispiel #10
0
 public ValueTarget Callvirt(MethodReference method)
 {
     _callvirt = method;
     return(this);
 }
Beispiel #11
0
 /// <summary>
 /// Generates IL for the specified create delegate instance.
 /// </summary>
 /// <param name="createDelegateInstance">The create delegate instance.</param>
 public override void TraverseChildren(ICreateDelegateInstance createDelegateInstance)
 {
     IPlatformType platformType = createDelegateInstance.Type.PlatformType;
       MethodReference constructor = new MethodReference(this.host, createDelegateInstance.Type, CallingConvention.Default|CallingConvention.HasThis,
     platformType.SystemVoid, this.host.NameTable.Ctor, 0, platformType.SystemObject, platformType.SystemIntPtr);
       if (createDelegateInstance.Instance != null) {
     this.Traverse(createDelegateInstance.Instance);
     if (createDelegateInstance.IsVirtualDelegate) {
       this.generator.Emit(OperationCode.Dup);
       this.StackSize++;
       this.generator.Emit(OperationCode.Ldvirtftn, createDelegateInstance.MethodToCallViaDelegate);
       this.StackSize--;
     } else
       this.generator.Emit(OperationCode.Ldftn, createDelegateInstance.MethodToCallViaDelegate);
     this.StackSize++;
       } else {
     this.generator.Emit(OperationCode.Ldnull);
     this.generator.Emit(OperationCode.Ldftn, createDelegateInstance.MethodToCallViaDelegate);
     this.StackSize+=2;
       }
       this.generator.Emit(OperationCode.Newobj, constructor);
       this.StackSize--;
 }
Beispiel #12
0
 public static bool IsGenericMethod(MethodReference methodDefinition)
 {
     return(methodDefinition.GenericParameters.Count > 0);
 }
Beispiel #13
0
 public MethodReference Import(MethodReference meth)
 {
     return m_importer.ImportMethodReference (meth, this);
 }
 /// <summary>
 /// Finds dependencies based on an operand.
 /// </summary>
 /// <param name="operand">Operand for instruction</param>
 /// <returns>Imported operand for target instruction.</returns>
 protected override IEnumerable <object> InvokeForOperand(MethodReference operand)
 {
     Contract.Requires(operand != null);
     return(operand.GetDependencies());
 }
        /// <summary>
        /// Creates a new method for invoking the original test method from the testing engine.
        /// </summary>
        internal void RewriteTestMethod(MethodDefinition method, MethodDefinition testMethod)
        {
            bool          isAsyncMethod   = false;
            TypeReference asyncReturnType = null;

            // move any AsyncStateMachineAttributes.
            foreach (var attr in method.CustomAttributes.ToArray())
            {
                var typeName = attr.AttributeType.FullName;
                if (typeName == "System.Runtime.CompilerServices.AsyncStateMachineAttribute")
                {
                    isAsyncMethod     = true;
                    asyncReturnType   = method.ReturnType;
                    method.ReturnType = this.Module.ImportReference(typeof(void));
                }

                if (typeName == "System.Runtime.CompilerServices.AsyncStateMachineAttribute" ||
                    typeName == "System.Diagnostics.DebuggerStepThroughAttribute")
                {
                    method.CustomAttributes.Remove(attr);
                    testMethod.CustomAttributes.Add(attr);
                }
            }

            method.Body.Variables.Clear();
            method.Body.Instructions.Clear();
            method.Body.ExceptionHandlers.Clear();

            MethodReference launchMethod = null;

            if (this.Configuration.AttachDebugger)
            {
                var debuggerType = this.Module.ImportReference(typeof(System.Diagnostics.Debugger)).Resolve();
                launchMethod = FindMethod("Launch", debuggerType);
            }

            TypeReference actionType;

            if (isAsyncMethod)
            {
                var funcType = this.Module.ImportReference(typeof(Func <>));
                actionType = MakeGenericType(funcType, asyncReturnType);
            }
            else
            {
                actionType = this.Module.ImportReference(typeof(Action));
            }

            var configurationType = this.Module.ImportReference(typeof(Configuration));
            var engineType        = this.Module.ImportReference(typeof(TestingEngine));

            var resolvedActionType        = actionType.Resolve(); // Func<>
            var resolvedConfigurationType = configurationType.Resolve();
            var resolvedEngineType        = engineType.Resolve();

            MethodReference actionConstructor = this.Module.ImportReference(
                resolvedActionType.Methods.FirstOrDefault(m => m.IsConstructor));

            if (isAsyncMethod)
            {
                actionConstructor = MakeGenericMethod(actionConstructor, asyncReturnType);
            }

            MethodReference createConfigurationMethod = this.Module.ImportReference(
                resolvedConfigurationType.Methods.FirstOrDefault(m => m.Name is "Create"));
            MethodReference createEngineMethod = this.Module.ImportReference(
                FindMethod("Create", resolvedEngineType, configurationType, actionType));

            // The emitted IL corresponds to a method body such as:
            //   Configuration configuration = Configuration.Create();
            //   TestingEngine engine = TestingEngine.Create(configuration, new Action(Test));
            //   engine.Run();
            //   engine.ThrowIfBugFound();
            //
            // With optional calls to setup some of the configuration options based on Coyote command line:
            // including:
            //   configuration.WithTestingIterations(n);
            //   configuration.WithMaxSchedulingSteps(x, y);
            //   configuration.WithProbabilisticStrategy(x);
            //   configuration.WithPCTStrategy(x);
            //   configuration.SchedulingStrategy(x);
            //   configuration.WithLivenessTemperatureThreshold(x);
            //   configuration.WithTimeoutDelay(x);
            //   configuration.WithRandomGeneratorSeed(x);
            //   configuration.WithVerbosityEnabled(x);
            //   configuration.WithTelemetryEnabled(x);
            var processor = method.Body.GetILProcessor();

            if (launchMethod != null)
            {
                processor.Emit(OpCodes.Call, this.Module.ImportReference(launchMethod));
                processor.Emit(OpCodes.Pop);
            }

            var defaultConfig = Configuration.Create();

            processor.Emit(OpCodes.Call, createConfigurationMethod);
            if (this.Configuration.TestingIterations != defaultConfig.TestingIterations)
            {
                this.EmitMethodCall(processor, resolvedConfigurationType, "WithTestingIterations", this.Configuration.TestingIterations);
            }

            if (this.Configuration.MaxUnfairSchedulingSteps != defaultConfig.MaxUnfairSchedulingSteps || this.Configuration.MaxFairSchedulingSteps != defaultConfig.MaxFairSchedulingSteps)
            {
                this.EmitMethodCall(processor, resolvedConfigurationType, "WithMaxSchedulingSteps", (uint)this.Configuration.MaxUnfairSchedulingSteps, (uint)this.Configuration.MaxFairSchedulingSteps);
            }

            if (this.Configuration.SchedulingStrategy != defaultConfig.SchedulingStrategy)
            {
                switch (this.Configuration.SchedulingStrategy)
                {
                case "fairpct":
                    this.EmitMethodCall(processor, resolvedConfigurationType, "WithProbabilisticStrategy", (uint)this.Configuration.StrategyBound);
                    break;

                case "pct":
                    this.EmitMethodCall(processor, resolvedConfigurationType, "WithPCTStrategy", false, (uint)this.Configuration.StrategyBound);
                    break;

                case "dfs":
                    this.EmitMethodCall(processor, resolvedConfigurationType, "SchedulingStrategy", this.Configuration.ScheduleTrace);
                    break;

                default:
                    break;
                }
            }

            if (this.Configuration.UserExplicitlySetLivenessTemperatureThreshold)
            {
                this.EmitMethodCall(processor, resolvedConfigurationType, "WithLivenessTemperatureThreshold", (uint)this.Configuration.LivenessTemperatureThreshold);
            }

            if (this.Configuration.TimeoutDelay != defaultConfig.TimeoutDelay)
            {
                this.EmitMethodCall(processor, resolvedConfigurationType, "WithTimeoutDelay", this.Configuration.TimeoutDelay);
            }

            if (this.Configuration.RandomGeneratorSeed.HasValue)
            {
                this.EmitMethodCall(processor, resolvedConfigurationType, "WithRandomGeneratorSeed", this.Configuration.RandomGeneratorSeed.Value);
            }

            if (this.Configuration.IsVerbose)
            {
                this.EmitMethodCall(processor, resolvedConfigurationType, "WithVerbosityEnabled", this.Configuration.IsVerbose, this.Configuration.LogLevel);
            }

            if (!this.Configuration.EnableTelemetry)
            {
                this.EmitMethodCall(processor, resolvedConfigurationType, "WithTelemetryEnabled", this.Configuration.EnableTelemetry);
            }

            processor.Emit(OpCodes.Ldarg_0);
            processor.Emit(OpCodes.Ldftn, testMethod);
            processor.Emit(OpCodes.Newobj, actionConstructor);
            processor.Emit(OpCodes.Call, createEngineMethod);
            processor.Emit(OpCodes.Dup);
            this.EmitMethodCall(processor, resolvedEngineType, "Run");
            this.EmitMethodCall(processor, resolvedEngineType, "ThrowIfBugFound");
            processor.Emit(OpCodes.Ret);

            method.Body.OptimizeMacros();
        }
Beispiel #16
0
        /// <summary>Try rewriting the direct field reference with reflection access.</summary>
        /// <param name="cil">The CIL processor.</param>
        /// <param name="module">The assembly module containing the instruction.</param>
        /// <param name="instruction">The CIL instruction to rewrite.</param>
        /// <param name="fieldRef">The field reference.</param>
        /// <param name="isRead">Whether the field is being read; else it's being written to.</param>
        /// <param name="isStatic">Whether the field is static field; else it's instance field.</param>
        /// <param name="declaringType">The type on which the field was defined.</param>
        private bool TryRewriteWithReflection(ILProcessor cil, ModuleDefinition module, Instruction instruction, FieldReference fieldRef, bool isRead, bool isStatic)
        {
            MethodReference    getTypeFromHandleRef = module.ImportReference(typeof(Type).GetMethod("GetTypeFromHandle", new Type[] { typeof(RuntimeTypeHandle) }));
            MethodReference    getFieldRef          = module.ImportReference(typeof(Type).GetMethod("GetField", new Type[] { typeof(string), typeof(BindingFlags) }));
            VariableDefinition varInstance          = null;

            if (isRead)
            {
                if (!isStatic)
                {
                    varInstance = new VariableDefinition(fieldRef.DeclaringType);
                    cil.Body.Variables.Add(varInstance);
                }
                // inverse order insert
                // load instance (origin logic, if not static)
                // stloc.s 0
                // ldtoken	MonoGame.Framework.Patcher.Test
                // call	System.Type System.Type::GetTypeFromHandle(System.RuntimeTypeHandle)
                // ldstr	text
                // ldc.i4.s	60
                // callvirt	System.Reflection.FieldInfo System.Type::GetField(System.String,System.Reflection.BindingFlags)
                // ldloc.0
                // callvirt	System.Object System.Reflection.FieldInfo::GetValue(System.Object)
                // castclass System.String
                if (fieldRef.FieldType.IsValueType)
                {
                    cil.InsertAfter(instruction, cil.Create(OpCodes.Unbox_Any, fieldRef.FieldType));
                }
                else
                {
                    cil.InsertAfter(instruction, cil.Create(OpCodes.Castclass, fieldRef.FieldType));
                }
                MethodReference getValueMethodRef = module.ImportReference(AccessTools.Method(typeof(FieldInfo), nameof(FieldInfo.GetValue)));
                cil.InsertAfter(instruction, cil.Create(OpCodes.Callvirt, getValueMethodRef));
                if (!isStatic)
                {
                    cil.InsertAfter(instruction, cil.Create(OpCodes.Ldloc_S, varInstance));
                }
                else
                {
                    cil.InsertAfter(instruction, cil.Create(OpCodes.Ldnull));
                }
                cil.InsertAfter(instruction, cil.Create(OpCodes.Callvirt, getFieldRef));
                cil.InsertAfter(instruction, cil.Create(OpCodes.Ldc_I4_S, (sbyte)60));
                cil.InsertAfter(instruction, cil.Create(OpCodes.Ldstr, fieldRef.Name));
                cil.InsertAfter(instruction, cil.Create(OpCodes.Call, getTypeFromHandleRef));
                if (!isStatic)
                {
                    // prohibit replace remove entry point (may cause jump logic broken)
                    cil.InsertAfter(instruction, cil.Create(OpCodes.Nop));
                    instruction.OpCode  = OpCodes.Stloc_S;
                    instruction.Operand = varInstance;
                    instruction         = instruction.Next;
                }
            }
            else
            {
                VariableDefinition varValue = null;
                if (!isStatic)
                {
                    varInstance = new VariableDefinition(fieldRef.DeclaringType);
                    cil.Body.Variables.Add(varInstance);
                }
                varValue = new VariableDefinition(fieldRef.FieldType);
                cil.Body.Variables.Add(varValue);
                // inverse order insert
                // load instance (origin logic, if not static)
                // load value (origin logic)
                // stloc.s 0
                // ldtoken	Patcher.TestClass
                // call	System.Type System.Type::GetTypeFromHandle(System.RuntimeTypeHandle)
                // ldstr	text
                // ldc.i4.s	60
                // callvirt	System.Reflection.FieldInfo System.Type::GetField(System.String,System.Reflection.BindingFlags)
                // ldloc.0
                // ldloc.1
                // callvirt	System.Object System.Reflection.FieldInfo::SetValue(System.Object, System.Object)
                MethodReference setValueMethodRef = module.ImportReference(AccessTools.Method(typeof(FieldInfo), nameof(FieldInfo.SetValue), new Type[] { typeof(object), typeof(object) }));
                cil.InsertAfter(instruction, cil.Create(OpCodes.Callvirt, setValueMethodRef));
                cil.InsertAfter(instruction, cil.Create(OpCodes.Ldloc_S, varValue));
                if (isStatic)
                {
                    cil.InsertAfter(instruction, cil.Create(OpCodes.Ldnull));
                }
                else
                {
                    cil.InsertAfter(instruction, cil.Create(OpCodes.Ldloc_S, varInstance));
                }
                cil.InsertAfter(instruction, cil.Create(OpCodes.Callvirt, getFieldRef));
                cil.InsertAfter(instruction, cil.Create(OpCodes.Ldc_I4_S, (sbyte)60));
                cil.InsertAfter(instruction, cil.Create(OpCodes.Ldstr, fieldRef.Name));
                cil.InsertAfter(instruction, cil.Create(OpCodes.Call, getTypeFromHandleRef));

                // prohibit replace remove entry point (may cause jump logic broken)
                instruction.OpCode  = OpCodes.Stloc_S;
                instruction.Operand = varValue;
                cil.InsertAfter(instruction, cil.Create(OpCodes.Nop));
                if (!isStatic)
                {
                    cil.InsertAfter(instruction, cil.Create(OpCodes.Stloc_S, varInstance));
                    instruction = instruction.Next;
                }
                instruction = instruction.Next;
            }
            // rewrite field ref to ldtoken
            instruction.OpCode  = OpCodes.Ldtoken;
            instruction.Operand = fieldRef.DeclaringType;

            this.Phrases.Add($"{fieldRef.DeclaringType.Name}.{fieldRef.Name} (field ref => reflection ref)");
// #if SMAPI_FOR_MOBILE
//             this.Phrases.Add($"{cil.Body.Method.FullName} => {cil.Body.Instructions.Select(ins => ins.ToString()).Join(null, ";")}");
// #endif
            cil.Body.MaxStackSize += 5;
            return(this.MarkRewritten());
        }
Beispiel #17
0
 private static void InjectReturnableMethod <TParam, TThis, TInput, TLocal, TUseOutput, TMethodOutputBind>(CecilContext stardewContext, ILProcessor ilProcessor, IEnumerable <Instruction> targets, MethodReference method, bool isExit = false)
 {
     foreach (var target in targets.ToList())
     {
         InjectReturnableMethod <TParam, TThis, TInput, TLocal, TUseOutput, TMethodOutputBind>(stardewContext, ilProcessor, target, method, isExit);
     }
 }
Beispiel #18
0
 protected override void ImplementProceed(MethodDefinition methodInfo, MethodBody methodBody, ILProcessor il, FieldReference methodInfoField, MethodReference proceed, Action <ILProcessor> emitProceedTarget, MethodReference proceedTargetMethod, OpCode proceedOpCode)
 {
     if (methodInfo.IsAbstract)
     {
         CecilExtensions.CreateDefaultMethodImplementation(methodInfo, il);
     }
     else
     {
         base.ImplementProceed(methodInfo, methodBody, il, methodInfoField, proceed, emitProceedTarget, proceedTargetMethod, proceedOpCode);
     }
 }
 public static bool IsGenericMethod(this MethodReference method)
 {
     return(method.GenericParameters.Count > 0);
 }
Beispiel #20
0
        public override void WriteTo(ITextOutput output)
        {
            if (Operand is ILVariable && ((ILVariable)Operand).IsGenerated)
            {
                if (Code == ILCode.Stloc && this.InferredType == null)
                {
                    output.Write(((ILVariable)Operand).Name);

                    output.Write(" = ");
                    Arguments.First().WriteTo(output);
                    return;
                }
                else if (Code == ILCode.Ldloc)
                {
                    output.Write(((ILVariable)Operand).Name);
                    if (this.InferredType != null)
                    {
                        output.Write(':');
                        this.InferredType.WriteTo(output, ILNameSyntax.ShortTypeName);
                        if (this.ExpectedType != null && this.ExpectedType.FullName != this.InferredType.FullName)
                        {
                            output.Write("[exp:");
                            this.ExpectedType.WriteTo(output, ILNameSyntax.ShortTypeName);
                            output.Write(']');
                        }
                    }
                    return;
                }
            }

            if (this.Prefixes != null)
            {
                foreach (var prefix in this.Prefixes)
                {
                    output.Write(prefix.Code.GetName());
                    output.Write(". ");
                }
            }

            output.Write(Code.GetName());
            if (this.InferredType != null)
            {
                output.Write(':');
                this.InferredType.WriteTo(output, ILNameSyntax.ShortTypeName);
                if (this.ExpectedType != null && this.ExpectedType.FullName != this.InferredType.FullName)
                {
                    output.Write("[exp:");
                    this.ExpectedType.WriteTo(output, ILNameSyntax.ShortTypeName);
                    output.Write(']');
                }
            }
            else if (this.ExpectedType != null)
            {
                output.Write("[exp:");
                this.ExpectedType.WriteTo(output, ILNameSyntax.ShortTypeName);
                output.Write(']');
            }
            output.Write('(');
            bool first = true;

            if (Operand != null)
            {
                if (Operand is ILLabel)
                {
                    output.WriteReference(((ILLabel)Operand).Name, Operand);
                }
                else if (Operand is ILLabel[])
                {
                    ILLabel[] labels = (ILLabel[])Operand;
                    for (int i = 0; i < labels.Length; i++)
                    {
                        if (i > 0)
                        {
                            output.Write(", ");
                        }
                        output.WriteReference(labels[i].Name, labels[i]);
                    }
                }
                else if (Operand is MethodReference)
                {
                    MethodReference method = (MethodReference)Operand;
                    if (method.DeclaringType != null)
                    {
                        method.DeclaringType.WriteTo(output, ILNameSyntax.ShortTypeName);
                        output.Write("::");
                    }
                    output.WriteReference(method.Name, method);
                }
                else if (Operand is FieldReference)
                {
                    FieldReference field = (FieldReference)Operand;
                    field.DeclaringType.WriteTo(output, ILNameSyntax.ShortTypeName);
                    output.Write("::");
                    output.WriteReference(field.Name, field);
                }
                else
                {
                    DisassemblerHelpers.WriteOperand(output, Operand);
                }
                first = false;
            }
            foreach (ILExpression arg in this.Arguments)
            {
                if (!first)
                {
                    output.Write(", ");
                }
                arg.WriteTo(output);
                first = false;
            }
            output.Write(')');
        }
 public GenericContext(TypeReference type, MethodReference meth)
 {
     m_type = type;
     m_method = meth;
 }
    public void Execute()
    {
        var markerDll = Check(() => ModuleDefinition.AssemblyReferences.SingleOrDefault(a => a.Name.ToLowerInvariant() == "AutoDependencyPropertyMarker".ToLowerInvariant()), "find AutoDependencyPropertyMarker reference");

        if (markerDll == null)
        {
            return;
        }
        var             windowsBase        = CheckAssembly("WindowsBase", description: "Couldn't find reference to WindowsBase. Or it isn't referenced by project or it was stripped because it wasn't referenced from code. Make sure that your types are subtypes of DependencyObject.");
        var             mscorlib           = CheckAssembly("mscorlib");
        var             typeFromHandle     = CheckImport(() => mscorlib.GetType("System.Type").Methods.Single(m => m.Name == "GetTypeFromHandle"), "GetTypeFromHandle");
        var             depObject          = Check(() => windowsBase.GetType("System.Windows.DependencyObject"), "load DependencyObject");
        var             getValue           = CheckImport(() => depObject.Methods.Single(m => m.Name == "GetValue"), "GetValue");
        var             setValue           = CheckImport(() => depObject.Methods.Single(m => m.Name == "SetValue" && m.Parameters.Count == 2 && m.Parameters[0].ParameterType.Name == "DependencyProperty" && m.Parameters[1].ParameterType.Name == "Object"), "SetValue");
        var             depProperty        = Check(() => windowsBase.GetType("System.Windows.DependencyProperty"), "load DependencyProperty");
        var             depPropertyRef     = Check(() => ModuleDefinition.Import(depProperty), "import DependencyProperty");
        var             registerSimple     = CheckImport(() => depProperty.Methods.Single(m => m.Name == "Register" && m.Parameters.Count == 3), "Register");
        var             registerMeta       = CheckImport(() => depProperty.Methods.Single(m => m.Name == "Register" && m.Parameters.Count == 4), "Register");
        var             presentationDllRef = Check(() => ModuleDefinition.AssemblyReferences.SingleOrDefault(a => a.Name.ToLowerInvariant() == "PresentationFramework".ToLowerInvariant()), "check for PresentationFramework reference");
        MethodReference metadataCtor       = null;

        foreach (var type in ModuleDefinition.Types)
        {
            if (!type.IsSpecialName && type.GenericParameters.Count == 0 && Inherits(type, "System.Windows.DependencyObject"))
            {
                var instructions = new List <Instruction>();
                var cctor        = type.GetStaticConstructor();
                foreach (var property in type.Properties)
                {
                    if (!property.IsSpecialName && property.HasThis && property.GetMethod != null && property.SetMethod != null && property.GetMethod.IsPublic && property.SetMethod.IsPublic)
                    {
                        var attribute = property.CustomAttributes.Concat(type.CustomAttributes).FirstOrDefault(
                            a => a.AttributeType.FullName == "AutoDependencyPropertyMarker.AutoDependencyPropertyAttribute");
                        if (attribute == null)
                        {
                            continue;
                        }
                        if (type.Fields.Any(f => f.Name == property.Name + "Property"))
                        {
                            continue;
                        }
                        var backing = type.Fields.FirstOrDefault(f => f.Name == "<" + property.Name + ">k__BackingField" && f.FieldType.FullName == property.PropertyType.FullName);
                        if (backing == null)
                        {
                            continue;
                        }
                        var field = new FieldDefinition(property.Name + "Property", FieldAttributes.Static | FieldAttributes.InitOnly | FieldAttributes.Public, depPropertyRef);
                        type.Fields.Add(field);
                        if (cctor == null)
                        {
                            cctor = new MethodDefinition(".cctor", MethodAttributes.Static | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Private | MethodAttributes.RTSpecialName, ModuleDefinition.TypeSystem.Void);
                            type.Methods.Add(cctor);
                            cctor.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));
                        }
                        instructions.Add(Instruction.Create(OpCodes.Ldstr, property.Name));
                        instructions.Add(Instruction.Create(OpCodes.Ldtoken, property.PropertyType));
                        instructions.Add(Instruction.Create(OpCodes.Call, typeFromHandle));
                        instructions.Add(Instruction.Create(OpCodes.Ldtoken, type));
                        instructions.Add(Instruction.Create(OpCodes.Call, typeFromHandle));
                        var options = attribute.Properties.FirstOrDefault(p => p.Name == "Options");
                        if (options.Name == null || (int)options.Argument.Value == 0)
                        {
                            instructions.Add(Instruction.Create(OpCodes.Call, registerSimple));
                        }
                        else
                        {
                            if (metadataCtor == null)
                            {
                                if (presentationDllRef == null)
                                {
                                    metadataCtor = Check(() => ModuleDefinition.Import(typeof(FrameworkPropertyMetadata).GetConstructor(new[] { typeof(object), typeof(FrameworkPropertyMetadataOptions) })), "directly import FrameworkPropertyMetadata constructor");
                                }
                                else
                                {
                                    var presentationDll = CheckAssembly("PresentationFramework");
                                    metadataCtor = CheckImport(() => presentationDll.GetType("System.Windows.FrameworkPropertyMetadata").GetConstructors().Single(c => c.Parameters.Count == 2 && c.Parameters[1].ParameterType.Name == "FrameworkPropertyMetadataOptions"), "FrameworkPropertyMetadata constructor");
                                }
                            }
                            if (!property.PropertyType.IsValueType)
                            {
                                instructions.Add(Instruction.Create(OpCodes.Ldnull));
                            }
                            else
                            {
                                cctor.Body.InitLocals = true;
                                var constVar = new VariableDefinition(property.PropertyType);
                                cctor.Body.Variables.Add(constVar);
                                instructions.Add(Instruction.Create(OpCodes.Ldloca_S, constVar));
                                instructions.Add(Instruction.Create(OpCodes.Initobj, property.PropertyType));
                                instructions.Add(Instruction.Create(OpCodes.Ldloc, constVar));
                                instructions.Add(Instruction.Create(OpCodes.Box, property.PropertyType));
                            }
                            instructions.Add(Instruction.Create(OpCodes.Ldc_I4, (int)options.Argument.Value));
                            instructions.Add(Instruction.Create(OpCodes.Newobj, metadataCtor));
                            instructions.Add(Instruction.Create(OpCodes.Call, registerMeta));
                        }
                        instructions.Add(Instruction.Create(OpCodes.Stsfld, field));
                        property.GetMethod.Body.Instructions.Clear();
                        var getter = property.GetMethod.Body.GetILProcessor();
                        getter.Emit(OpCodes.Ldarg_0);
                        getter.Emit(OpCodes.Ldarg_0);
                        getter.Emit(OpCodes.Ldfld, field);
                        getter.Emit(OpCodes.Call, getValue);
                        getter.Emit(property.PropertyType.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass, property.PropertyType);
                        getter.Emit(OpCodes.Ret);
                        property.SetMethod.Body.Instructions.Clear();
                        var setter = property.SetMethod.Body.GetILProcessor();
                        setter.Emit(OpCodes.Ldarg_0);
                        setter.Emit(OpCodes.Ldarg_0);
                        setter.Emit(OpCodes.Ldfld, field);
                        setter.Emit(OpCodes.Ldarg_1);
                        if (property.PropertyType.IsValueType)
                        {
                            setter.Emit(OpCodes.Box, property.PropertyType);
                        }
                        setter.Emit(OpCodes.Call, setValue);
                        setter.Emit(OpCodes.Ret);
                        type.Fields.Remove(backing);
                        property.CustomAttributes.Remove(attribute);
                    }
                }
                instructions.Reverse();
                foreach (var instruction in instructions)
                {
                    cctor.Body.Instructions.Insert(0, instruction);
                }
                foreach (var attribute in type.CustomAttributes.Where(a => a.AttributeType.FullName == "AutoDependencyPropertyMarker.AutoDependencyPropertyAttribute").ToList())
                {
                    type.CustomAttributes.Remove(attribute);
                }
            }
        }
        ModuleDefinition.AssemblyReferences.Remove(markerDll);
    }
    //^ invariant this.PEFileReader.MethodSpecTable.NumberOfRows >= 1 ==> this.MethodSpecHashtable != null;

    internal MemberReference/*?*/ GetModuleMemberReferenceAtRowWorker(
      MetadataObject owningObject,
      uint memberRefRowId
    ) {
      if (memberRefRowId == 0 || memberRefRowId > this.PEFileReader.MemberRefTable.NumberOfRows) {
        return null;
      }
      if (this.ModuleMemberReferenceArray[memberRefRowId] == null) {
        MemberRefRow memberRefRow = this.PEFileReader.MemberRefTable[memberRefRowId];
        uint classTokenType = memberRefRow.Class & TokenTypeIds.TokenTypeMask;
        uint classRowId = memberRefRow.Class & TokenTypeIds.RIDMask;
        IModuleTypeReference/*?*/ parentTypeReference = null;
        switch (classTokenType) {
          case TokenTypeIds.TypeDef:
            parentTypeReference = this.GetTypeDefinitionAtRowWorker(classRowId);
            break;
          case TokenTypeIds.TypeRef:
            parentTypeReference = this.GetTypeRefReferenceAtRowWorker(classRowId);
            break;
          case TokenTypeIds.TypeSpec:
            parentTypeReference = this.GetTypeSpecReferenceAtRow(owningObject, classRowId).UnderlyingModuleTypeReference;
            break;
          case TokenTypeIds.MethodDef: {
              MethodDefinition/*?*/ methodDef = this.GetMethodDefAtRow(classRowId);
              if (methodDef == null) {
                //  Error...
                return null;
              }
              parentTypeReference = methodDef.OwningModuleType;
              break;
            }
          case TokenTypeIds.ModuleRef: {
              ModuleReference/*?*/ modRef = this.GetModuleReferenceAt(classRowId);
              if (modRef == null) {
                //  MDError
                return null;
              }
              Module/*?*/ module = this.ResolveModuleRefReference(modRef);
              if (module == null) {
                //TODO: MDError...
                return null;
              }
              PEFileToObjectModel modulePEFileToObjectModel = module.PEFileToObjectModel;
              parentTypeReference = modulePEFileToObjectModel._Module_;
              break;
            }
          default: {
              //  MDError...
              return null;
            }
        }
        if (parentTypeReference == null) {
          //  Error...
          return null;
        }
        MemberReference retModuleMemberReference;
        IName name = this.GetNameFromOffset(memberRefRow.Name);
        byte firstByte = this.PEFileReader.BlobStream.GetByteAt(memberRefRow.Signature, 0);
        IModuleGenericTypeInstance/*?*/ genericTypeInstance = parentTypeReference as IModuleGenericTypeInstance;
        IModuleSpecializedNestedTypeReference/*?*/ specializedNestedTypeReference = parentTypeReference as IModuleSpecializedNestedTypeReference;
        if (SignatureHeader.IsFieldSignature(firstByte)) {
          if (genericTypeInstance != null) {
            //The same memberRef token can be shared by distinct instance references, therefore recompute every time.
            return new GenericInstanceFieldReference(this, memberRefRowId, genericTypeInstance, name);
          } else if (specializedNestedTypeReference != null) {
            //The same memberRef token can be shared by distinct instance references, therefore recompute every time.
            return new SpecializedNestedTypeFieldReference(this, memberRefRowId, parentTypeReference, specializedNestedTypeReference, name);
          } else {
            retModuleMemberReference = new FieldReference(this, memberRefRowId, parentTypeReference, name);
          }
        } else if (SignatureHeader.IsMethodSignature(firstByte)) {
          if (genericTypeInstance != null) {
            //The same memberRef token can be shared by distinct instance references, therefore recompute every time.
            return new GenericInstanceMethodReference(this, memberRefRowId, genericTypeInstance, name, firstByte);
          } else if (specializedNestedTypeReference != null) {
            //The same memberRef token can be shared by distinct instance references, therefore recompute every time.
            return new SpecializedNestedTypeMethodReference(this, memberRefRowId, parentTypeReference, specializedNestedTypeReference, name, firstByte);
          } else {
            retModuleMemberReference = new MethodReference(this, memberRefRowId, parentTypeReference, name, firstByte);
          }
        } else {
          //  MD Error
          return null;
        }
        this.ModuleMemberReferenceArray[memberRefRowId] = retModuleMemberReference;
      }
      MemberReference/*?*/ ret = this.ModuleMemberReferenceArray[memberRefRowId];
      return ret;
    }
Beispiel #24
0
        private IEnumerable <AssemblyLine> Call(Instruction instruction)
        {
            // Could be either a MethodDefinition or MethodReference.
            MethodReference method = (MethodReference)instruction.Operand;

            var methodDeclaringType = method.DeclaringType.FullName;
            var processedSubroutine = Types[methodDeclaringType].Subroutines.Single(s => s.FullName == method.FullName);

            // Check if this method should be replaced with a direct store to a symbol (generally a TIA register).
            // Don't directly compare types since we may have received a different Framework assembly than what this library was built against.
            if (processedSubroutine.TryGetFrameworkAttribute <OverrideWithStoreToSymbolAttribute>(out var overrideStore))
            {
                if (!overrideStore.Strobe)
                {
                    //TODO - We assume this is a 1-arg void method. Actually enforce this at the processing stage.
                    if (method.Parameters.Count != 1)
                    {
                        throw new NotImplementedException($"{method.Name}, marked with {nameof(OverrideWithStoreToSymbolAttribute)}, must take 1 parameter for now.");
                    }
                    yield return(PLA());
                }
                yield return(STA(overrideStore.Symbol));

                yield break;
            }

            if (processedSubroutine.TryGetFrameworkAttribute <OverrideWithLoadToRegisterAttribute>(out var overrideRegisterLoad))
            {
                //TODO - We assume this is a 1-arg void method. Actually enforce this at the processing stage.
                if (method.Parameters.Count != 1)
                {
                    throw new NotImplementedException($"{method.Name}, marked with {nameof(OverrideWithLoadToRegisterAttribute)} must take 1 parameter.");
                }
                yield return(PLA());

                switch (overrideRegisterLoad.Register)
                {
                case "A":
                    break;

                case "X":
                    yield return(TAX());

                    break;

                case "Y":
                    yield return(TAY());

                    break;

                default:
                    throw new FatalCompilationException($"Attempted load to unknown register: {overrideRegisterLoad.Register}");
                }
                yield break;
            }

            if (processedSubroutine.TryGetFrameworkAttribute <OverrideWithLoadFromSymbolAttribute>(out var overrideLoad))
            {
                if (method.Parameters.Count != 0)
                {
                    throw new NotImplementedException($"{method.Name}, marked with {nameof(OverrideWithLoadFromSymbolAttribute)}, must take 0 parameters.");
                }
                yield return(LDA(overrideLoad.Symbol));

                yield return(PHA());

                yield break;
            }

            var parameters = ((MethodReference)method).Parameters.ToImmutableArray();

            if (parameters.Any())
            {
                // PLA arguments in reverse off stack and assign to parameters.
                foreach (var parameter in parameters.Reverse())
                {
                    yield return(PLA());

                    yield return(STA(LabelGenerator.GetFromParameter(parameter)));
                }
            }

            if (processedSubroutine.TryGetFrameworkAttribute <AlwaysInlineAttribute>(out _))
            {
                var compiledSubroutine = Types[method.DeclaringType.FullName].Subroutines.Single(s => s.FullName == method.FullName) as CompiledSubroutine;
                if (compiledSubroutine == null)
                {
                    throw new FatalCompilationException($"Attempted to inline method '{processedSubroutine.Name}' that hasn't been compiled yet. This suggests a bug in determining method compilation order.");
                }

                foreach (var assemblyLine in compiledSubroutine.Body)
                {
                    //TODO - If the subroutine contains labels you can end up emitting duplicates if the inline subroutine is called more than once. Make them unique.
                    //TODO - Once we have branching and multiple return statements this will explode.
                    // In reality we probably want to replace RTS with JMP to a label inserted after this method body.
                    if (!assemblyLine.Text.Contains("RTS"))
                    {
                        yield return(assemblyLine);
                    }
                }
                yield break;
            }

            yield return(JSR(LabelGenerator.GetFromMethod(method)));
        }
 internal MethodRefSignatureConverter GetMethodRefSignature(
   MethodReference moduleMethodReference
 ) {
   uint signatureBlobOffset = this.PEFileReader.MemberRefTable.GetSignature(moduleMethodReference.MemberRefRowId);
   //  TODO: error checking offset in range
   MemoryBlock signatureMemoryBlock = this.PEFileReader.BlobStream.GetMemoryBlockAt(signatureBlobOffset);
   //  TODO: Error checking enough space in signature memoryBlock.
   MemoryReader memoryReader = new MemoryReader(signatureMemoryBlock);
   //  TODO: Check if this is really method signature there.
   MethodRefSignatureConverter methodRefSigConv = new MethodRefSignatureConverter(this, moduleMethodReference, memoryReader);
   return methodRefSigConv;
 }
Beispiel #26
0
        /// <summary />
        public override IStatement Rewrite(IForEachStatement forEachStatement)
        {
            ILocalDefinition foreachLocal;
            var key = forEachStatement.Collection.Type.InternedKey;

            ITypeReference enumeratorType;
            IMethodReference getEnumerator;
            IMethodReference getCurrent;

            var gtir = forEachStatement.Collection.Type as IGenericTypeInstanceReference;
            if (gtir != null)
            {
                var typeArguments = gtir.GenericArguments;
                ITypeReference genericEnumeratorType = new Immutable.GenericTypeInstanceReference(this.host.PlatformType.SystemCollectionsGenericIEnumerator, typeArguments, this.host.InternFactory);
                ITypeReference genericEnumerableType = new Immutable.GenericTypeInstanceReference(this.host.PlatformType.SystemCollectionsGenericIEnumerable, typeArguments, this.host.InternFactory);
                enumeratorType = genericEnumeratorType;
                getEnumerator = new SpecializedMethodReference()
                {
                    CallingConvention = CallingConvention.HasThis,
                    ContainingType = genericEnumerableType,
                    InternFactory = this.host.InternFactory,
                    Name = this.host.NameTable.GetNameFor("GetEnumerator"),
                    Parameters = new List<IParameterTypeInformation>(),
                    Type = genericEnumeratorType,
                    UnspecializedVersion = new MethodReference()
                    {
                        CallingConvention = CallingConvention.HasThis,
                        ContainingType = this.host.PlatformType.SystemCollectionsGenericIEnumerable,
                        InternFactory = this.host.InternFactory,
                        Name = this.host.NameTable.GetNameFor("GetEnumerator"),
                        Parameters = new List<IParameterTypeInformation>(),
                        Type = this.host.PlatformType.SystemCollectionsGenericIEnumerator,
                    },
                };
                var getEnumerator2 = (IMethodReference) 
                    IteratorHelper.First(genericEnumerableType.ResolvedType.GetMembersNamed(this.host.NameTable.GetNameFor("GetEnumerator"), false));
                getEnumerator = getEnumerator2;
                getCurrent = (IMethodReference) IteratorHelper.First(genericEnumeratorType.ResolvedType.GetMembersNamed(this.host.NameTable.GetNameFor("get_Current"), false));
            }
            else
            {
                enumeratorType = this.host.PlatformType.SystemCollectionsIEnumerator;
                getEnumerator = new MethodReference()
                {
                    CallingConvention = CallingConvention.HasThis,
                    ContainingType = enumeratorType,
                    InternFactory = this.host.InternFactory,
                    Name = this.host.NameTable.GetNameFor("GetEnumerator"),
                    Parameters = new List<IParameterTypeInformation>(),
                    Type = this.host.PlatformType.SystemCollectionsIEnumerable,
                };
                getCurrent = new MethodReference()
                {
                    CallingConvention = CallingConvention.HasThis,
                    ContainingType = enumeratorType,
                    InternFactory = this.host.InternFactory,
                    Name = this.host.NameTable.GetNameFor("get_Current"),
                    Parameters = new List<IParameterTypeInformation>(),
                    Type = this.host.PlatformType.SystemObject,
                };
            }

            var initializer = new MethodCall()
                    {
                        Arguments = new List<IExpression>(),
                        IsStaticCall = false,
                        IsVirtualCall = true,
                        MethodToCall = getEnumerator,
                        ThisArgument = forEachStatement.Collection,
                        Type = enumeratorType,
                    };
            IStatement initialization;

            if (!this.foreachLocals.TryGetValue(key, out foreachLocal))
            {
                foreachLocal = new LocalDefinition() { Type = enumeratorType, Name = this.host.NameTable.GetNameFor("CS$5$" + this.foreachLocals.Count) };
                this.foreachLocals.Add(key, foreachLocal);
                initialization = new LocalDeclarationStatement()
                {
                    InitialValue = initializer,
                    LocalVariable = foreachLocal,
                };
            }
            else
            {
                initialization = new ExpressionStatement()
                {
                    Expression = new Assignment()
                    {
                        Source = initializer,
                        Target = new TargetExpression()
                        {
                            Definition = foreachLocal,
                            Instance = null,
                            Type = foreachLocal.Type,
                        },
                        Type = foreachLocal.Type,
                    },
                };
            }

            var newStmts = new List<IStatement>();
            newStmts.Add(new ExpressionStatement(){
                                                Expression = new Assignment(){
                                                     Source = new MethodCall(){
                                                          Arguments = new List<IExpression>(),
                                                          IsStaticCall = false,
                                                          IsVirtualCall = true,
                                                          MethodToCall = getCurrent,
                                                          ThisArgument = new BoundExpression(){
                                                               Definition = foreachLocal,
                                                               Instance = null,
                                                          },
                                                          Type = forEachStatement.Variable.Type,
                                                     },
                                                      Target = new TargetExpression(){
                                                           Definition = forEachStatement.Variable,
                                                           Instance = null,
                                                      },
                                                       Type = forEachStatement.Variable.Type,
                                                },
                                           });
            newStmts.Add(forEachStatement.Body);
            var newBody = new BlockStatement(){ Statements = newStmts,}; 
            var result = new BlockStatement()
            {
                Statements = new List<IStatement>(){
                   initialization,
                   new TryCatchFinallyStatement(){
                       TryBody = new BlockStatement() {
                           Statements = new List<IStatement>(){
                               new WhileDoStatement(){
                                   Body = newBody,
                                   Condition = new MethodCall(){
                                       Arguments = new List<IExpression>(),
                                       IsStaticCall = false,
                                       IsVirtualCall = true,
                                       MethodToCall = moveNext,
                                       ThisArgument = new BoundExpression(){ 
                                           Definition = foreachLocal,
                                           Instance = null,
                                       },
                                       Type = this.host.PlatformType.SystemBoolean,
                                   },
                               },
                           },
                       },
                       FinallyBody = new BlockStatement() {
                           Statements = new List<IStatement>(){
                               new ConditionalStatement(){
                                   Condition = new Equality(){
                                       LeftOperand = new BoundExpression(){ Definition = foreachLocal, Instance = null, Type = foreachLocal.Type, },
                                       RightOperand = new CompileTimeConstant(){ Type = foreachLocal.Type, Value = null, },
                                       Type = this.host.PlatformType.SystemBoolean,
                                   },
                                   FalseBranch = new EmptyStatement(),
                                   TrueBranch = new ExpressionStatement(){
                                       Expression = new MethodCall(){
                                           Arguments = new List<IExpression>(),
                                           IsStaticCall = false,
                                           IsVirtualCall = true,
                                           MethodToCall = this.disposeMethod,
                                           ThisArgument = new BoundExpression(){ 
                                               Definition = foreachLocal,
                                               Instance = null,
                                           },
                                           Type = this.host.PlatformType.SystemVoid,
                                       },
                                   },
                               },
                           },
                       },
                   },
                },
            };
            return result;
        }
Beispiel #27
0
 public Instruction Create(OpCode opcode, MethodReference method)
 {
     return Instruction.Create (opcode, method);
 }
        public RuleResult CheckMethod(MethodDefinition method)
        {
            // rule apply only if the method has a body (e.g. p/invokes, icalls don't)
            if (!method.HasBody || method.IsGeneratedCode())
            {
                return(RuleResult.DoesNotApply);
            }

            // is there any Call or Callvirt instructions in the method
            OpCodeBitmask bitmask = OpCodeEngine.GetBitmask(method);

            if (!OpCodeBitmask.Calls.Intersect(bitmask))
            {
                return(RuleResult.DoesNotApply);
            }

            foreach (Instruction ins in method.Body.Instructions)
            {
                Code code = ins.OpCode.Code;
                if ((code != Code.Call) && (code != Code.Callvirt))
                {
                    continue;
                }

                MethodReference mref = (ins.Operand as MethodReference);

                // covers Equals(string) method and both == != operators
                switch (mref.Name)
                {
                case "Equals":
                    if (mref.Parameters.Count > 1)
                    {
                        continue;
                    }
                    TypeReference type = mref.DeclaringType;
                    if (type.Namespace != "System")
                    {
                        continue;
                    }
                    string name = type.Name;
                    if ((name != "String") && (name != "Object"))
                    {
                        continue;
                    }
                    break;

                case "op_Equality":
                case "op_Inequality":
                    if (!mref.DeclaringType.IsNamed("System", "String"))
                    {
                        continue;
                    }
                    break;

                default:
                    continue;
                }

                Instruction prev = ins.Previous;
                switch (prev.OpCode.Code)
                {
                case Code.Ldstr:
                    if ((prev.Operand as string).Length > 0)
                    {
                        continue;
                    }
                    break;

                case Code.Ldsfld:
                    FieldReference field = (prev.Operand as FieldReference);
                    if (!field.DeclaringType.IsNamed("System", "String"))
                    {
                        continue;
                    }
                    // unlikely to be anything else (at least with released fx)
                    if (field.Name != "Empty")
                    {
                        continue;
                    }
                    break;

                default:
                    continue;
                }

                Runner.Report(method, ins, Severity.Medium, Confidence.High);
            }

            return(Runner.CurrentRuleResult);
        }
Beispiel #29
0
		public static Instruction Create (OpCode opcode, MethodReference method)
		{
			if (method == null)
				throw new ArgumentNullException ("method");
			if (opcode.OperandType != OperandType.InlineMethod &&
				opcode.OperandType != OperandType.InlineTok)
				throw new ArgumentException ("opcode");

			return new Instruction (opcode, method);
		}
Beispiel #30
0
 /// <summary>Get whether a type has a method whose signature matches the one expected by a method reference.</summary>
 /// <param name="type">The type to check.</param>
 /// <param name="reference">The method reference.</param>
 public static bool HasMatchingSignature(Type type, MethodReference reference)
 {
     return(type
            .GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public)
            .Any(method => RewriteHelper.HasMatchingSignature(method, reference)));
 }
Beispiel #31
0
        void IntroducePropertyAccessInstructions(ILExpression expr, ILExpression parentExpr, int posInParent)
        {
            if (expr.Code == ILCode.Call || expr.Code == ILCode.Callvirt)
            {
                MethodReference cecilMethod = (MethodReference)expr.Operand;
                if (cecilMethod.DeclaringType is ArrayType)
                {
                    switch (cecilMethod.Name)
                    {
                    case "Get":
                        expr.Code = ILCode.CallGetter;
                        break;

                    case "Set":
                        expr.Code = ILCode.CallSetter;
                        break;

                    case "Address":
                        ByReferenceType brt = cecilMethod.ReturnType as ByReferenceType;
                        if (brt != null)
                        {
                            MethodReference getMethod = new MethodReference("Get", brt.ElementType, cecilMethod.DeclaringType);
                            foreach (var p in cecilMethod.Parameters)
                            {
                                getMethod.Parameters.Add(p);
                            }
                            getMethod.HasThis = cecilMethod.HasThis;
                            expr.Operand      = getMethod;
                        }
                        expr.Code = ILCode.CallGetter;
                        if (parentExpr != null)
                        {
                            parentExpr.Arguments[posInParent] = new ILExpression(ILCode.AddressOf, null, expr);
                        }
                        break;
                    }
                }
                else
                {
                    MethodDefinition cecilMethodDef = cecilMethod.Resolve();
                    if (cecilMethodDef != null)
                    {
                        if (cecilMethodDef.IsGetter)
                        {
                            expr.Code = (expr.Code == ILCode.Call) ? ILCode.CallGetter : ILCode.CallvirtGetter;
                        }
                        else if (cecilMethodDef.IsSetter)
                        {
                            expr.Code = (expr.Code == ILCode.Call) ? ILCode.CallSetter : ILCode.CallvirtSetter;
                        }
                    }
                }
            }
            else if (expr.Code == ILCode.Newobj && expr.Arguments.Count == 2)
            {
                // Might be 'newobj(SomeDelegate, target, ldvirtftn(F, target))'.
                ILVariable target;
                if (expr.Arguments[0].Match(ILCode.Ldloc, out target) &&
                    expr.Arguments[1].Code == ILCode.Ldvirtftn &&
                    expr.Arguments[1].Arguments.Count == 1 &&
                    expr.Arguments[1].Arguments[0].MatchLdloc(target))
                {
                    // Remove the 'target' argument from the ldvirtftn instruction.
                    // It's not needed in the translation to C#, and needs to be eliminated so that the target expression
                    // can be inlined.
                    expr.Arguments[1].Arguments.Clear();
                }
            }
        }
Beispiel #32
0
        void GenerateSerialization()
        {
            Weaver.DLog(m_td, "  GenerateSerialization");
            foreach (var m in m_td.Methods)
            {
                if (m.Name == "Serialize")
                {
                    return;
                }
            }

            if (m_td.Fields.Count == 0)
            {
                return;
            }

            // check for self-referencing types
            foreach (var field in m_td.Fields)
            {
                if (field.FieldType.FullName == m_td.FullName)
                {
                    Weaver.fail = true;
                    Log.Error("GenerateSerialization for " + m_td.Name + " [" + field.FullName + "]. [MessageBase] member cannot be self referencing.");
                    return;
                }
            }

            MethodDefinition serializeFunc = new MethodDefinition("Serialize", MethodAttributes.Public |
                                                                  MethodAttributes.Virtual |
                                                                  MethodAttributes.HideBySig,
                                                                  Weaver.voidType);

            serializeFunc.Parameters.Add(new ParameterDefinition("writer", ParameterAttributes.None, Weaver.scriptDef.MainModule.ImportReference(Weaver.NetworkWriterType)));
            ILProcessor serWorker = serializeFunc.Body.GetILProcessor();

            foreach (var field in m_td.Fields)
            {
                if (field.IsStatic || field.IsPrivate || field.IsSpecialName)
                {
                    continue;
                }

                if (field.FieldType.Resolve().HasGenericParameters)
                {
                    Weaver.fail = true;
                    Log.Error("GenerateSerialization for " + m_td.Name + " [" + field.FieldType + "/" + field.FieldType.FullName + "]. [MessageBase] member cannot have generic parameters.");
                    return;
                }

                if (field.FieldType.Resolve().IsInterface)
                {
                    Weaver.fail = true;
                    Log.Error("GenerateSerialization for " + m_td.Name + " [" + field.FieldType + "/" + field.FieldType.FullName + "]. [MessageBase] member cannot be an interface.");
                    return;
                }

                MethodReference writeFunc = Weaver.GetWriteFunc(field.FieldType);
                if (writeFunc != null)
                {
                    serWorker.Append(serWorker.Create(OpCodes.Ldarg_1));
                    serWorker.Append(serWorker.Create(OpCodes.Ldarg_0));
                    serWorker.Append(serWorker.Create(OpCodes.Ldfld, field));
                    serWorker.Append(serWorker.Create(OpCodes.Call, writeFunc));
                }
                else
                {
                    Weaver.fail = true;
                    Log.Error("GenerateSerialization for " + m_td.Name + " unknown type [" + field.FieldType + "/" + field.FieldType.FullName + "]. [MessageBase] member variables must be basic types.");
                    return;
                }
            }
            serWorker.Append(serWorker.Create(OpCodes.Ret));

            m_td.Methods.Add(serializeFunc);
        }
Beispiel #33
0
        private static void InjectMethod <TParam, TThis, TInput, TLocal>(CecilContext stardewContext, ILProcessor ilProcessor, Instruction target, MethodReference method, bool isExit = false, bool cancelable = false)
        {
            ilProcessor.Body.SimplifyMacros();

            var callEnterInstruction = ilProcessor.Create(OpCodes.Call, method);

            if (method.HasThis)
            {
                var loadObjInstruction = ilProcessor.Create(OpCodes.Ldarg_0);
                ilProcessor.InsertBefore(target, loadObjInstruction);
            }

            if (method.HasParameters)
            {
                Instruction prevInstruction    = null;
                var         paramLdInstruction = target;
                var         first = true;
                foreach (var parameter in method.Parameters)
                {
                    paramLdInstruction = GetInstructionForParameter <TParam, TThis, TInput, TLocal, Patcher, Patcher>(stardewContext, ilProcessor, parameter);
                    if (paramLdInstruction == null)
                    {
                        throw new Exception($"Error parsing parameter setup on {parameter.Name}");
                    }

                    if (isExit)
                    {
                        if (first)
                        {
                            first = false;
                            ilProcessor.Replace(target, paramLdInstruction);
                        }
                        else
                        {
                            ilProcessor.InsertAfter(prevInstruction, paramLdInstruction);
                        }
                        prevInstruction = paramLdInstruction;
                    }
                    else
                    {
                        ilProcessor.InsertBefore(target, paramLdInstruction);
                    }
                }

                if (isExit)
                {
                    if (first)
                    {
                        ilProcessor.Replace(target, callEnterInstruction);
                        ilProcessor.InsertAfter(callEnterInstruction, ilProcessor.Create(OpCodes.Ret));
                    }
                    else
                    {
                        ilProcessor.InsertAfter(prevInstruction, callEnterInstruction);
                        ilProcessor.InsertAfter(callEnterInstruction, ilProcessor.Create(OpCodes.Ret));
                    }
                }
                else
                {
                    ilProcessor.InsertAfter(paramLdInstruction, callEnterInstruction);
                }
            }
            else
            {
                if (isExit)
                {
                    ilProcessor.Replace(target, callEnterInstruction);
                    ilProcessor.InsertAfter(callEnterInstruction, ilProcessor.Create(OpCodes.Ret));
                }
                else
                {
                    ilProcessor.InsertBefore(target, callEnterInstruction);
                }
            }

            if (cancelable)
            {
                var branch = ilProcessor.Create(OpCodes.Brtrue, ilProcessor.Body.Instructions.Last());
                ilProcessor.InsertAfter(callEnterInstruction, branch);
            }

            ilProcessor.Body.OptimizeMacros();
        }
		public static bool HasSameSignatureWith(this MethodReference self, MethodReference other)
		{
			if (!(self.GetMethodSignature() == other.GetMethodSignature()))
			{
				return false;
			}

			if (self.ReturnType.FullName != other.ReturnType.FullName)
			{
				if (self.ReturnType is GenericParameter && other.ReturnType is GenericParameter)
				{
					if ((self.ReturnType as GenericParameter).Position == (other.ReturnType as GenericParameter).Position)
					{
						return true;
					}
				}

				return false;
			}

			return true;
		}
Beispiel #35
0
        private static void InjectReturnableMethod <TParam, TThis, TInput, TLocal, TUseOutput, TMethodOutputBind>(CecilContext stardewContext, ILProcessor ilProcessor, Instruction target, MethodReference method, bool isExit = false)
        {
            ilProcessor.Body.SimplifyMacros();

            // Add UseReturnVal variable
            if (ilProcessor.Body.Variables.All(n => n.Name != "UseReturnVal"))
            {
                var boolType = stardewContext.GetTypeReference(typeof(bool));
                ilProcessor.Body.Variables.Add(new VariableDefinition("UseReturnVal", boolType));
            }
            var useOutputVariable = ilProcessor.Body.Variables.First(n => n.Name == "UseReturnVal");

            if (ilProcessor.Body.Variables.All(n => n.Name != "ReturnContainer-" + method.ReturnType.Name))
            {
                ilProcessor.Body.Variables.Add(new VariableDefinition("ReturnContainer-" + method.ReturnType.Name, method.ReturnType));
            }
            if (isExit)
            {
                if (ilProcessor.Body.Variables.All(n => n.Name != "OldReturnContainer"))
                {
                    ilProcessor.Body.Variables.Add(new VariableDefinition("OldReturnContainer", method.ReturnType));
                }
            }
            var containerVariable    = ilProcessor.Body.Variables.First(n => n.Name == "ReturnContainer-" + method.ReturnType.Name);
            var oldContainerVariable = ilProcessor.Body.Variables.FirstOrDefault(n => n.Name == "OldReturnContainer");

            List <Instruction> instructions = new List <Instruction>();

            if (isExit)
            {
                instructions.Add(ilProcessor.Create(OpCodes.Stloc, oldContainerVariable));
            }

            if (method.HasParameters)
            {
                foreach (var parameter in method.Parameters)
                {
                    var paramLdInstruction = GetInstructionForParameter <TParam, TThis, TInput, TLocal, TUseOutput, TMethodOutputBind>(stardewContext, ilProcessor, parameter);
                    if (paramLdInstruction == null)
                    {
                        throw new Exception($"Error parsing parameter setup on {parameter.Name}");
                    }

                    instructions.Add(paramLdInstruction);
                }
            }

            instructions.Add(ilProcessor.Create(OpCodes.Call, method));
            instructions.Add(ilProcessor.Create(OpCodes.Stloc, containerVariable));
            instructions.Add(ilProcessor.Create(OpCodes.Ldloc, useOutputVariable));
            if (!isExit)
            {
                instructions.Add(ilProcessor.Create(OpCodes.Brfalse, target));
                instructions.Add(ilProcessor.Create(OpCodes.Ldloc, containerVariable));
                instructions.Add(ilProcessor.Create(OpCodes.Br, ilProcessor.Body.Instructions.Last()));
            }
            else
            {
                var brToRet = ilProcessor.Create(OpCodes.Br, target);
                var loadOld = ilProcessor.Create(OpCodes.Ldloc, oldContainerVariable);
                var loadNew = ilProcessor.Create(OpCodes.Ldloc, containerVariable);
                instructions.Add(ilProcessor.Create(OpCodes.Brfalse, loadOld));
                instructions.Add(loadNew);
                instructions.Add(brToRet);
                instructions.Add(loadOld);
            }

            foreach (var inst in instructions)
            {
                ilProcessor.InsertBefore(target, inst);
            }

            ilProcessor.Body.OptimizeMacros();
        }
		public static TypeReference ResolveParameterType(this ParameterReference param, MethodReference method)
		{
			TypeReference parameterType = param.ParameterType;
			GenericParameter genericParameter = parameterType as GenericParameter;
			//if (parameterType is GenericInstanceType)
			//{
			//    return ResolveParameterGenericInstanceType(parameterType as GenericInstanceType);
			//}
			bool isByRef = false;
			bool isArray = false;

			if (parameterType.IsByReference)
			{
				genericParameter = parameterType.GetElementType() as GenericParameter;
				isByRef = true;
			}
			if (parameterType.IsArray)
			{
				genericParameter = parameterType.GetElementType() as GenericParameter;
				isArray = true;
			}

			if (genericParameter == null)
			{
				return parameterType;
			}
			int index = genericParameter.Position;
			if (genericParameter.Owner is MethodReference && method.IsGenericInstance)
			{
				GenericInstanceMethod generic = method as GenericInstanceMethod;
				if (index >= 0 && index < generic.GenericArguments.Count)
				{
					parameterType = generic.GenericArguments[index];
					if (generic.PostionToArgument.ContainsKey(index))
					{
						parameterType = generic.PostionToArgument[index];
					}
				}
			}
			else if (genericParameter.Owner is TypeReference && method.DeclaringType.IsGenericInstance)
			{
				GenericInstanceType generic = method.DeclaringType as GenericInstanceType;
				if (index >= 0 && index < generic.GenericArguments.Count)
				{
					parameterType = generic.GenericArguments[index];
					if (generic.PostionToArgument.ContainsKey(index))
					{
						parameterType = generic.PostionToArgument[index];
					}
				}
			}
			if (isByRef)
			{
				return new ByReferenceType(parameterType);
			}
			if (isArray)
			{
				return new ArrayType(parameterType);
			}
			return parameterType;
		}
Beispiel #37
0
        /// <summary>
        /// Emits the IL that calculates a hash code from a given service type.
        /// </summary>
        /// <param name="module">The module that holds the target type.</param>
        /// <param name="body">The body of the GetServiceHashCode method.</param>
        /// <param name="il">The <see cref="ILProcessor"/> that will be used to emit the instructions.</param>
        /// <param name="getHashCodeMethod">The <see cref="Object.GetHashCode"/> method.</param>
        /// <returns>The variable that holds the hash code.</returns>
        private static VariableDefinition EmitGetServiceTypeHashCode(ModuleDefinition module, Mono.Cecil.Cil.MethodBody body, ILProcessor il, MethodReference getHashCodeMethod)
        {
            // Get the hash code for the service type
            var hashVariable = AddLocals(module, body);

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Callvirt, getHashCodeMethod);
            il.Emit(OpCodes.Stloc, hashVariable);

            return(hashVariable);
        }
Beispiel #38
0
 public Instruction Emit(OpCode opcode, MethodReference method)
 {
     var instruction = Create (opcode, method);
     Append (instruction);
     return instruction;
 }
		private static EventDefinition GetMethodDeclaringEvent(MethodReference method)
		{
			if (method == null)
			{
				return null;
			}

			TypeDefinition type = method.DeclaringType.Resolve();
			if (type != null)
			{
				foreach (EventDefinition @event in type.Events)
				{
					if ((@event.AddMethod != null && @event.AddMethod.HasSameSignatureWith(method)) ||
						(@event.RemoveMethod != null && @event.RemoveMethod.HasSameSignatureWith(method)))
					{
						return @event;
					}
				}
			}

			return null;
		}
Beispiel #40
0
 /// <summary>
 /// Rewrites the declaring <see cref="TypeReference"/> of the specified <see cref="MethodReference"/>.
 /// </summary>
 /// <param name="method">The method with the declaring type to rewrite.</param>
 /// <returns>The rewritten declaring type, or the original if it was not changed.</returns>
 protected virtual TypeReference RewriteDeclaringTypeReference(MethodReference method) => method.DeclaringType;
 public MethodReference ImportMethodReference(MethodReference method, ImportContext context)
 {
     return method;
 }
Beispiel #42
0
        /// <summary>
        /// Rewrites the specified <see cref="MethodReference"/>.
        /// </summary>
        /// <param name="method">The method reference to rewrite.</param>
        /// <param name="module">The module definition that is being visited.</param>
        /// <returns>The rewritten method, or the original if it was not changed.</returns>
        protected MethodReference RewriteMethodReference(MethodReference method, ModuleDefinition module)
        {
            MethodReference result = method;

            TypeReference declaringType = this.RewriteDeclaringTypeReference(method);

            if (method.DeclaringType == declaringType)
            {
                // We are not rewriting this method.
                return(result);
            }

            MethodDefinition resolvedMethod        = Resolve(method);
            TypeDefinition   resolvedDeclaringType = Resolve(declaringType);

            // This is an extra initial parameter that we have when converting an instance to a static method.
            // For example, `task.GetAwaiter()` is converted to `ControlledTask.GetAwaiter(task)`.
            ParameterDefinition instanceParameter = null;
            MethodDefinition    match             = FindMatchingMethodInDeclaringType(resolvedMethod, resolvedDeclaringType);

            if (match != null)
            {
                result = module.ImportReference(match);
                if (resolvedMethod.Parameters.Count != match.Parameters.Count)
                {
                    // We are converting from an instance method to a static method, so store the instance parameter.
                    instanceParameter = result.Parameters[0];
                }
            }

            TypeReference returnType = this.RewriteTypeReference(method.ReturnType);

            // Instantiate the method reference to set its generic arguments and parameters, if any.
            result = new MethodReference(result.Name, returnType, declaringType)
            {
                HasThis           = result.HasThis,
                ExplicitThis      = result.ExplicitThis,
                CallingConvention = result.CallingConvention
            };

            if (resolvedMethod.HasGenericParameters)
            {
                // We need to instantiate the generic method.
                GenericInstanceMethod genericMethodInstance = new GenericInstanceMethod(result);

                var genericArgs      = new List <TypeReference>();
                int genericArgOffset = 0;

                if (declaringType is GenericInstanceType genericDeclaringType)
                {
                    // Populate the generic arguments with the generic declaring type arguments.
                    genericArgs.AddRange(genericDeclaringType.GenericArguments);
                    genericArgOffset = genericDeclaringType.GenericArguments.Count;
                }

                if (method is GenericInstanceMethod genericInstanceMethod)
                {
                    // Populate the generic arguments with the generic instance method arguments.
                    genericArgs.AddRange(genericInstanceMethod.GenericArguments);
                }

                for (int i = 0; i < resolvedMethod.GenericParameters.Count; i++)
                {
                    var p = resolvedMethod.GenericParameters[i];
                    var j = p.Position + genericArgOffset;
                    if (j > genericArgs.Count)
                    {
                        throw new InvalidOperationException(string.Format("Not enough generic arguments to instantiate method {0}", method));
                    }

                    GenericParameter parameter = new GenericParameter(p.Name, genericMethodInstance);
                    result.GenericParameters.Add(parameter);
                    genericMethodInstance.GenericParameters.Add(parameter);
                    genericMethodInstance.GenericArguments.Add(this.RewriteTypeReference(genericArgs[j]));
                }

                result = genericMethodInstance;
            }

            // Set the instance parameter of the method, if any.
            if (instanceParameter != null)
            {
                result.Parameters.Add(instanceParameter);
            }

            // Set the remaining parameters of the method, if any.
            foreach (var parameter in method.Parameters)
            {
                result.Parameters.Add(this.RewriteParameterDefinition(parameter));
            }

            return(module.ImportReference(result));
        }
Beispiel #43
0
        private void ReadMethodReferences(BinaryReader reader)
        {
            reader.PreserveCurrentPosition(header.MethodReferencesOffset, () =>
            {
                for (int i = 0; i < header.MethodReferencesSize; i++)
                {
                    int classIndex = reader.ReadUInt16();
                    int prototypeIndex = reader.ReadUInt16();
                    int nameIndex = reader.ReadInt32();

                    var mref = new MethodReference();
                    mref.Owner = (CompositeType) typeReferences[classIndex];
                    // Clone the prototype so we can annotate & update it easily
                    mref.Prototype = prototypes[prototypeIndex].Clone();
                    mref.Name = strings[nameIndex];

                    methodReferences.Add(mref);
                }
            });
        }
Beispiel #44
0
 public MethodReference ImportReference(MethodReference methRef)
 {
     return(ModelTypeDef.Module.ImportReference(methRef));
 }
Beispiel #45
0
 public MethodReference Import(MethodReference meth)
 {
     return m_helper == null ? meth : m_helper.ImportMethodReference (meth, this);
 }
Beispiel #46
0
 public MethodReference ImportReference(MethodReference methRef, IGenericParameterProvider context)
 {
     return(ModelTypeDef.Module.ImportReference(methRef, context));
 }
 //^ [NotDelayed]
 internal MethodRefSignatureConverter(
   PEFileToObjectModel peFileToObjectModel,
   MethodReference moduleMethodRef,
   MemoryReader signatureMemoryReader
 )
   : base(peFileToObjectModel, signatureMemoryReader, moduleMethodRef) {
   //^ this.ReturnCustomModifiers = TypeCache.EmptyCustomModifierArray;
   this.RequiredParameters = TypeCache.EmptyParameterInfoArray;
   this.VarArgParameters = TypeCache.EmptyParameterInfoArray;
   //^ base;
   //^ this.SignatureMemoryReader = signatureMemoryReader; //TODO: Spec# bug. This assignment should not be necessary.
   //  TODO: Check minimum required size of the signature...
   byte firstByte = this.SignatureMemoryReader.ReadByte();
   if (SignatureHeader.IsGeneric(firstByte)) {
     this.GenericParamCount = (ushort)this.SignatureMemoryReader.ReadCompressedUInt32();
   }
   int paramCount = this.SignatureMemoryReader.ReadCompressedUInt32();
   bool dummyPinned;
   this.ReturnCustomModifiers = this.GetCustomModifiers(out dummyPinned);
   byte retByte = this.SignatureMemoryReader.PeekByte(0);
   if (retByte == ElementType.Void) {
     this.ReturnTypeReference = peFileToObjectModel.SystemVoid;
     this.SignatureMemoryReader.SkipBytes(1);
   } else if (retByte == ElementType.TypedReference) {
     this.ReturnTypeReference = peFileToObjectModel.SystemTypedReference;
     this.SignatureMemoryReader.SkipBytes(1);
   } else {
     if (retByte == ElementType.ByReference) {
       this.IsReturnByReference = true;
       this.SignatureMemoryReader.SkipBytes(1);
     }
     this.ReturnTypeReference = this.GetTypeReference();
   }
   if (paramCount > 0) {
     IModuleParameterTypeInformation[] reqModuleParamArr = this.GetModuleParameterTypeInformations(moduleMethodRef, paramCount);
     if (reqModuleParamArr.Length > 0)
       this.RequiredParameters = new EnumerableArrayWrapper<IModuleParameterTypeInformation, IParameterTypeInformation>(reqModuleParamArr, Dummy.ParameterTypeInformation);
     IModuleParameterTypeInformation[] varArgModuleParamArr = this.GetModuleParameterTypeInformations(moduleMethodRef, paramCount - reqModuleParamArr.Length);
     if (varArgModuleParamArr.Length > 0)
       this.VarArgParameters = new EnumerableArrayWrapper<IModuleParameterTypeInformation, IParameterTypeInformation>(varArgModuleParamArr, Dummy.ParameterTypeInformation);
   }
 }
Beispiel #48
0
        /// <summary>
        /// Gets the index of a method in the corresponding VTable.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="method">The method.</param>
        /// <returns>The index inside the table of the type.</returns>
        public int GetMethodIndex(TypeDefinition type, MethodReference method)
        {
            string name = NameHelper.CreateShortMethodName(method);

            return(mNameTable[type][name]);
        }
    //^ invariant this.PEFileReader.MethodSpecTable.NumberOfRows >= 1 ==> this.MethodSpecHashtable != null;

    internal ITypeMemberReference/*?*/ GetModuleMemberReferenceAtRowWorker(
      MetadataObject owningObject,
      uint memberRefRowId
    ) {
      if (memberRefRowId == 0 || memberRefRowId > this.PEFileReader.MemberRefTable.NumberOfRows) {
        return null;
      }
      if (this.ModuleMemberReferenceArray[memberRefRowId] == null) {
        MemberRefRow memberRefRow = this.PEFileReader.MemberRefTable[memberRefRowId];
        uint classTokenType = memberRefRow.Class & TokenTypeIds.TokenTypeMask;
        uint classRowId = memberRefRow.Class & TokenTypeIds.RIDMask;
        ITypeReference/*?*/ parentTypeReference = null;
        switch (classTokenType) {
          case TokenTypeIds.TypeDef:
            parentTypeReference = this.GetTypeDefinitionAtRow(classRowId);
            break;
          case TokenTypeIds.TypeRef:
            parentTypeReference = this.GetTypeRefReferenceAtRow(classRowId);
            break;
          case TokenTypeIds.TypeSpec:
            parentTypeReference = this.GetTypeSpecReferenceAtRow(owningObject, classRowId).UnderlyingModuleTypeReference;
            break;
          case TokenTypeIds.MethodDef: {
              var/*?*/ methodDef = this.GetMethodDefAtRow(classRowId);
              if (methodDef == null) {
                //  Error...
                return null;
              }
              parentTypeReference = methodDef.ContainingType;
              break;
            }
          case TokenTypeIds.ModuleRef: {
              ModuleReference/*?*/ modRef = this.GetModuleReferenceAt(classRowId);
              if (modRef == null) {
                //  MDError
                return null;
              }
              var module = this.ResolveModuleRefReference(modRef) as Module;
              if (module == null) {
                //TODO: MDError...
                return null;
              }
              PEFileToObjectModel modulePEFileToObjectModel = module.PEFileToObjectModel;
              parentTypeReference = modulePEFileToObjectModel._Module_;
              break;
            }
          default: {
              //  MDError...
              return null;
            }
        }
        if (parentTypeReference == null) {
          //  Error...
          return null;
        }
        MemberReference retModuleMemberReference;
        IName name = this.GetNameFromOffset(memberRefRow.Name);
        byte firstByte = this.PEFileReader.BlobStream.GetByteAt(memberRefRow.Signature, 0);
        var genericTypeInstance = parentTypeReference as IGenericTypeInstanceReference;
        var specializedNestedTypeReference = parentTypeReference as ISpecializedNestedTypeReference;
        if (SignatureHeader.IsFieldSignature(firstByte)) {
          if (genericTypeInstance != null || specializedNestedTypeReference != null) {
            //The same memberRef token can be shared by distinct instance references, therefore special caching is required
            FieldReference unspecializedFieldReference = this.UnspecializedMemberReferenceArray[memberRefRowId] as FieldReference;
            if (unspecializedFieldReference == null) {
              unspecializedFieldReference = new FieldReference(this, memberRefRowId, TypeCache.Unspecialize(parentTypeReference), name);
              this.UnspecializedMemberReferenceArray[memberRefRowId] = unspecializedFieldReference;
            }
            uint key1 = parentTypeReference.InternedKey;
            uint key2 = unspecializedFieldReference.InternedKey;
            var specializedField = this.SpecializedFieldHashtable.Find(key1, key2);
            if (specializedField == null) {
              specializedField = new SpecializedFieldReference(parentTypeReference, unspecializedFieldReference, this.InternFactory);
              this.SpecializedFieldHashtable.Add(key1, key2, specializedField);
            }
            return specializedField;
          } else {
            retModuleMemberReference = new FieldReference(this, memberRefRowId, parentTypeReference, name);
          }
        } else if (SignatureHeader.IsMethodSignature(firstByte)) {
          if (genericTypeInstance != null || specializedNestedTypeReference != null) {
            //The same memberRef token can be shared by distinct instance references, therefore special caching is required
            MethodReference unspecializedMethodReference = this.UnspecializedMemberReferenceArray[memberRefRowId] as MethodReference;
            if (unspecializedMethodReference == null) {
              unspecializedMethodReference = new MethodReference(this, memberRefRowId, TypeCache.Unspecialize(parentTypeReference), name, firstByte);
              this.UnspecializedMemberReferenceArray[memberRefRowId] = unspecializedMethodReference;
            }
            uint key1 = parentTypeReference.InternedKey;
            uint key2 = unspecializedMethodReference.InternedKey;
            var specializedMethod = this.SpecializedMethodHashtable.Find(key1, key2);
            if (specializedMethod == null) {
              specializedMethod = new SpecializedMethodReference(parentTypeReference, unspecializedMethodReference, this.InternFactory);
              this.SpecializedMethodHashtable.Add(key1, key2, specializedMethod);
            }
            return specializedMethod;
          } else {
            retModuleMemberReference = new MethodReference(this, memberRefRowId, parentTypeReference, name, firstByte);
          }
        } else {
          //  MD Error
          return null;
        }
        this.ModuleMemberReferenceArray[memberRefRowId] = retModuleMemberReference;
      }
      MemberReference/*?*/ ret = this.ModuleMemberReferenceArray[memberRefRowId];
      return ret;
    }
Beispiel #50
0
 public CallMethodDescription(Instruction instruction)
 {
     this.instruction = instruction;
     targetMethod     = (MethodReference)instruction.Operand;
 }
 internal int GetMethodRefGenericParameterCount(
   MethodReference moduleMethodReference
 ) {
   uint signatureBlobOffset = this.PEFileReader.MemberRefTable.GetSignature(moduleMethodReference.MemberRefRowId);
   //  TODO: error checking offset in range
   MemoryBlock signatureMemoryBlock = this.PEFileReader.BlobStream.GetMemoryBlockAt(signatureBlobOffset);
   //  TODO: Error checking enough space in signature memoryBlock.
   MemoryReader memoryReader = new MemoryReader(signatureMemoryBlock);
   //  TODO: Check if this is really method signature there.
   byte firstByte = memoryReader.ReadByte();
   if (SignatureHeader.IsGeneric(firstByte)) {
     return memoryReader.ReadCompressedUInt32();
   }
   return 0;
 }
 protected virtual string GetConstructorName(MethodReference constructor)
 {
     return(constructor.Name);
 }
Beispiel #53
0
 public void Emit(OpCode opcode, MethodReference method)
 {
     Append (Create (opcode, method));
 }
 protected virtual string GetMethodName(MethodReference method)
 {
     return(method.Name);
 }
Beispiel #55
0
 public FluentEmitter Call(MethodReference m)
 {
     return Emit(OpCodes.Call, m);
 }
Beispiel #56
0
 public Instruction CreateInstruction(OpCode opCode, MethodReference value)
 {
     return(Processor.Create(opCode, value));
 }
    /// <summary>
    /// Returns a reference to the closure method. If the method is generic, the reference is to an instantiation, 
    /// using the generic parameters of the current class as arguments.
    /// </summary>
    private IMethodReference CreateClosureMethod(AnonymousDelegate anonymousDelegate) {
      bool isPeerMethod = this.helperMembers != null && !this.anonymousDelegatesThatCaptureLocalsOrParameters.ContainsKey(anonymousDelegate);
      bool isStaticMethod = isPeerMethod && !this.anonymousDelegatesThatCaptureThis.ContainsKey(anonymousDelegate);
      var body = new SourceMethodBody(this.host, this.sourceLocationProvider) {
        Block = anonymousDelegate.Body,
        LocalsAreZeroed = true
      };
      var counter = isPeerMethod ? this.helperMembers.Count : this.anonymousDelegateCounter++;
      var prefix = "<"+this.method.Name.Value;
      prefix += isPeerMethod ? ">p__" : ">b__";
      var method = new MethodDefinition() {
        ContainingTypeDefinition = isPeerMethod ? this.method.ContainingTypeDefinition : this.currentClosureClass,
        Name = this.host.NameTable.GetNameFor(prefix+counter),
        Visibility = isPeerMethod ? TypeMemberVisibility.Private : TypeMemberVisibility.Public,
        Body = body,
        CallingConvention = isStaticMethod ? CallingConvention.Default : CallingConvention.HasThis,
        InternFactory = this.host.InternFactory,
        Parameters = anonymousDelegate.Parameters,
        Type = anonymousDelegate.ReturnType,
        IsCil = true,
        IsStatic = isStaticMethod,
        IsHiddenBySignature = true,
      };
      body.MethodDefinition = method;
      if (method.Parameters != null) {
        foreach (ParameterDefinition parameterDefinition in method.Parameters)
          parameterDefinition.ContainingSignature = method;
      }

      if (isPeerMethod) {
        this.helperMembers.Add(method);
        if (this.method.IsGeneric) this.MakeDelegateMethodGeneric(method);
        method.Attributes = new List<ICustomAttribute>(1);
        method.Attributes.Add(this.compilerGenerated);
      } else {
        this.currentClosureClass.Methods.Add(method);
        this.isInsideAnonymousMethod = true;
        this.RewriteChildren(method);
        this.isInsideAnonymousMethod = false;
      }

      IMethodReference methodReference = method;
      ITypeReference containingTypeDefinitionInstance = method.ContainingTypeDefinition;
      if (isPeerMethod)
        containingTypeDefinitionInstance = NamedTypeDefinition.SelfInstance((INamedTypeDefinition)method.ContainingTypeDefinition, this.host.InternFactory);
      if ((isPeerMethod && method.ContainingTypeDefinition != containingTypeDefinitionInstance) || 
          (!isPeerMethod && this.currentClosureClass != this.currentClosureInstance)) {
        methodReference = new MethodReference() {
          CallingConvention = method.CallingConvention,
          ContainingType = isPeerMethod ? containingTypeDefinitionInstance : this.currentClosureInstance,
          GenericParameterCount = method.GenericParameterCount,
          InternFactory = this.host.InternFactory,
          Name = method.Name,
          Parameters = methodReference.ParameterCount == 0 ? null : new List<IParameterTypeInformation>(methodReference.Parameters),
          Type = method.Type,
        };
      }

      if (!method.IsGeneric) return methodReference;
      return new GenericMethodInstanceReference() {
        CallingConvention = method.CallingConvention,
        ContainingType = method.ContainingTypeDefinition,
        GenericArguments = new List<ITypeReference>(IteratorHelper.GetConversionEnumerable<IGenericMethodParameter, ITypeReference>(method.GenericParameters)),
        GenericMethod = methodReference,
        InternFactory = this.host.InternFactory,
        Name = method.Name,
        Parameters = methodReference.ParameterCount == 0 ? null : new List<IParameterTypeInformation>(methodReference.Parameters),
        Type = method.Type,
      };
    }
 public void AddInflatedMethod(MethodReference method)
 {
     this._inflatedMethods.Add(method);
 }
Beispiel #59
0
    SecurityCustomAttribute/*?*/ ReadSecurityAttribute(SecurityAttribute securityAttribute) {
      string/*?*/ typeNameStr = this.GetSerializedString();
      if (typeNameStr == null)
        return null;
      ITypeReference/*?*/ moduleTypeReference = this.PEFileToObjectModel.GetSerializedTypeNameAsTypeReference(typeNameStr);
      if (moduleTypeReference == null)
        return null;
      IMethodReference ctorReference = Dummy.MethodReference;
      ITypeDefinition attributeType = moduleTypeReference.ResolvedType;
      if (!(attributeType is Dummy)) {
        foreach (ITypeDefinitionMember member in attributeType.GetMembersNamed(this.PEFileToObjectModel.NameTable.Ctor, false)) {
          IMethodDefinition/*?*/ method = member as IMethodDefinition;
          if (method == null) continue;
          if (!IteratorHelper.EnumerableHasLength(method.Parameters, 1)) continue;
          //TODO: check that parameter has the right type
          ctorReference = method;
          break;
        }
      } else {
        int ctorKey = this.PEFileToObjectModel.NameTable.Ctor.UniqueKey;
        foreach (ITypeMemberReference mref in this.PEFileToObjectModel.GetMemberReferences()) {
          IMethodReference/*?*/ methRef = mref as IMethodReference;
          if (methRef == null) continue;
          if (methRef.ContainingType.InternedKey != moduleTypeReference.InternedKey) continue;
          if (methRef.Name.UniqueKey != ctorKey) continue;
          if (!IteratorHelper.EnumerableHasLength(methRef.Parameters, 1)) continue;
          //TODO: check that parameter has the right type
          ctorReference = methRef;
          break;
        }
      }
      if (ctorReference is Dummy) {
        ctorReference = new MethodReference(this.PEFileToObjectModel.ModuleReader.metadataReaderHost, moduleTypeReference,
          CallingConvention.Default|CallingConvention.HasThis, this.PEFileToObjectModel.PlatformType.SystemVoid,
          this.PEFileToObjectModel.NameTable.Ctor, 0, this.PEFileToObjectModel.PlatformType.SystemSecurityPermissionsSecurityAction);
      }

      this.SignatureMemoryReader.ReadCompressedUInt32(); //  BlobSize...
      int numOfNamedArgs = this.SignatureMemoryReader.ReadCompressedUInt32();
      FieldOrPropertyNamedArgumentExpression[]/*?*/ namedArgumentArray = null;
      if (numOfNamedArgs > 0) {
        namedArgumentArray = new FieldOrPropertyNamedArgumentExpression[numOfNamedArgs];
        for (int i = 0; i < numOfNamedArgs; ++i) {
          bool isField = this.SignatureMemoryReader.ReadByte() == SerializationType.Field;
          ITypeReference/*?*/ memberType = this.GetFieldOrPropType();
          if (memberType == null)
            return null;
          string/*?*/ memberStr = this.GetSerializedString();
          if (memberStr == null)
            return null;
          IName memberName = this.PEFileToObjectModel.NameTable.GetNameFor(memberStr);
          ExpressionBase/*?*/ value = this.ReadSerializedValue(memberType);
          if (value == null)
            return null;
          namedArgumentArray[i] = new FieldOrPropertyNamedArgumentExpression(memberName, moduleTypeReference, isField, memberType, value);
        }
      }
      return new SecurityCustomAttribute(securityAttribute, ctorReference, namedArgumentArray);
    }
Beispiel #60
0
 /// <summary>
 /// Returns a method on the type similar to the specified method.
 /// </summary>
 /// <param name="containingType">The type on which to resolve the method.</param>
 /// <param name="similarMethod">A reference to the similar method.</param>
 /// <param name="altName">Optionally, find a method similar to <paramref name="similarMethod"/>, but with this name instead.</param>
 /// <returns></returns>
 public static MethodDefinition GetMethodLike(this TypeDefinition containingType, MethodReference similarMethod, string altName = null)
 {
     Console.WriteLine("Method like");
     return
         (containingType.GetMethods(altName ?? similarMethod.Name, similarMethod.Parameters.Select(x => x.ParameterType),
                                    similarMethod.GenericParameters.Count, similarMethod.ReturnType)
          .SingleOrDefault());
 }