Ejemplo n.º 1
0
 public override void Generate(ILProcessor processor)
 {
     // Now add the IL that creates the delegate.
     processor.Append(Instruction.Create(OpCodes.Nop));
     processor.Append(Instruction.Create(OpCodes.Ldarg_0));
     processor.Append(Instruction.Create(OpCodes.Ldftn, this.m_Target));
     //processor.Append(Instruction.Create(OpCodes.Ldnull));
     processor.Append(Instruction.Create(OpCodes.Newobj, this.m_Constructor));
     processor.Append(Instruction.Create(OpCodes.Stloc, this.m_Storage));
 }
Ejemplo n.º 2
0
        public override void Generate(ILProcessor processor)
        {
            // Load the arguments.
            foreach (VariableDefinition v in m_Parameters)
            {
                processor.Append(Instruction.Create(OpCodes.Ldloc, v));
            }

            // Call the delegate.
            processor.Append(Instruction.Create(OpCodes.Call, this.m_Target));

            // Handle the return type.
            if (this.m_ReturnType.FullName == this.m_Target.Module.Import(typeof(void)).FullName)
            {
                // Return value is void.  Discard any result and return.
                processor.Append(Instruction.Create(OpCodes.Pop));
            }
            else if (this.m_ReturnType.IsValueType || this.m_ReturnType.IsGenericParameter)
            {
                // Return value is value type (not reference).  Unbox and return it.
                processor.Append(Instruction.Create(OpCodes.Unbox_Any, this.m_ReturnType));
                processor.Append(Instruction.Create(OpCodes.Stloc, this.Result));
            }
            else
            {
                // Return value is reference type.  Cast it and return it.
                processor.Append(Instruction.Create(OpCodes.Isinst, this.m_ReturnType));
                processor.Append(Instruction.Create(OpCodes.Stloc, this.Result));
            }
        }
Ejemplo n.º 3
0
        private void FillResetWatchdog(ILProcessor ilProc)
        {
            Instruction ldarg = Instruction.Create(OpCodes.Ldarg_0);

            FieldReference targetField = new FieldReference("_computerTarget", GetCommonTingComputer(), _target);
            Instruction targetToStack = Instruction.Create(OpCodes.Ldfld, targetField);

            MethodReference injectoid = _source.Methods.First(o => o.Name == "ResetWatchdog");
            injectoid = _target.Module.Import(injectoid);
            Instruction callInjectoid = Instruction.Create(OpCodes.Call, injectoid);

            Instruction ret = Instruction.Create(OpCodes.Ret);

            ilProc.Append(ldarg);
            ilProc.Append(targetToStack);
            ilProc.Append(callInjectoid);
            ilProc.Append(ret);
        }
Ejemplo n.º 4
0
            protected override void ImplementProceed(MethodDefinition methodInfo, MethodBody methodBody, ILProcessor il, FieldReference methodInfoField, MethodReference proceed, Action<ILProcessor> emitProceedTarget, MethodReference proceedTargetMethod, OpCode proceedOpCode)
            {
                // If T is an interface, then we want to check if target is null; if so, we want to just return the default value
                var targetNotNull = il.Create(OpCodes.Nop);
                EmitProxyFromProceed(il);
                il.Emit(OpCodes.Ldfld, ClassWeaver.Target);  // Load "target" from "this"
                il.Emit(OpCodes.Brtrue, targetNotNull);      // If target is not null, jump below
                CecilExtensions.CreateDefaultMethodImplementation(methodBody.Method, il);

                il.Append(targetNotNull);                    // Mark where the previous branch instruction should jump to                        

                base.ImplementProceed(methodInfo, methodBody, il, methodInfoField, proceed, emitProceedTarget, proceedTargetMethod, proceedOpCode);
            }
Ejemplo n.º 5
0
        /// <summary>
        /// Emits the instructions that call <see cref="IInitialize.Initialize"/> on a given service instance.
        /// </summary>
        /// <param name="il"></param>
        /// <param name="module">The host module.</param>
        /// <param name="serviceInstance">The local variable that points to the current service instance.</param>
        public void Initialize(ILProcessor il, ModuleDefinition module, VariableDefinition serviceInstance)
        {
            var body = il.Body;
            var method = body.Method;
            var declaringType = method.DeclaringType;

            var targetField = GetTargetField(declaringType);
            if (targetField == null)
                return;

            var initializeType = module.ImportType<IInitialize>();

            il.Emit(OpCodes.Ldloc, serviceInstance);
            il.Emit(OpCodes.Isinst, initializeType);

            var initializeMethod = module.ImportMethod<IInitialize>("Initialize");
            var skipInitializationCall = il.Create(OpCodes.Nop);
            il.Emit(OpCodes.Brfalse, skipInitializationCall);

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, targetField);
            GetServiceHash(il, module, serviceInstance);

            var containsMethod = module.ImportMethod<Dictionary<int, int>>("ContainsKey");
            il.Emit(OpCodes.Callvirt, containsMethod);
            il.Emit(OpCodes.Brtrue, skipInitializationCall);

            // if (!__initializedServices.ContainsKey(currentService.GetHashCode()) {
            il.Emit(OpCodes.Ldloc, serviceInstance);
            il.Emit(OpCodes.Isinst, initializeType);
            il.Emit(OpCodes.Ldarg_0);

            il.Emit(OpCodes.Callvirt, initializeMethod);

            // __initializedServices.Add(hashCode, 0);
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, targetField);
            GetServiceHash(il, module, serviceInstance);
            il.Emit(OpCodes.Ldc_I4_1);

            var addMethod = module.ImportMethod<Dictionary<int, int>>("Add");
            il.Emit(OpCodes.Callvirt, addMethod);

            il.Append(skipInitializationCall);
        }
Ejemplo n.º 6
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
                {
                    var targetNotNull = il.Create(OpCodes.Nop);
                    EmitProxyFromProceed(il);
                    il.Emit(OpCodes.Ldfld, target);              // Load "target" from "this"
                    il.Emit(OpCodes.Brtrue, targetNotNull);      // If target is not null, jump below

                    base.ImplementProceed(methodInfo, methodBody, il, methodInfoField, proceed, _ => EmitProxyFromProceed(il), callBaseMethod, OpCodes.Call);

                    il.Append(targetNotNull);                    // Mark where the previous branch instruction should jump to                        
                
                    base.ImplementProceed(methodInfo, methodBody, il, methodInfoField, proceed, emitProceedTarget, proceedTargetMethod, proceedOpCode);
                }
            }
Ejemplo n.º 7
0
 /// <summary>
 /// Emits the cpblk method, supporting x86 and x64 platform.
 /// </summary>
 /// <param name="method">The method.</param>
 /// <param name="gen">The gen.</param>
 private void EmitCpblk(MethodDefinition method, ILProcessor gen)
 {
     var cpblk = gen.Create(OpCodes.Cpblk);
     //gen.Emit(OpCodes.Sizeof, voidPointerType);
     //gen.Emit(OpCodes.Ldc_I4_8);
     //gen.Emit(OpCodes.Bne_Un_S, cpblk);
     gen.Emit(OpCodes.Unaligned, (byte)1);       // unaligned to 1
     gen.Append(cpblk);
     
 }
Ejemplo n.º 8
0
        static int EmitParameters(MethodDefinition method, MethodBody body, ILProcessor il)
        {
            int i;
            for (i = 0; i < method.Parameters.Count; i++)
            {
                var p = method.Module.Import(method.Parameters[i].ParameterType);
                il.Emit(OpCodes.Ldarg, i);

                if (p.Name == "StringBuilder")
                {
                    // void GetShaderInfoLog(..., StringBuilder foo)
                    // IntPtr foo_sb_ptr;
                    // try {
                    //  foo_sb_ptr = Marshal.AllocHGlobal(sb.Capacity + 1);
                    //  glGetShaderInfoLog(..., foo_sb_ptr);
                    //  MarshalPtrToStringBuilder(foo_sb_ptr, sb);
                    // }
                    // finally {
                    //  Marshal.FreeHGlobal(sb_ptr);
                    // }

                    // Make sure we have imported StringBuilder::Capacity and Marshal::AllocHGlobal
                    var sb_get_capacity = method.Module.Import(TypeStringBuilder.Methods.First(m => m.Name == "get_Capacity"));
                    var alloc_hglobal = method.Module.Import(TypeMarshal.Methods.First(m => m.Name == "AllocHGlobal"));

                    // IntPtr ptr;
                    var variable_name = p.Name + " _sb_ptr";
                    body.Variables.Add(new VariableDefinition(variable_name, TypeIntPtr));
                    int index = body.Variables.Count - 1;

                    // ptr = Marshal.AllocHGlobal(sb.Capacity + 1);
                    il.Emit(OpCodes.Callvirt, sb_get_capacity);
                    il.Emit(OpCodes.Call, alloc_hglobal);
                    il.Emit(OpCodes.Stloc, index);
                    il.Emit(OpCodes.Ldloc, index);

                    // We'll emit the try-finally block in the epilogue implementation,
                    // because we haven't yet emitted all necessary instructions here.
                }
                else if (p.Name == "String" && !p.IsArray)
                {
                    EmitStringParameter(method, p, body, il);
                }
                else if (p.IsByReference)
                {
                    body.Variables.Add(new VariableDefinition(new PinnedType(p)));
                    var index = body.Variables.Count - 1;
                    il.Emit(OpCodes.Stloc, index);
                    il.Emit(OpCodes.Ldloc, index);
                    il.Emit(OpCodes.Conv_I);
                }
                else if (p.IsArray)
                {
                    if (p.Name != method.Module.Import(typeof(string[])).Name)
                    {
                        // .Net treats 1d arrays differently than higher rank arrays.
                        // 1d arrays are directly supported by instructions such as ldlen and ldelema.
                        // Higher rank arrays must be accessed through System.Array methods such as get_Length.
                        // 1d array:
                        //    check array is not null
                        //    check ldlen array > 0
                        //    ldc.i4.0
                        //    ldelema
                        // 2d array:
                        //    check array is not null
                        //    check array.get_Length() > 0
                        //    ldc.i4.0
                        //    ldc.i4.0
                        //    call instance T& T[0..., 0...]::Address(int32, int32)
                        // Mono treats everything as a 1d array.
                        // Interestingly, the .Net approach works on both Mono and .Net.
                        // The Mono approach fails when using high-rank arrays on .Net.
                        // We should report a bug to http://bugzilla.xamarin.com

                        // Pin the array and pass the address
                        // of its first element.
                        var array = (ArrayType)p;
                        var element_type = p.GetElementType();
                        body.Variables.Add(new VariableDefinition(new PinnedType(new ByReferenceType(element_type))));
                        int pinned_index = body.Variables.Count - 1;

                        var empty = il.Create(OpCodes.Ldc_I4, 0);
                        var pin = il.Create(OpCodes.Ldarg, i);
                        var end = il.Create(OpCodes.Stloc, pinned_index);

                        // if (array == null) goto empty
                        il.Emit(OpCodes.Brfalse, empty);

                        // else if (array.Length != 0) goto pin
                        il.Emit(OpCodes.Ldarg, i);
                        if (array.Rank == 1)
                        {
                            il.Emit(OpCodes.Ldlen);
                            il.Emit(OpCodes.Conv_I4);
                        }
                        else
                        {
                            var get_length = method.Module.Import(
                                mscorlib.MainModule.GetType("System.Array").Methods.First(m => m.Name == "get_Length"));
                            il.Emit(OpCodes.Callvirt, get_length);
                        }
                        il.Emit(OpCodes.Brtrue, pin);

                        // empty: IntPtr ptr = IntPtr.Zero
                        il.Append(empty);
                        il.Emit(OpCodes.Conv_U);
                        il.Emit(OpCodes.Br, end);

                        // pin: &array[0]
                        il.Append(pin);
                        if (array.Rank == 1)
                        {
                            // 1d array (vector), address is taken by ldelema
                            il.Emit(OpCodes.Ldc_I4, 0);
                            il.Emit(OpCodes.Ldelema, element_type);
                        }
                        else
                        {
                            // 2d-3d array, address must be taken as follows:
                            // call instance T& T[0..., 0..., 0...]::Address(int, int, int)
                            ByReferenceType t_ref = array.ElementType.MakeByReferenceType();
                            MethodReference get_address = new MethodReference("Address", t_ref, array);
                            for (int r = 0; r < array.Rank; r++)
                            {
                                get_address.Parameters.Add(new ParameterDefinition(TypeInt32));
                            }
                            get_address.HasThis = true;

                            // emit the get_address call
                            for (int r = 0; r < array.Rank; r++)
                            {
                                il.Emit(OpCodes.Ldc_I4, 0);
                            }
                            il.Emit(OpCodes.Call, get_address);
                        }

                        // end: fixed (IntPtr ptr = &array[0])
                        il.Append(end);
                        il.Emit(OpCodes.Ldloc, pinned_index);
                        il.Emit(OpCodes.Conv_I);
                    }
                    else
                    {
                        EmitStringArrayParameter(method, p, body, il);
                    }
                }
            }
            return i;
        }
        /// <summary>
        /// Defines the instructions that create each service type in the <paramref name="serviceMap"/>.
        /// </summary>
        /// <param name="serviceMap">The service map that contains the list of application dependencies.</param>
        /// <param name="getInstanceMethod">The method that will be used to instantiate the service types.</param>
        /// <param name="jumpTargetField">The field that holds the dictionary with the switch table target instructions.</param>
        /// <param name="getServiceHash">The method that calculates the service hash code.</param>
        /// <param name="il">The <see cref="ILProcessor"/> that points to the body of the factory method.</param>
        private void DefineServices(IDictionary<IDependency, IImplementation> serviceMap, MethodDefinition getInstanceMethod, FieldDefinition jumpTargetField, MethodDefinition getServiceHash, ILProcessor il)
        {
            var endLabel = Instruction.Create(OpCodes.Nop);
            il.Append(endLabel);

            var body = il.Body;
            body.InitLocals = true;

            var method = body.Method;
            var returnValue = method.AddLocal<object>();
            var declaringType = method.DeclaringType;
            var module = declaringType.Module;

            var jumpTargets = new Dictionary<IDependency, Instruction>();
            foreach (var dependency in serviceMap.Keys)
            {
                jumpTargets[dependency] = il.Create(OpCodes.Nop);
            }

            var getItemMethod = module.ImportMethod<Dictionary<int, int>>("get_Item");
            var serviceHash = method.AddLocal<int>();
            var skipCreate = il.Create(OpCodes.Nop);

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, jumpTargetField);
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Ldarg_2);
            il.Emit(OpCodes.Call, getServiceHash);
            il.Emit(OpCodes.Stloc, serviceHash);

            var contains = module.ImportMethod<Dictionary<int, int>>("ContainsKey");
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, jumpTargetField);
            il.Emit(OpCodes.Ldloc, serviceHash);
            il.Emit(OpCodes.Callvirt, contains);
            il.Emit(OpCodes.Brfalse, skipCreate);

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, jumpTargetField);
            il.Emit(OpCodes.Ldloc, serviceHash);
            il.Emit(OpCodes.Callvirt, getItemMethod);

            var switchLabels = new List<Instruction>(jumpTargets.Values);
            var labels = switchLabels.ToArray();
            il.Emit(OpCodes.Switch, labels);
            il.Emit(OpCodes.Ldnull);
            il.Emit(OpCodes.Stloc, returnValue);
            il.Emit(OpCodes.Br, skipCreate);

            foreach (var dependency in serviceMap.Keys)
            {
                // Set the jump target
                var currentLabel = jumpTargets[dependency];
                il.Append(currentLabel);

                var serviceType = module.ImportType(dependency.ServiceType);

                // Emit the implementation
                var implementation = serviceMap[dependency];
                EmitService(getInstanceMethod, dependency, implementation, serviceMap);

                il.Emit(OpCodes.Stloc, returnValue);

                var serviceInstance = returnValue;

                // Call IInitialize.Initialize(this) on the current type
                if (_initializer != null)
                    _initializer.Initialize(il, module, serviceInstance);

                //il.Emit(OpCodes.Ldloc, returnValue);
                //il.Emit(OpCodes.Unbox_Any, serviceType);

                il.Emit(OpCodes.Br, endLabel);
            }

            il.Append(skipCreate);

            var getNextContainer = module.ImportMethod<IMicroContainer>("get_NextContainer");
            var otherContainer = method.AddLocal<IMicroContainer>();

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Callvirt, getNextContainer);
            il.Emit(OpCodes.Stloc, otherContainer);

            // if (otherContainer != null ) {
            var skipOtherContainerCall = il.Create(OpCodes.Nop);
            il.Emit(OpCodes.Ldloc, otherContainer);
            il.Emit(OpCodes.Brfalse, skipOtherContainerCall);

            // Prevent the container from calling itself
            il.Emit(OpCodes.Ldloc, otherContainer);
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ceq);
            il.Emit(OpCodes.Brtrue, skipOtherContainerCall);

            var otherGetInstanceMethod = module.ImportMethod<IMicroContainer>("GetInstance");

            // return otherContainer.GetInstance(type, key);

            il.Emit(OpCodes.Ldloc, otherContainer);
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Ldarg_2);
            il.Emit(OpCodes.Callvirt, otherGetInstanceMethod);
            il.Emit(OpCodes.Stloc, returnValue);
            il.Emit(OpCodes.Br, endLabel);
            // }

            il.Append(skipOtherContainerCall);

            il.Append(endLabel);
            il.Emit(OpCodes.Pop);
            il.Emit(OpCodes.Ldloc, returnValue);
        }
 private static void WriteMessageId(ILProcessor worker, int msgId)
 {
     worker.Append(worker.Create(OpCodes.Ldloc_0));
     worker.Append(worker.Create(OpCodes.Ldc_I4, msgId));
     worker.Append(worker.Create(OpCodes.Conv_U2));
     worker.Append(worker.Create(OpCodes.Callvirt, Weaver.NetworkWriterWriteInt16));
 }
 private static void WriteDirtyCheck(ILProcessor serWorker, bool reset)
 {
     Instruction target = serWorker.Create(OpCodes.Nop);
     serWorker.Append(serWorker.Create(OpCodes.Ldloc_0));
     serWorker.Append(serWorker.Create(OpCodes.Brtrue, target));
     serWorker.Append(serWorker.Create(OpCodes.Ldarg_1));
     serWorker.Append(serWorker.Create(OpCodes.Ldarg_0));
     serWorker.Append(serWorker.Create(OpCodes.Call, Weaver.NetworkBehaviourDirtyBitsReference));
     serWorker.Append(serWorker.Create(OpCodes.Callvirt, Weaver.NetworkWriterWritePacked32));
     if (reset)
     {
         serWorker.Append(serWorker.Create(OpCodes.Ldc_I4_1));
         serWorker.Append(serWorker.Create(OpCodes.Stloc_0));
     }
     serWorker.Append(target);
 }
 private void GenerateSyncListInitializer(ILProcessor awakeWorker, FieldReference fd, int index)
 {
     awakeWorker.Append(awakeWorker.Create(OpCodes.Ldarg_0));
     awakeWorker.Append(awakeWorker.Create(OpCodes.Ldfld, fd));
     awakeWorker.Append(awakeWorker.Create(OpCodes.Ldarg_0));
     awakeWorker.Append(awakeWorker.Create(OpCodes.Ldsfld, this.m_SyncListStaticFields[index]));
     GenericInstanceType baseType = (GenericInstanceType) fd.FieldType.Resolve().BaseType;
     baseType = (GenericInstanceType) Weaver.scriptDef.MainModule.ImportReference(baseType);
     TypeReference reference = baseType.GenericArguments[0];
     TypeReference[] arguments = new TypeReference[] { reference };
     MethodReference method = Helpers.MakeHostInstanceGeneric(Weaver.SyncListInitBehaviourReference, arguments);
     awakeWorker.Append(awakeWorker.Create(OpCodes.Callvirt, method));
     Weaver.scriptDef.MainModule.ImportReference(method);
 }
Ejemplo n.º 13
0
        static DebugVariables EmitDebugPrologue(MethodDefinition wrapper, ILProcessor il)
        {

            DebugVariables vars = null;
            if (il.Body.Method.Name != "GetError")
            {
                // Pull out the namespace name, method fullname will look 
                // something like "type namespace.class::method(type arg)"
                var module = il.Body.Method.FullName;
                module = module.Substring(module.IndexOf(' ') + 1);
                module = module.Substring(0, module.IndexOf("::"));
                module = module.Substring(0, module.LastIndexOf('.'));

                // Only works for Graphics modules due to hardcoded use of
                // OpenTK.Graphics.GraphicsContext
                if (module == "OpenTK.Graphics.OpenGL4" ||
                    module == "OpenTK.Graphics.OpenGL" ||
                    module == "OpenTK.Graphics.ES10" ||
                    module == "OpenTK.Graphics.ES11" ||
                    module == "OpenTK.Graphics.ES20" ||
                    module == "OpenTK.Graphics.ES30")
                {
                    var errorHelperType = wrapper.Module.GetType(module, "ErrorHelper");

                    if (errorHelperType != null)
                    {
                        vars = new DebugVariables();
                        vars.ErrorHelperType = errorHelperType;

                        // GraphicsContext type
                        var graphicsContext = wrapper.Module.Types.First(
                            type => type.FullName == "OpenTK.Graphics.GraphicsContext");

                        // IGraphicsContext type
                        var iGraphicsContext = wrapper.Module.Types.First(
                            type => type.FullName == "OpenTK.Graphics.IGraphicsContext");

                        // Get the constructor that takes a GraphicsContext parameter
                        var ctor = vars.ErrorHelperType.GetConstructors().FirstOrDefault(
                            c => c.Parameters.Count == 1 &&
                            c.Parameters[0].ParameterType.FullName == iGraphicsContext.FullName);

                        if (ctor == null)
                        {
                            throw new InvalidOperationException(
                                String.Format(
                                    "{0} does needs a constructor taking {1}",
                                    errorHelperType,
                                    graphicsContext));
                        }

                        // GraphicsContext.CurrentContext property getter
                        vars.Get_CurrentContext = graphicsContext.Methods.First(
                            method => method.Name == "get_CurrentContext");

                        vars.Set_ErrorChecking = graphicsContext.Methods.First(
                            method => method.Name == "set_ErrorChecking");

                        vars.ErrorHelperLocal = new VariableDefinition(vars.ErrorHelperType);

                        // using (new ErrorHelper(GraphicsContext.CurrentContext)) { ...
                        il.Body.Variables.Add(vars.ErrorHelperLocal);
                        il.Emit(OpCodes.Ldloca, vars.ErrorHelperLocal);
                        il.Emit(OpCodes.Call, vars.Get_CurrentContext);
                        il.Emit(OpCodes.Call, ctor);

                        vars.BeginTry = Instruction.Create(OpCodes.Nop);
                        il.Append(vars.BeginTry);

                        // Special case Begin to turn off error checking.
                        if (il.Body.Method.Name == "Begin")
                        {
                            il.Emit(OpCodes.Call, vars.Get_CurrentContext);
                            il.Emit(OpCodes.Ldc_I4_0);
                            il.Emit(OpCodes.Conv_I1);
                            il.Emit(OpCodes.Call, vars.Set_ErrorChecking);
                        }
                    }
                }
            }

            return vars;
        }
 private static void WriteMessageSize(ILProcessor worker)
 {
     worker.Append(worker.Create(OpCodes.Ldc_I4_0));
     worker.Append(worker.Create(OpCodes.Callvirt, Weaver.NetworkWriterWriteInt16));
 }
 private void DefaultValueMappingCode(ILProcessor ilProcessor)
 {
     ilProcessor.Append(Instruction.Create(OpCodes.Ldsfld, _imports.ObjectFieldRef));
     ilProcessor.Append(Instruction.Create(OpCodes.Callvirt, _imports.PropertyMapIsUriRef));
 }
 private void InjectUriStringTerm(ILProcessor il, string uriString, MethodReference method)
 {
     il.Append(Instruction.Create(OpCodes.Ldstr, uriString));
     il.Append(Instruction.Create(OpCodes.Newobj, _imports.UriStringConstructorRef));
     il.Append(Instruction.Create(OpCodes.Callvirt, method));
 }
 private void InjectQNameTerm(ILProcessor il, string prefix, string termName, MethodReference method)
 {
     il.Append(Instruction.Create(OpCodes.Ldstr, prefix));
     il.Append(Instruction.Create(OpCodes.Ldstr, termName));
     il.Append(Instruction.Create(OpCodes.Callvirt, method));
 }
Ejemplo n.º 18
0
        private static void EmitIsDivisibleBy(ILProcessor processor, int divisor, VariableDefinition storageVariable)
        {
            var skipSetFlag = processor.Create(OpCodes.Nop);
            processor.Emit(OpCodes.Ldarg_1);
            processor.Emit(OpCodes.Ldc_I4, divisor);
            processor.Emit(OpCodes.Rem);

            // var isDivisible = remainder == 0;
            processor.Emit(OpCodes.Brfalse, skipSetFlag);
            processor.Emit(OpCodes.Ldc_I4_1);

            processor.Emit(OpCodes.Stloc, storageVariable);
            processor.Append(skipSetFlag);
        }
 private void GenerateCommandDelegate(ILProcessor awakeWorker, MethodReference registerMethod, MethodDefinition func, FieldReference field)
 {
     awakeWorker.Append(awakeWorker.Create(OpCodes.Ldtoken, this.m_td));
     awakeWorker.Append(awakeWorker.Create(OpCodes.Call, Weaver.getTypeFromHandleReference));
     awakeWorker.Append(awakeWorker.Create(OpCodes.Ldsfld, field));
     awakeWorker.Append(awakeWorker.Create(OpCodes.Ldnull));
     awakeWorker.Append(awakeWorker.Create(OpCodes.Ldftn, func));
     awakeWorker.Append(awakeWorker.Create(OpCodes.Newobj, Weaver.CmdDelegateConstructor));
     awakeWorker.Append(awakeWorker.Create(OpCodes.Call, registerMethod));
 }
Ejemplo n.º 20
0
        static int EmitParameters(MethodDefinition method, MethodBody body, ILProcessor il)
        {
            int i;
            for (i = 0; i < method.Parameters.Count; i++)
            {
                var p = method.Module.Import(method.Parameters[i].ParameterType);
                il.Emit(OpCodes.Ldarg, i);

                if (p.Name == "StringBuilder")
                {
                    // void GetShaderInfoLog(..., StringBuilder foo)
                    // IntPtr foo_sb_ptr;
                    // try {
                    //  foo_sb_ptr = Marshal.AllocHGlobal(sb.Capacity + 1);
                    //  glGetShaderInfoLog(..., foo_sb_ptr);
                    //  MarshalPtrToStringBuilder(foo_sb_ptr, sb);
                    // }
                    // finally {
                    //  Marshal.FreeHGlobal(sb_ptr);
                    // }

                    // Make sure we have imported StringBuilder::Capacity and Marshal::AllocHGlobal
                    var sb_get_capacity = method.Module.Import(TypeStringBuilder.Methods.First(m => m.Name == "get_Capacity"));
                    var alloc_hglobal = method.Module.Import(TypeMarshal.Methods.First(m => m.Name == "AllocHGlobal"));

                    // IntPtr ptr;
                    var variable_name = p.Name + " _sb_ptr";
                    body.Variables.Add(new VariableDefinition(variable_name, TypeIntPtr));
                    int index = body.Variables.Count - 1;

                    // ptr = Marshal.AllocHGlobal(sb.Capacity + 1);
                    il.Emit(OpCodes.Callvirt, sb_get_capacity);
                    il.Emit(OpCodes.Call, alloc_hglobal);
                    il.Emit(OpCodes.Stloc, index);
                    il.Emit(OpCodes.Ldloc, index);

                    // We'll emit the try-finally block in the epilogue implementation,
                    // because we haven't yet emitted all necessary instructions here.
                }
                else if (p.Name == "String" && !p.IsArray)
                {
                    EmitStringParameter(method, p, body, il);
                }
                else if (p.IsByReference)
                {
                    body.Variables.Add(new VariableDefinition(new PinnedType(p)));
                    var index = body.Variables.Count - 1;
                    il.Emit(OpCodes.Stloc, index);
                    il.Emit(OpCodes.Ldloc, index);
                    il.Emit(OpCodes.Conv_I);
                }
                else if (p.IsArray)
                {
                    if (p.Name != method.Module.Import(typeof(string[])).Name)
                    {
                        // Pin the array and pass the address
                        // of its first element.
                        var element_type = p.GetElementType();
                        body.Variables.Add(new VariableDefinition(new PinnedType(new ByReferenceType(element_type))));
                        int pinned_index = body.Variables.Count - 1;

                        var empty = il.Create(OpCodes.Ldc_I4, 0);
                        var pin = il.Create(OpCodes.Ldarg, i);
                        var end = il.Create(OpCodes.Stloc, pinned_index);
                        
                        // if (array == null) goto empty
                        il.Emit(OpCodes.Brfalse, empty);

                        // else if (array.Length != 0) goto pin
                        il.Emit(OpCodes.Ldarg, i);
                        il.Emit(OpCodes.Ldlen);
                        il.Emit(OpCodes.Conv_I4);
                        il.Emit(OpCodes.Brtrue, pin);

                        // empty: IntPtr ptr = IntPtr.Zero
                        il.Append(empty);
                        il.Emit(OpCodes.Conv_U);
                        il.Emit(OpCodes.Br, end);

                        // pin: &array[0]
                        il.Append(pin);
                        il.Emit(OpCodes.Ldc_I4, 0);
                        il.Emit(OpCodes.Ldelema, element_type);

                        // end: fixed (IntPtr ptr = &array[0])
                        il.Append(end);
                        il.Emit(OpCodes.Ldloc, pinned_index);
                        il.Emit(OpCodes.Conv_I);
                    }
                    else
                    {
                        EmitStringArrayParameter(method, p, body, il);
                    }
                }
            }
            return i;
        }
Ejemplo n.º 21
0
            private void InstrumentInstructions(ILProcessor il, IList<Instruction> instructions, int numberOfReplacedInstructions, Action<ILProcessor> loadInvocation)
            {
                var seekDepth = numberOfReplacedInstructions - 1;

                // Now add all the instructions back, but transforming this.Invocation() if present
                for (var i = 0; i < instructions.Count; i++)
                {
                    var instruction = instructions[i];
                    var nextInstruction = i < instructions.Count - seekDepth ? instructions[i + seekDepth] : null;
                    if (nextInstruction != null && nextInstruction.OpCode == OpCodes.Call)
                    {
                        var methodReference = (MethodReference)nextInstruction.Operand;
                        if (methodReference.FullName == "SexyProxy.Invocation SexyProxy.ProxyExtensions::Invocation(SexyProxy.IReverseProxy)")
                        {
                            // Insert reference to invocation
                            loadInvocation(il);
                            i += seekDepth;
                            continue;
                        }
                    }
                    il.Append(instruction);
                }            
            }
Ejemplo n.º 22
0
        static int EmitParameters(MethodDefinition method, MethodDefinition native, MethodBody body, ILProcessor il)
        {
            int i;
            for (i = 0; i < method.Parameters.Count; i++)
            {
                var parameter = method.Parameters[i];
                var p = method.Module.Import(method.Parameters[i].ParameterType);
                il.Emit(OpCodes.Ldarg, i);

                if (p.Name.Contains("Int32") && native.Parameters[i].ParameterType.Name.Contains("IntPtr"))
                {
                    // This is a convenience Int32 overload for an IntPtr (size_t) parameter.
                    // We need to convert the loaded argument to IntPtr.
                    il.Emit(OpCodes.Conv_I);
                }
                else if (p.Name == "StringBuilder")
                {
                    EmitStringBuilderParameter(method, parameter, body, il);
                }
                else if (p.Name == "String" && !p.IsArray)
                {
                    EmitStringParameter(method, parameter, body, il);
                }
                else if (p.IsByReference)
                {
                    body.Variables.Add(new VariableDefinition(new PinnedType(p)));
                    var index = body.Variables.Count - 1;
                    il.Emit(OpCodes.Stloc, index);
                    il.Emit(OpCodes.Ldloc, index);
                    il.Emit(OpCodes.Conv_I);
                }
                else if (p.IsArray)
                {
                    if (p.Name != method.Module.Import(typeof(string[])).Name)
                    {
                        // .Net treats 1d arrays differently than higher rank arrays.
                        // 1d arrays are directly supported by instructions such as ldlen and ldelema.
                        // Higher rank arrays must be accessed through System.Array methods such as get_Length.
                        // 1d array:
                        //    check array is not null
                        //    check ldlen array > 0
                        //    ldc.i4.0
                        //    ldelema
                        // 2d array:
                        //    check array is not null
                        //    check array.get_Length() > 0
                        //    ldc.i4.0
                        //    ldc.i4.0
                        //    call instance T& T[0..., 0...]::Address(int32, int32)
                        // Mono treats everything as a 1d array.
                        // Interestingly, the .Net approach works on both Mono and .Net.
                        // The Mono approach fails when using high-rank arrays on .Net.
                        // We should report a bug to http://bugzilla.xamarin.com

                        // Pin the array and pass the address
                        // of its first element.
                        var array = (ArrayType)p;
                        var element_type = p.GetElementType();
                        body.Variables.Add(new VariableDefinition(new PinnedType(new ByReferenceType(element_type))));
                        int pinned_index = body.Variables.Count - 1;

                        var empty = il.Create(OpCodes.Ldc_I4, 0);
                        var pin = il.Create(OpCodes.Ldarg, i);
                        var end = il.Create(OpCodes.Stloc, pinned_index);

                        // if (array == null) goto empty
                        il.Emit(OpCodes.Brfalse, empty);

                        // else if (array.Length != 0) goto pin
                        il.Emit(OpCodes.Ldarg, i);
                        if (array.Rank == 1)
                        {
                            il.Emit(OpCodes.Ldlen);
                            il.Emit(OpCodes.Conv_I4);
                        }
                        else
                        {
                            var get_length = method.Module.Import(
                                mscorlib.MainModule.GetType("System.Array").Methods.First(m => m.Name == "get_Length"));
                            il.Emit(OpCodes.Callvirt, get_length);
                        }
                        il.Emit(OpCodes.Brtrue, pin);

                        // empty: IntPtr ptr = IntPtr.Zero
                        il.Append(empty);
                        il.Emit(OpCodes.Conv_U);
                        il.Emit(OpCodes.Br, end);

                        // pin: &array[0]
                        il.Append(pin);
                        if (array.Rank == 1)
                        {
                            // 1d array (vector), address is taken by ldelema
                            il.Emit(OpCodes.Ldc_I4, 0);
                            il.Emit(OpCodes.Ldelema, element_type);
                        }
                        else
                        {
                            // 2d-3d array, address must be taken as follows:
                            // call instance T& T[0..., 0..., 0...]::Address(int, int, int)
                            ByReferenceType t_ref = array.ElementType.MakeByReferenceType();
                            MethodReference get_address = new MethodReference("Address", t_ref, array);
                            for (int r = 0; r < array.Rank; r++)
                            {
                                get_address.Parameters.Add(new ParameterDefinition(TypeInt32));
                            }
                            get_address.HasThis = true;

                            // emit the get_address call
                            for (int r = 0; r < array.Rank; r++)
                            {
                                il.Emit(OpCodes.Ldc_I4, 0);
                            }
                            il.Emit(OpCodes.Call, get_address);
                        }

                        // end: fixed (IntPtr ptr = &array[0])
                        il.Append(end);
                        il.Emit(OpCodes.Ldloc, pinned_index);
                        il.Emit(OpCodes.Conv_I);
                    }
                    else
                    {
                        EmitStringArrayParameter(method, parameter, body, il);
                    }
                }
            }
            return i;
        }
Ejemplo n.º 23
0
        /// <summary>
        /// Emits the instructions that will instantiate each property value and assign it to the target property.
        /// </summary>
        /// <param name="serviceMap">The service map that contains the application dependencies.</param>
        /// <param name="targetMethod">The target method.</param>
        /// <param name="module">The module that hosts the container type.</param>
        /// <param name="il">The <see cref="ILProcessor"/> that points to the target method body.</param>
        /// <param name="property">The target property.</param>
        /// <param name="curentDependency">The <see cref="IDependency"/> that describes the service instance that will be assigned to the target property.</param>
        private static void EmitPropertySetter(IDictionary<IDependency, IImplementation> serviceMap, MethodDefinition targetMethod, ModuleDefinition module, ILProcessor il, PropertyInfo property, IDependency curentDependency)
        {
            // Push the target onto the stack
            il.Emit(OpCodes.Dup);

            // Get the code that will instantiate the property value
            var propertyValueImplementation = serviceMap[curentDependency];
            propertyValueImplementation.Emit(curentDependency, serviceMap, targetMethod);

            // Call the setter
            var setterMethod = property.GetSetMethod();
            var setter = module.Import(setterMethod);

            var callInstruction = setterMethod.IsVirtual ? il.Create(OpCodes.Callvirt, setter) : il.Create(OpCodes.Call, setter);
            il.Append(callInstruction);
        }
 private static void WriteServerActiveCheck(ILProcessor worker, string mdName, Instruction label, string errString)
 {
     worker.Append(worker.Create(OpCodes.Call, Weaver.NetworkServerGetActive));
     worker.Append(worker.Create(OpCodes.Brtrue, label));
     worker.Append(worker.Create(OpCodes.Ldstr, errString + " " + mdName + " called on client."));
     worker.Append(worker.Create(OpCodes.Call, Weaver.logErrorReference));
     worker.Append(worker.Create(OpCodes.Ret));
     worker.Append(label);
 }
Ejemplo n.º 25
0
        static void EmitDebugEpilogue(MethodDefinition wrapper, ILProcessor il, DebugVariables vars)
        {
            if (vars != null)
            {
                var disposeMethod = vars.ErrorHelperType.Methods.First(
                    method => method.Name == "Dispose");

                // Store then reload the result from the call
                var resultLocal = new VariableDefinition(wrapper.ReturnType);
                if (resultLocal.VariableType.FullName != Program.TypeVoid.FullName)
                {
                    il.Body.Variables.Add(resultLocal);
                    il.Emit(OpCodes.Stloc, resultLocal);
                }

                // Special case End to turn on error checking.
                if (il.Body.Method.Name == "End")
                {
                    il.Emit(OpCodes.Call, vars.Get_CurrentContext);
                    il.Emit(OpCodes.Ldc_I4_1);
                    il.Emit(OpCodes.Conv_I1);
                    il.Emit(OpCodes.Call, vars.Set_ErrorChecking);
                }

                // We need a NOP to set up the finally handler range correctly.
                var nopInstruction = Instruction.Create(OpCodes.Nop);
                var loadInstruction = Instruction.Create(OpCodes.Ldloca, vars.ErrorHelperLocal);
                var disposeInstruction = Instruction.Create(OpCodes.Call, disposeMethod);
                var endFinallyInstruction = Instruction.Create(OpCodes.Endfinally);
                var endTryInstruction = Instruction.Create(OpCodes.Leave, nopInstruction);

                il.Append(endTryInstruction);
                il.Append(loadInstruction);
                il.Append(disposeInstruction);
                il.Append(endFinallyInstruction);
                il.Append(nopInstruction);

                var finallyHandler = new ExceptionHandler(ExceptionHandlerType.Finally);
                finallyHandler.TryStart = vars.BeginTry;
                finallyHandler.TryEnd = loadInstruction;
                finallyHandler.HandlerStart = loadInstruction;
                finallyHandler.HandlerEnd = nopInstruction;

                il.Body.ExceptionHandlers.Add(finallyHandler);

                if (resultLocal.VariableType.FullName != Program.TypeVoid.FullName)
                {
                    il.Emit(OpCodes.Ldloc, resultLocal);
                }
            }
        }
Ejemplo n.º 26
0
 /// <summary>
 /// Injects the anti reflector code.
 /// </summary>
 /// <param name="il">The il builder.</param>
 /// <param name="first">The first instruction to use.</param>
 private static void InjectAntiReflectorCode(ILProcessor il, Instruction first)
 {
     il.Append(il.Create(OpCodes.Br_S, first));
     il.Append(ConfuseDecompilationTask.CreateInvalidOpCode());
     il.Append(ConfuseDecompilationTask.CreateInvalidOpCode());
     il.Append(first);
 }
Ejemplo n.º 27
0
        private static void Emit(ILProcessor ip, ModuleDefinition mod, VariableDefinition arrayVar, VariableDefinition indexVar, Dictionary<int, Instruction> braces, OpValue[] ops, int i)
        {
            OpValue op = ops[i];
            switch (op.OpCode)
            {
                case BFOpCode.Increment:
                    ip.Emit(OpCodes.Ldloc, arrayVar);
                    ip.Emit(OpCodes.Ldloc, indexVar);
                    ip.Emit(OpCodes.Ldloc, arrayVar);
                    ip.Emit(OpCodes.Ldloc, indexVar);
                    ip.Emit(OpCodes.Ldelem_I4);
                    ip.Emit(OpCodes.Ldc_I4, op.Data);
                    ip.Emit(OpCodes.Add);
                    ip.Emit(OpCodes.Stelem_I4);
                    break;

                case BFOpCode.Decrement:
                    ip.Emit(OpCodes.Ldloc, arrayVar);
                    ip.Emit(OpCodes.Ldloc, indexVar);
                    ip.Emit(OpCodes.Ldloc, arrayVar);
                    ip.Emit(OpCodes.Ldloc, indexVar);
                    ip.Emit(OpCodes.Ldelem_I4);
                    ip.Emit(OpCodes.Ldc_I4, op.Data);
                    ip.Emit(OpCodes.Sub);
                    ip.Emit(OpCodes.Stelem_I4);
                    break;

                case BFOpCode.ShiftRight:
                    ip.Emit(OpCodes.Ldloc, indexVar);
                    ip.Emit(OpCodes.Ldc_I4, op.Data);
                    ip.Emit(OpCodes.Add);
                    ip.Emit(OpCodes.Stloc, indexVar);
                    break;

                case BFOpCode.ShiftLeft:
                    ip.Emit(OpCodes.Ldloc, indexVar);
                    ip.Emit(OpCodes.Ldc_I4, op.Data);
                    ip.Emit(OpCodes.Sub);
                    ip.Emit(OpCodes.Stloc, indexVar);
                    break;

                case BFOpCode.Output:
                    ip.Emit(OpCodes.Ldloc, arrayVar);
                    ip.Emit(OpCodes.Ldloc, indexVar);
                    ip.Emit(OpCodes.Ldelem_I4);
                    ip.Emit(OpCodes.Conv_I1);
                    ip.Emit(OpCodes.Call, mod.Import(typeof(Console).GetMethod("Write", new[] { typeof(char) })));
                    break;

                case BFOpCode.Input:
                    ip.Emit(OpCodes.Call, mod.Import(typeof(Console).GetMethod("Read", new Type[0])));
                    ip.Emit(OpCodes.Ldloc, arrayVar);
                    ip.Emit(OpCodes.Ldloc, indexVar);
                    ip.Emit(OpCodes.Ldelem_I4);
                    ip.Emit(OpCodes.Conv_I1);
                    break;

                case BFOpCode.CondLeft:
                    var leftB = ip.Create(OpCodes.Ldloc, arrayVar);
                    var rightB = ip.Create(OpCodes.Nop);
                    ip.Append(leftB);
                    braces[i] = leftB;
                    braces[op.Data] = rightB;
                    ip.Emit(OpCodes.Ldloc, indexVar);
                    ip.Emit(OpCodes.Ldelem_I4);
                    ip.Emit(OpCodes.Brfalse, rightB);
                    ip.Emit(OpCodes.Nop);
                    break;

                case BFOpCode.CondRight:
                    ip.Emit(OpCodes.Br, braces[op.Data]);
                    ip.Append(braces[i]);
                    break;

                case BFOpCode.Assign:
                    ip.Emit(OpCodes.Ldloc, arrayVar);
                    ip.Emit(OpCodes.Ldloc, indexVar);
                    ip.Emit(OpCodes.Ldc_I4, op.Data);
                    ip.Emit(OpCodes.Stelem_I4);
                    break;
            }
        }
Ejemplo n.º 28
0
        protected virtual void ImplementBody(ILProcessor il, FieldReference methodInfoField, FieldReference propertyInfoField, MethodReference proceed, MethodReference proceedTargetMethod)
        {
            // Allow the InvocationHandler to opt out of handling (for perf)
            var notOptedOut = il.Create(OpCodes.Nop);
            EmitInvocationHandler(il);                                                      // Load handler
            il.Emit(OpCodes.Ldarg_0);                                                       // Load this
            il.Emit(OpCodes.Ldsfld, methodInfoField);                                       // Load the MethodInfo onto the stack
            if (propertyInfoField == null)
                il.Emit(OpCodes.Ldnull);                                                    // Not a property so load null onto the stack
            else
                il.Emit(OpCodes.Ldsfld, propertyInfoField);                                 // Load the PropertyInfo onto the stack
            il.Emit(OpCodes.Call, ClassWeaver.Context.InvocationHandlerIsHandlerActive);    // Call InvocationHandler.IsHandlerActive and leave the bool result on the stack
            il.Emit(OpCodes.Brtrue, notOptedOut);                                           // If they didn't opt out (returned true), jump to the normal interception logic below
            ImplementOptOut(il, proceedTargetMethod);                                       // They opted out, so do an implicit (and efficient) equivalent of proceed

            il.Append(notOptedOut);
            EmitCallToInvocationHandler(il, methodInfoField, propertyInfoField, proceed);

            // Return
            il.Emit(OpCodes.Ret);            
        }
Ejemplo n.º 29
0
        public void EmitToString(Application app, Page page, ILProcessor processor, TypeReference resolved)
        {
            if (resolved.FullName == "System.String")
                return;

            if (resolved.FullName == "System.Void") {
                processor.Emit (OpCodes.Ldsfld, application.CommonMethods.StringEmptyField);
                return;
            }

            if (resolved.IsValueType) {
                processor.Emit (OpCodes.Box, app.Assembly.MainModule.Import (resolved));
                processor.Emit (OpCodes.Call, app.Assembly.MainModule.Import (page.ValueToStringMethod));
                return;
            }

            TypeDefinition rtype = resolved.Resolve ();
            MethodReference method = rtype.Methods.Where (m => m.Name == "ToString").First ();

            // Import it so we get a method reference
            method = application.Assembly.MainModule.Import (method);
            Instruction inst = processor.Create (OpCodes.Callvirt, (MethodReference) method);
            processor.Append (inst);
        }
 private static void WriteCreateWriter(ILProcessor worker)
 {
     worker.Append(worker.Create(OpCodes.Newobj, Weaver.NetworkWriterCtor));
     worker.Append(worker.Create(OpCodes.Stloc_0));
     worker.Append(worker.Create(OpCodes.Ldloc_0));
 }