예제 #1
0
        private void AddExecutionVariable(MethodDefinition method, List <Instruction> instructions, ILProcessor processor)
        {
            // evaluation stack: bottom
            method.Body.Variables.Add(new VariableDefinition(context.BaseReference.Execution.TypeReference));
            context.ExecutionVariableSwitchableSection.StartIndex = instructions.Count;
            instructions.Add(processor.Create(OpCodes.Ldstr, method.Module.Assembly.FullName));
            instructions.Add(processor.Create(OpCodes.Ldstr, method.DeclaringType.Namespace));
            instructions.Add(processor.Create(OpCodes.Ldstr, method.DeclaringType.FullName));
            instructions.Add(processor.Create(OpCodes.Ldstr, method.DeclaringType.Name));
            if (method.HasThis)
            {
                instructions.Add(processor.Create(OpCodes.Ldarg_0));
                instructions.Add(processor.Create(OpCodes.Callvirt, context.GetMethodReference(getHashCodeMethod)));
            }
            else
            {
                instructions.Add(processor.Create(OpCodes.Ldc_I4_0));
            }

            instructions.Add(processor.Create(OpCodes.Ldstr, method.FullName));
            instructions.Add(processor.Create(OpCodes.Ldstr, method.Name));
            instructions.Add(processor.Create(OpCodes.Ldstr, method.ReturnType.FullName));

            // evaluation stack after the following statement: bottom->ICanAddParameters
            instructions.Add(processor.Create(OpCodes.Call, context.BaseReference.MetadataFactory.InitializeExecutionMethod));
            if (method.HasParameters)
            {
                foreach (var parameter in method.Parameters)
                {
                    // evaluation stack after the following statement: bottom->ICanAddParameters->ICanAddParameters
                    instructions.Add(processor.Create(OpCodes.Dup));
                    instructions.Add(processor.Create(OpCodes.Ldstr, parameter.Name));
                    instructions.Add(processor.Create(OpCodes.Ldstr, parameter.ParameterType.FullName));
                    instructions.Add(processor.Create(OpCodes.Ldc_I4, parameter.Sequence));
                    instructions.Add(processor.Create(OpCodes.Ldarg, parameter.Sequence));

                    // insert indirect load instruction
                    if (parameter.ParameterType.IsByReference && parameter.ParameterType is TypeSpecification)
                    {
                        instructions.Add(processor.CreateIndirectLoadInstruction(parameter.ParameterType));
                    }

                    // insert box instruction
                    if (parameter.ParameterType.IsValueType)
                    {
                        instructions.Add(processor.CreateBoxValueTypeInstruction(parameter.ParameterType));
                    }

                    // evaluation stack after the following statement: bottom->ICanAddParameters->ICanAddParameters->ICanAddCustomAttribute
                    instructions.Add(processor.Create(OpCodes.Call, context.BaseReference.MetadataFactory.InitializeParameterMethod));
                    if (parameter.HasCustomAttributes)
                    {
                        for (var i = 0; i < parameter.CustomAttributes.Count; i++)
                        {
                            var attribute = parameter.CustomAttributes[i];

                            // evaluation stack after the following statement: bottom->ICanAddParameters->ICanAddParameters->ICanAddCustomAttribute->ICanAddCustomAttribute
                            instructions.Add(processor.Create(OpCodes.Dup));
                            instructions.Add(processor.Create(OpCodes.Ldstr, attribute.AttributeType.FullName));
                            instructions.Add(processor.Create(OpCodes.Ldc_I4, i));

                            // evaluation stack after the following statement: bottom->ICanAddParameters->ICanAddParameters->ICanAddCustomAttribute->ICanAddCustomAttribute->ICanAddAttributeProperty
                            instructions.Add(processor.Create(OpCodes.Call, context.BaseReference.MetadataFactory.InitializeCustomAttributeMethod));
                            if (attribute.HasProperties)
                            {
                                for (var j = 0; j < attribute.Properties.Count; j++)
                                {
                                    var property = attribute.Properties[j];
                                    if (IlUtilities.CustomAttributePropertyTypeIsSupported(property.Argument))
                                    {
                                        // evaluation stack after the following statement: bottom->ICanAddParameters->ICanAddParameters->ICanAddCustomAttribute->ICanAddCustomAttribute->ICanAddAttributeProperty->ICanAddAttributeProperty
                                        instructions.Add(processor.Create(OpCodes.Dup));
                                        instructions.Add(processor.Create(OpCodes.Ldstr, property.Name));
                                        instructions.Add(processor.Create(OpCodes.Ldstr, property.Argument.Type.FullName));
                                        instructions.Add(processor.Create(OpCodes.Ldc_I4, j));
                                        instructions.Add(processor.CreateLoadCustomAttributePropertyValueInstruction(property.Argument));
                                        if (property.Argument.Type.IsValueType)
                                        {
                                            instructions.Add(processor.CreateBoxValueTypeInstruction(property.Argument.Type));
                                        }

                                        // evaluation stack after the following statement: bottom->ICanAddParameters->ICanAddParameters->ICanAddCustomAttribute->ICanAddCustomAttribute->ICanAddAttributeProperty->ICanAddAttributeProperty->IAttributeProperty
                                        instructions.Add(processor.Create(OpCodes.Call, context.BaseReference.MetadataFactory.InitializeAttributePropertyMethod));

                                        // evaluation stack after the following statement: bottom->ICanAddParameters->ICanAddParameters->ICanAddCustomAttribute->ICanAddCustomAttribute->ICanAddAttributeProperty
                                        instructions.Add(processor.Create(OpCodes.Callvirt, context.BaseReference.CustomAttribute.AddAttributePropertyMethod));
                                    }
                                }
                            }

                            // evaluation stack after the following statement: bottom->ICanAddParameters->ICanAddParameters->ICanAddCustomAttribute->ICanAddCustomAttribute->ICustomAttribute
                            instructions.Add(processor.Create(OpCodes.Callvirt, context.BaseReference.CustomAttribute.BuildMethod));

                            // evaluation stack after the following statement: bottom->ICanAddParameters->ICanAddParameters->ICanAddCustomAttribute
                            instructions.Add(processor.Create(OpCodes.Callvirt, context.BaseReference.Parameter.AddCustomAttributeMethod));
                        }
                    }

                    // evaluation stack after the following statement: bottom->ICanAddParameters->ICanAddParameters->IParameter
                    instructions.Add(processor.Create(OpCodes.Callvirt, context.BaseReference.Parameter.BuildMethod));

                    // evaluation stack after the following statement: bottom->ICanAddParameters
                    instructions.Add(processor.Create(OpCodes.Callvirt, context.BaseReference.Execution.AddParameterMethod));
                }
            }

            // evaluation stack after the following statement: bottom->IMethodExecution
            instructions.Add(processor.Create(OpCodes.Callvirt, context.BaseReference.Execution.BuildMethod));
            context.ExecutionVariableIndex = method.Body.Variables.Count;
            method.Body.Variables.Add(new VariableDefinition(context.BaseReference.Execution.ReadOnlyTypeReference));
            instructions.Add(processor.Create(OpCodes.Stloc, context.ExecutionVariableIndex));

            // evaluation stack after the following statement: bottom
            context.ExecutionVariableSwitchableSection.EndIndex = instructions.Count;
        }