Ejemplo n.º 1
0
        public ParameterBuilder CreateParameterBuilder(ILConversion conversion, ConvertedRoutine routine, ConvertedRoutineParameter parameter)
        {
            ParameterBuilder builder = null;

            var attributes = GetParameterAttributes(parameter.ParameterDefinition);


            if (routine.IsConstructor())
            {
                var constructor = (ConvertedEmittedConstructor)routine;

                builder = constructor.ConstructorBuilder.DefineParameter(parameter.Position, attributes, parameter.Name);
            }
            else
            {
                var method = (ConvertedBuiltMethod)routine;

                builder = method.MethodBuilder.DefineParameter(parameter.Position, attributes, parameter.Name);
            }

            if ((attributes & ParameterAttributes.HasDefault) > 0)
            {
                builder.SetConstant(parameter.ParameterDefinition.Constant);
            }

            CustomAttributes.BuildCustomAttributes(conversion, parameter);

            return(builder);
        }
Ejemplo n.º 2
0
        private bool EmitOpCodes(ILConversion conversion, ConvertedRoutine routine)
        {
            var methodDefinition = (MethodDefinition)routine.MethodReference;

            var bodyState = routine.EmitState.Body;

            if (bodyState.InstructionStream == null)
            {
                bodyState.InstructionStream = new ConvertedILStream
                {
                    Buffer        = new byte[methodDefinition.Body.CodeSize],
                    ModuleBuilder = routine.DeclaringType.Module.ModuleBuilder
                };
            }

            for (int iInstruction = bodyState.CurrentInstruction; iInstruction < methodDefinition.Body.Instructions.Count; bodyState.CurrentInstruction = ++iInstruction)
            {
                var instructionDefinition = methodDefinition.Body.Instructions[iInstruction];

                if (!EmitOpCode(conversion, routine, methodDefinition, bodyState.InstructionStream, instructionDefinition))
                {
                    return(false);
                }
            }

            return(true);
        }
        /// <summary>
        /// Gets an array of bytes that contain the serialized local variable structure (.locals structure) of a routine.
        /// </summary>
        /// <param name="conversion"></param>
        /// /// <param name="routine"></param>
        /// <returns></returns>
        public bool GetLocalSignature(ILConversion conversion, ConvertedRoutine routine)
        {
            var bodyEmitState = routine.EmitState.Body;

            if (bodyEmitState.SignatureHelper == null)
            {
                bodyEmitState.SignatureHelper = SignatureHelper.GetLocalVarSigHelper(routine.DeclaringType.Module.ModuleBuilder);
            }

            var localVariables = routine.Body.LocalVariables;

            if (localVariables != null)
            {
                for (int i = bodyEmitState.CurrentLocalVariable; i < localVariables.Length; bodyEmitState.CurrentLocalVariable = ++i)
                {
                    var localVariable = localVariables[i];

                    if (localVariable.CustomModifiers != null && localVariable.CustomModifiers.Count > 0)
                    {
                        throw new Exception("Currently do not support emitted custom modifiers in local variables");
                    }

                    bodyEmitState.SignatureHelper.AddArgument(localVariable.UnderlyingType, localVariable.IsPinned);
                }
            }

            bodyEmitState.LocalSignature = bodyEmitState.SignatureHelper.GetSignature();

            return(true);

            //var e01dLocalSignature = Signatures.GetLocalSignature(conversion, convertedConstructor);

            //foreach (var local in routine.Body.LocalVariables)
            //{
            //var type = ResolveType(local.Type);
            //if (local.IsReference)
            //{
            //	type = type.MakeByRefType();
            //}

            //if (local.CustomModifiers.Any())
            //{
            //	if (local.IsPinned)
            //	{
            //		throw new NotSupportedException("Ref.Emit limitation");
            //	}

            //	Type[] reqMods, optMods;
            //	ResolveCustomModifiers(local.CustomModifiers, out reqMods, out optMods);
            //	sigHelper.AddArgument(type, reqMods, optMods);
            //}
            //else
            //{
            //	sigHelper.AddArgument(type, local.IsPinned);
            //}

            //localCount++;
            //}
        }
Ejemplo n.º 4
0
        public void CreateParameterBuilders(ILConversion conversion, ConvertedRoutine routine)
        {
            for (int i = 0; i < routine.Parameters.All.Count; i++)
            {
                var parameter = (ConvertedRoutineParameter)routine.Parameters.All[i];

                parameter.Builder = CreateParameterBuilder(conversion, routine, parameter);
            }
        }
Ejemplo n.º 5
0
        public MethodInfo GetMethodInfoOrThrow(ILConversion conversion, ConvertedTypeDefinitionMask_I typeBeingBuilt,
                                               ConvertedRoutine methodBeingBuilt, BoundTypeDefinitionMask_I methodReferenceDeclaringType, MethodReference methodReference)
        {
            //var declaringType = Execution.Types.Ensuring.EnsureBound(conversion.Model, methodReference.DeclaringType);

            if (!(methodReferenceDeclaringType is BoundTypeDefinitionWithMethodsMask_I declaringTypeWithMethods))
            {
                throw new System.Exception("Expected a type with methods declared.");
            }

            var methodInfo = GetMethodOrThrow_Internal(conversion, typeBeingBuilt, declaringTypeWithMethods, methodReference);

            if (methodInfo == null)
            {
                throw new System.Exception("Could not locate a MethodInfo.");
            }

            if (!methodReference.IsGenericInstance)
            {
                return(methodInfo);
            }

            if (!methodInfo.IsGenericMethod)
            {
                throw new System.Exception("Did not find a generic method");
            }

            var genericInstanceMethod = (GenericInstanceMethod)methodReference;

            var typeArguments = new Type[genericInstanceMethod.GenericArguments.Count];

            for (var i = 0; i < typeArguments.Length; i++)
            {
                var typeArgumentReference = genericInstanceMethod.GenericArguments[i];

                var semanticTypeNode = Execution.Types.Ensuring.Ensure(new ExecutionEnsureContext()
                {
                    Conversion      = conversion,
                    RuntimicSystem  = conversion.RuntimicSystem,
                    TypeReference   = typeArgumentReference,
                    MethodReference = methodBeingBuilt.MethodReference
                });



                typeArguments[i] = semanticTypeNode.Type.UnderlyingType;
            }

            return(methodInfo.MakeGenericMethod(typeArguments));
        }
Ejemplo n.º 6
0
        public Type SetReturnType(ILConversion conversion, ConvertedRoutine routine)
        {
            var methodDefinition = routine.MethodReference;

            if (methodDefinition.ReturnType == null)
            {
                return(null);
            }

            var bound = Execution.Types.Ensuring.EnsureBound(conversion, methodDefinition.ReturnType);

            routine.ReturnType = bound;

            return(bound.UnderlyingType);
        }
Ejemplo n.º 7
0
        private void CreateTokenFixups(ILConversion conversion, ConvertedRoutine convertedConstructor)
        {
            var bodyState = convertedConstructor.EmitState.Body;

            var ilInstructionStream = bodyState.InstructionStream;

            var tokenFixups = new int[ilInstructionStream.FixupCount];

            if (ilInstructionStream.Fixups != null)
            {
                Array.Copy(ilInstructionStream.Fixups, 0, tokenFixups, 0, ilInstructionStream.FixupCount);
            }

            bodyState.TokenFixups = tokenFixups;
        }
Ejemplo n.º 8
0
        public bool GetExceptionHandlerList(ILConversion conversion, ConvertedRoutine convertedRoutine)
        {
            var methodDefinition = (MethodDefinition)convertedRoutine.MethodReference;


            var moduleBuilder = convertedRoutine.DeclaringType.Module.ModuleBuilder;
            var regions       = methodDefinition.Body.ExceptionHandlers;
            var handlers      = new ExceptionHandler[regions.Count];
            var bodyEmitState = convertedRoutine.EmitState.Body;

            for (int i = bodyEmitState.CurrentExceptionHandler; i < regions.Count; bodyEmitState.CurrentExceptionHandler = ++i)
            {
                var info = regions[i];

                int catchToken = 0;

                if (info.HandlerType == ExceptionHandlerType.Catch)
                {
                    var boundType = Execution.Types.Ensuring.EnsureBound(conversion, info.CatchType);

                    if ((boundType is ConvertedTypeDefinition_I convertedType) &&
                        Types.Building.CheckForPhase3Dependency(convertedType, (ConvertedTypeDefinition_I)convertedRoutine.DeclaringType, true))
                    {
                        return(false);
                    }

                    catchToken = moduleBuilder.GetTypeToken(boundType.UnderlyingType).Token;

                    if (catchToken == 0)
                    {
                    }
                }

                handlers[i] = new ExceptionHandler(
                    tryOffset: info.TryStart.Offset,
                    tryLength: info.TryEnd.Offset - info.TryStart.Offset,
                    filterOffset: info.FilterStart?.Offset ?? 0,
                    handlerOffset: info.HandlerStart.Offset,
                    handlerLength: info.HandlerEnd.Offset - info.HandlerStart.Offset,
                    kind: (ExceptionHandlingClauseOptions)info.HandlerType,
                    exceptionTypeToken: catchToken);
            }


            convertedRoutine.EmitState.Body.ExceptionHandlers = handlers;

            return(true);
        }
Ejemplo n.º 9
0
        public bool EmitILStream(ILConversion conversion, ConvertedRoutine convertedConstructor)
        {
            var typeReference = convertedConstructor.DeclaringType.SourceTypeReference;

            if (typeReference.FullName.Contains("Root.Testing.Tests.Apis.E01D.Runtimic.Execution.Emitting.Conversion.Inputs.InstructionTests/<>c"))
            {
            }

            if (!EmitOpCodes(conversion, convertedConstructor))
            {
                return(false);
            }

            CreateTokenFixups(conversion, convertedConstructor);

            return(true);
        }
Ejemplo n.º 10
0
        public Type[] CreateParameters(ILConversion conversion, ConvertedRoutine routine)
        {
            var methodDefinition = routine.MethodReference;

            if (!methodDefinition.HasParameters)
            {
                return(new Type[0]);
            }

            var systemParameterTypes = new Type[methodDefinition.Parameters.Count];

            for (int i = 0; i < methodDefinition.Parameters.Count; i++)
            {
                var parameterDefinition = methodDefinition.Parameters[i];

                var bound = Execution.Types.Ensuring.EnsureBound(conversion, parameterDefinition.ParameterType);

                var convertedParameter = new ConvertedRoutineParameter()
                {
                    ParameterDefinition = parameterDefinition,
                    Position            = parameterDefinition.Sequence,
                    Name          = parameterDefinition.Name,
                    ParameterType = bound
                };

                // Make sure the 0th "this" parameter is not being overridden
                //if (
                //    //!methodDefinition.IsStatic &&
                //    convertedParameter.Position == 0)
                //{
                //    throw new Exception("Parameter position is zero which should be reserved for the 'return' argument.");
                //}

                routine.Parameters.All.Add(convertedParameter);

                systemParameterTypes[i] = bound.UnderlyingType;
            }

            return(systemParameterTypes);
        }
Ejemplo n.º 11
0
        public bool GetMemberInfo(ILConversion conversion, ConvertedTypeDefinitionMask_I typeBeingBuilt,
                                  ConvertedRoutine routineBeingBuilt,
                                  BoundTypeDefinitionMask_I methodReferenceDeclaringType,
                                  MethodReference methodReference, out MemberInfo memberInfo)
        {
            if (methodReference == null)
            {
                throw new System.Exception($"Member reference is null. Cannot resolve member info.");
            }



            // If a constructor
            if (methodReference.Name == ConstructorInfo.ConstructorName)
            {
                return(Constructors.Getting.GetConstructor(conversion, typeBeingBuilt, methodReferenceDeclaringType, methodReference, out memberInfo));
            }

            memberInfo = Methods.Getting.GetMethodInfoOrThrow(conversion, typeBeingBuilt, routineBeingBuilt, methodReferenceDeclaringType, methodReference);

            return(memberInfo != null);
        }
Ejemplo n.º 12
0
        private bool EmitOpCode(ILConversion conversion,
                                ConvertedRoutine routine,
                                MethodDefinition methodDefinition,
                                ConvertedILStream stream,
                                Instruction instructionDefinition)
        {
            if (methodDefinition.Name == "GetCustomAttributeArgumentValue" && instructionDefinition.Offset == 0x062)
            {
            }

            OpCode opCode = Cecil.Metadata.Instructions.ConvertOpCode(instructionDefinition.OpCode.Code);

            switch (instructionDefinition.OpCode.Code)
            {
            case Libs.Mono.Cecil.Cil.Code.Add:
            case Libs.Mono.Cecil.Cil.Code.Add_Ovf:
            case Libs.Mono.Cecil.Cil.Code.Add_Ovf_Un:
            case Libs.Mono.Cecil.Cil.Code.And:
            case Libs.Mono.Cecil.Cil.Code.Arglist:
            case Libs.Mono.Cecil.Cil.Code.Break:
            case Libs.Mono.Cecil.Cil.Code.Ceq:
            case Libs.Mono.Cecil.Cil.Code.Cgt:
            case Libs.Mono.Cecil.Cil.Code.Cgt_Un:
            case Libs.Mono.Cecil.Cil.Code.Ckfinite:
            case Libs.Mono.Cecil.Cil.Code.Clt:
            case Libs.Mono.Cecil.Cil.Code.Clt_Un:
            case Libs.Mono.Cecil.Cil.Code.Conv_I:
            case Libs.Mono.Cecil.Cil.Code.Conv_I1:
            case Libs.Mono.Cecil.Cil.Code.Conv_I2:
            case Libs.Mono.Cecil.Cil.Code.Conv_I4:
            case Libs.Mono.Cecil.Cil.Code.Conv_I8:
            case Libs.Mono.Cecil.Cil.Code.Conv_Ovf_I:
            case Libs.Mono.Cecil.Cil.Code.Conv_Ovf_I1:
            case Libs.Mono.Cecil.Cil.Code.Conv_Ovf_I1_Un:
            case Libs.Mono.Cecil.Cil.Code.Conv_Ovf_I2:
            case Libs.Mono.Cecil.Cil.Code.Conv_Ovf_I2_Un:
            case Libs.Mono.Cecil.Cil.Code.Conv_Ovf_I4:
            case Libs.Mono.Cecil.Cil.Code.Conv_Ovf_I4_Un:
            case Libs.Mono.Cecil.Cil.Code.Conv_Ovf_I8:
            case Libs.Mono.Cecil.Cil.Code.Conv_Ovf_I8_Un:
            case Libs.Mono.Cecil.Cil.Code.Conv_Ovf_I_Un:
            case Libs.Mono.Cecil.Cil.Code.Conv_Ovf_U:
            case Libs.Mono.Cecil.Cil.Code.Conv_Ovf_U1:
            case Libs.Mono.Cecil.Cil.Code.Conv_Ovf_U1_Un:
            case Libs.Mono.Cecil.Cil.Code.Conv_Ovf_U2:
            case Libs.Mono.Cecil.Cil.Code.Conv_Ovf_U2_Un:
            case Libs.Mono.Cecil.Cil.Code.Conv_Ovf_U4:
            case Libs.Mono.Cecil.Cil.Code.Conv_Ovf_U4_Un:
            case Libs.Mono.Cecil.Cil.Code.Conv_Ovf_U8:
            case Libs.Mono.Cecil.Cil.Code.Conv_Ovf_U8_Un:
            case Libs.Mono.Cecil.Cil.Code.Conv_Ovf_U_Un:
            case Libs.Mono.Cecil.Cil.Code.Conv_R4:
            case Libs.Mono.Cecil.Cil.Code.Conv_R8:
            case Libs.Mono.Cecil.Cil.Code.Conv_R_Un:
            case Libs.Mono.Cecil.Cil.Code.Conv_U:
            case Libs.Mono.Cecil.Cil.Code.Conv_U1:
            case Libs.Mono.Cecil.Cil.Code.Conv_U2:
            case Libs.Mono.Cecil.Cil.Code.Conv_U4:
            case Libs.Mono.Cecil.Cil.Code.Conv_U8:
            case Libs.Mono.Cecil.Cil.Code.Cpblk:
            case Libs.Mono.Cecil.Cil.Code.Div:
            case Libs.Mono.Cecil.Cil.Code.Div_Un:
            case Libs.Mono.Cecil.Cil.Code.Dup:
            case Libs.Mono.Cecil.Cil.Code.Endfilter:
            case Libs.Mono.Cecil.Cil.Code.Endfinally:
            case Libs.Mono.Cecil.Cil.Code.Initblk:
            case Libs.Mono.Cecil.Cil.Code.Ldarg_0:
            case Libs.Mono.Cecil.Cil.Code.Ldarg_1:
            case Libs.Mono.Cecil.Cil.Code.Ldarg_2:
            case Libs.Mono.Cecil.Cil.Code.Ldarg_3:
            case Libs.Mono.Cecil.Cil.Code.Ldc_I4_0:
            case Libs.Mono.Cecil.Cil.Code.Ldc_I4_1:
            case Libs.Mono.Cecil.Cil.Code.Ldc_I4_2:
            case Libs.Mono.Cecil.Cil.Code.Ldc_I4_3:
            case Libs.Mono.Cecil.Cil.Code.Ldc_I4_4:
            case Libs.Mono.Cecil.Cil.Code.Ldc_I4_5:
            case Libs.Mono.Cecil.Cil.Code.Ldc_I4_6:
            case Libs.Mono.Cecil.Cil.Code.Ldc_I4_7:
            case Libs.Mono.Cecil.Cil.Code.Ldc_I4_8:
            case Libs.Mono.Cecil.Cil.Code.Ldc_I4_M1:
            case Libs.Mono.Cecil.Cil.Code.Ldnull:

            case Libs.Mono.Cecil.Cil.Code.Ldelem_I:
            case Libs.Mono.Cecil.Cil.Code.Ldelem_I1:
            case Libs.Mono.Cecil.Cil.Code.Ldelem_I2:
            case Libs.Mono.Cecil.Cil.Code.Ldelem_I4:
            case Libs.Mono.Cecil.Cil.Code.Ldelem_I8:
            case Libs.Mono.Cecil.Cil.Code.Ldelem_R4:
            case Libs.Mono.Cecil.Cil.Code.Ldelem_R8:
            case Libs.Mono.Cecil.Cil.Code.Ldelem_Ref:
            case Libs.Mono.Cecil.Cil.Code.Ldelem_U1:
            case Libs.Mono.Cecil.Cil.Code.Ldelem_U2:
            case Libs.Mono.Cecil.Cil.Code.Ldelem_U4:
            case Libs.Mono.Cecil.Cil.Code.Ldlen:
            case Libs.Mono.Cecil.Cil.Code.Ldind_I:
            case Libs.Mono.Cecil.Cil.Code.Ldind_I1:
            case Libs.Mono.Cecil.Cil.Code.Ldind_I2:
            case Libs.Mono.Cecil.Cil.Code.Ldind_I4:
            case Libs.Mono.Cecil.Cil.Code.Ldind_I8:
            case Libs.Mono.Cecil.Cil.Code.Ldind_R4:
            case Libs.Mono.Cecil.Cil.Code.Ldind_R8:
            case Libs.Mono.Cecil.Cil.Code.Ldind_Ref:
            case Libs.Mono.Cecil.Cil.Code.Ldind_U1:
            case Libs.Mono.Cecil.Cil.Code.Ldind_U2:
            case Libs.Mono.Cecil.Cil.Code.Ldind_U4:
            case Libs.Mono.Cecil.Cil.Code.Ldloc_0:
            case Libs.Mono.Cecil.Cil.Code.Ldloc_1:
            case Libs.Mono.Cecil.Cil.Code.Ldloc_2:
            case Libs.Mono.Cecil.Cil.Code.Ldloc_3:
            case Libs.Mono.Cecil.Cil.Code.Localloc:
            case Libs.Mono.Cecil.Cil.Code.Mul:
            case Libs.Mono.Cecil.Cil.Code.Mul_Ovf:
            case Libs.Mono.Cecil.Cil.Code.Mul_Ovf_Un:
            case Libs.Mono.Cecil.Cil.Code.Neg:
            case Libs.Mono.Cecil.Cil.Code.Nop:
            case Libs.Mono.Cecil.Cil.Code.Not:
            case Libs.Mono.Cecil.Cil.Code.Pop:
            case Libs.Mono.Cecil.Cil.Code.Or:
            case Libs.Mono.Cecil.Cil.Code.Readonly:
            case Libs.Mono.Cecil.Cil.Code.Refanytype:
            case Libs.Mono.Cecil.Cil.Code.Rem:
            case Libs.Mono.Cecil.Cil.Code.Rem_Un:
            case Libs.Mono.Cecil.Cil.Code.Ret:
            case Libs.Mono.Cecil.Cil.Code.Rethrow:

            case Libs.Mono.Cecil.Cil.Code.Stelem_I:
            case Libs.Mono.Cecil.Cil.Code.Stelem_I1:
            case Libs.Mono.Cecil.Cil.Code.Stelem_I2:
            case Libs.Mono.Cecil.Cil.Code.Stelem_I4:
            case Libs.Mono.Cecil.Cil.Code.Stelem_I8:
            case Libs.Mono.Cecil.Cil.Code.Stelem_R4:
            case Libs.Mono.Cecil.Cil.Code.Stelem_R8:
            case Libs.Mono.Cecil.Cil.Code.Stelem_Ref:
            case Libs.Mono.Cecil.Cil.Code.Stind_I:
            case Libs.Mono.Cecil.Cil.Code.Stind_I1:
            case Libs.Mono.Cecil.Cil.Code.Stind_I2:
            case Libs.Mono.Cecil.Cil.Code.Stind_I4:
            case Libs.Mono.Cecil.Cil.Code.Stind_I8:
            case Libs.Mono.Cecil.Cil.Code.Stind_R4:
            case Libs.Mono.Cecil.Cil.Code.Stind_R8:
            case Libs.Mono.Cecil.Cil.Code.Stind_Ref:
            case Libs.Mono.Cecil.Cil.Code.Stloc_0:
            case Libs.Mono.Cecil.Cil.Code.Stloc_1:
            case Libs.Mono.Cecil.Cil.Code.Stloc_2:
            case Libs.Mono.Cecil.Cil.Code.Stloc_3:
            case Libs.Mono.Cecil.Cil.Code.Shl:
            case Libs.Mono.Cecil.Cil.Code.Shr:
            case Libs.Mono.Cecil.Cil.Code.Shr_Un:
            case Libs.Mono.Cecil.Cil.Code.Sub:
            case Libs.Mono.Cecil.Cil.Code.Sub_Ovf:
            case Libs.Mono.Cecil.Cil.Code.Sub_Ovf_Un:
            case Libs.Mono.Cecil.Cil.Code.Tail:
            case Libs.Mono.Cecil.Cil.Code.Throw:
            case Libs.Mono.Cecil.Cil.Code.Volatile:
            case Libs.Mono.Cecil.Cil.Code.Xor:
            {
                Generation.Emit(conversion, stream, opCode);
                break;
            }

            case Libs.Mono.Cecil.Cil.Code.Beq_S:
            case Libs.Mono.Cecil.Cil.Code.Bge_S:
            case Libs.Mono.Cecil.Cil.Code.Bge_Un_S:
            case Libs.Mono.Cecil.Cil.Code.Bgt_Un_S:
            case Libs.Mono.Cecil.Cil.Code.Bgt_S:
            case Libs.Mono.Cecil.Cil.Code.Ble_S:
            case Libs.Mono.Cecil.Cil.Code.Ble_Un_S:
            case Libs.Mono.Cecil.Cil.Code.Blt_S:
            case Libs.Mono.Cecil.Cil.Code.Blt_Un_S:
            case Libs.Mono.Cecil.Cil.Code.Bne_Un_S:
            case Libs.Mono.Cecil.Cil.Code.Brfalse_S:
            case Libs.Mono.Cecil.Cil.Code.Brtrue_S:
            case Libs.Mono.Cecil.Cil.Code.Br_S:
            case Libs.Mono.Cecil.Cil.Code.Leave_S:
            {
                var startingOffset = instructionDefinition.Offset;
                var opCodeSize     = instructionDefinition.OpCode.Size;
                var targetOffset   = ((Instruction)instructionDefinition.Operand).Offset;
                var relativeOffset = targetOffset - (startingOffset + opCodeSize + 1);


                if (instructionDefinition.BranchRelativeOffset != relativeOffset)
                {
                    throw new Exception("Relative offset incorrect");
                }

                Generation.Emit(conversion, stream, opCode, (sbyte)instructionDefinition.BranchRelativeOffset);
                break;
            }

            case Libs.Mono.Cecil.Cil.Code.Beq:
            case Libs.Mono.Cecil.Cil.Code.Bge:
            case Libs.Mono.Cecil.Cil.Code.Bge_Un:
            case Libs.Mono.Cecil.Cil.Code.Bgt:
            case Libs.Mono.Cecil.Cil.Code.Bgt_Un:
            case Libs.Mono.Cecil.Cil.Code.Ble:
            case Libs.Mono.Cecil.Cil.Code.Ble_Un:
            case Libs.Mono.Cecil.Cil.Code.Blt:
            case Libs.Mono.Cecil.Cil.Code.Blt_Un:
            case Libs.Mono.Cecil.Cil.Code.Bne_Un:
            case Libs.Mono.Cecil.Cil.Code.Br:
            case Libs.Mono.Cecil.Cil.Code.Brfalse:
            case Libs.Mono.Cecil.Cil.Code.Brtrue:
            case Libs.Mono.Cecil.Cil.Code.Leave:
            {
                var startingOffset = instructionDefinition.Offset;
                var opCodeSize     = instructionDefinition.OpCode.Size;
                var targetOffset   = ((Instruction)instructionDefinition.Operand).Offset;
                var relativeOffset = targetOffset - (startingOffset + opCodeSize + 4);

                if (instructionDefinition.BranchRelativeOffset != relativeOffset)
                {
                    throw new Exception("Relative offset incorrect");
                }

                Generation.Emit(conversion, stream, opCode, instructionDefinition.BranchRelativeOffset);
                break;
            }

            case Libs.Mono.Cecil.Cil.Code.Box:
            case Libs.Mono.Cecil.Cil.Code.Castclass:
            case Libs.Mono.Cecil.Cil.Code.Constrained:
            case Libs.Mono.Cecil.Cil.Code.Cpobj:
            case Libs.Mono.Cecil.Cil.Code.Initobj:
            case Libs.Mono.Cecil.Cil.Code.Isinst:
            case Libs.Mono.Cecil.Cil.Code.Ldelem_Any:
            case Libs.Mono.Cecil.Cil.Code.Ldelema:
            case Libs.Mono.Cecil.Cil.Code.Ldobj:
            case Libs.Mono.Cecil.Cil.Code.Mkrefany:
            case Libs.Mono.Cecil.Cil.Code.Newarr:
            case Libs.Mono.Cecil.Cil.Code.Refanyval:
            case Libs.Mono.Cecil.Cil.Code.Sizeof:
            case Libs.Mono.Cecil.Cil.Code.Stelem_Any:
            case Libs.Mono.Cecil.Cil.Code.Stobj:
            case Libs.Mono.Cecil.Cil.Code.Unbox:
            case Libs.Mono.Cecil.Cil.Code.Unbox_Any:
            {
                if (!Types.Ensuring.EnsurePhase3Type(conversion, routine.DeclaringType, methodDefinition, (TypeReference)instructionDefinition.Operand,
                                                     out BoundTypeDefinitionMask_I type))
                {
                    return(false);
                }

                Generation.Emit(conversion, stream, opCode, type.UnderlyingType);

                break;
            }

            case Libs.Mono.Cecil.Cil.Code.Ldarg:
            case Libs.Mono.Cecil.Cil.Code.Ldarga:
            case Libs.Mono.Cecil.Cil.Code.Starg:
            {
                if (instructionDefinition.Operand is ParameterDefinition parameter)
                {
                    Generation.Emit(conversion, stream, opCode, (ushort)parameter.Sequence);
                }
                else
                {
                    Generation.Emit(conversion, stream, opCode, (ushort)instructionDefinition.Operand);
                }
                break;
            }

            case Libs.Mono.Cecil.Cil.Code.Ldarga_S:
            case Libs.Mono.Cecil.Cil.Code.Ldarg_S:
            case Libs.Mono.Cecil.Cil.Code.Starg_S:
            {
                if (instructionDefinition.Operand is ParameterDefinition parameter)
                {
                    Generation.Emit(conversion, stream, opCode, (byte)parameter.Sequence);
                }
                else
                {
                    Generation.Emit(conversion, stream, opCode, (byte)instructionDefinition.Operand);
                }

                break;
            }

            // Constant Loading - Push the supplied integer value onto the stack
            case Libs.Mono.Cecil.Cil.Code.Ldc_I4:
            {
                Generation.Emit(conversion, stream, opCode, (int)instructionDefinition.Operand);
                break;
            }

            case Libs.Mono.Cecil.Cil.Code.Ldc_I4_S:
            {
                Generation.Emit(conversion, stream, opCode, (sbyte)instructionDefinition.Operand);

                break;
            }

            case Libs.Mono.Cecil.Cil.Code.Ldc_I8:
            {
                Generation.Emit(conversion, stream, opCode, (long)instructionDefinition.Operand);

                break;
            }

            // Local Load - Push the local value at the location specified by the supplied short value onto the stack
            case Libs.Mono.Cecil.Cil.Code.Ldloc:
            case Libs.Mono.Cecil.Cil.Code.Ldloca:
            case Libs.Mono.Cecil.Cil.Code.Stloc:
            {
                if (instructionDefinition.Operand is VariableDefinition variable)
                {
                    Generation.Emit(conversion, stream, opCode, (ushort)variable.Index);
                }
                else
                {
                    Generation.Emit(conversion, stream, opCode, (ushort)instructionDefinition.Operand);
                }

                break;
            }

            // Local Load - Push the address of the local value at the location specified by the supplied byte value onto the stack
            case Libs.Mono.Cecil.Cil.Code.Ldloca_S:
            case Libs.Mono.Cecil.Cil.Code.Ldloc_S:
            case Libs.Mono.Cecil.Cil.Code.Stloc_S:
            {
                if (instructionDefinition.Operand is VariableDefinition variable)
                {
                    Generation.Emit(conversion, stream, opCode, (byte)variable.Index);
                }
                else
                {
                    Generation.Emit(conversion, stream, opCode, (byte)instructionDefinition.Operand);
                }

                break;
            }


            case Libs.Mono.Cecil.Cil.Code.Ldstr:
            {
                Generation.Emit(conversion, stream, opCode, (string)instructionDefinition.Operand);
                break;
            }

            case Libs.Mono.Cecil.Cil.Code.Ldc_R4:
            {
                Generation.Emit(conversion, stream, opCode, (float)instructionDefinition.Operand);
                break;
            }

            case Libs.Mono.Cecil.Cil.Code.Ldc_R8:
            {
                Generation.Emit(conversion, stream, opCode, (double)instructionDefinition.Operand);
                break;
            }

            case Libs.Mono.Cecil.Cil.Code.Unaligned:
            {
                Generation.Emit(conversion, stream, opCode, (byte)instructionDefinition.Operand);
                break;
            }

            case Libs.Mono.Cecil.Cil.Code.Callvirt:
            case Libs.Mono.Cecil.Cil.Code.Call:
            {
                var methodReference = (MethodReference)instructionDefinition.Operand;

                var declaringBound = Execution.Types.Ensuring.EnsureBound(conversion, methodReference.DeclaringType);

                if (declaringBound == null || (declaringBound is ConvertedTypeDefinition_I convertedType &&
                                               Types.Building.CheckForPhase3Dependency(convertedType, (ConvertedTypeDefinition_I)routine.DeclaringType, true)))
                {
                    return(false);
                }

                if (!Members.GetMemberInfo(conversion, routine.DeclaringType, routine, declaringBound, methodReference,
                                           out MemberInfo memberInfo))
                {
                    return(false);
                }

                if (memberInfo is ConstructorInfo constructor)
                {
                    Generation.Emit(conversion, stream, opCode, constructor);
                }
                else if (memberInfo is MethodInfo methodInfo)
                {
                    Generation.Emit(conversion, stream, opCode, methodInfo);
                }
                else
                {
                    throw new System.Exception("Not a constructor or  method");
                }

                break;
            }

            case Libs.Mono.Cecil.Cil.Code.Calli:
            {
                throw new System.NotSupportedException("Calli instruction not supported yet.");
            }

            case Libs.Mono.Cecil.Cil.Code.Jmp:
            case Libs.Mono.Cecil.Cil.Code.Ldftn:
            case Libs.Mono.Cecil.Cil.Code.Ldvirtftn:
            {
                var methodReference = (MethodReference)instructionDefinition.Operand;

                var declaringBound = Execution.Types.Ensuring.EnsureBound(conversion, methodReference.DeclaringType);

                if (declaringBound == null || (declaringBound is ConvertedTypeDefinition_I convertedType &&
                                               Types.Building.CheckForPhase3Dependency(convertedType, (ConvertedTypeDefinition_I)routine.DeclaringType, true)))
                {
                    return(false);
                }

                if (!Members.GetMemberInfo(conversion, routine.DeclaringType, routine, declaringBound, methodReference, out MemberInfo memberInfo))
                {
                    throw new Exception("Could not find member.");
                }

                Generation.Emit(conversion, stream, opCode, (MethodInfo)memberInfo);

                break;
            }

            case Libs.Mono.Cecil.Cil.Code.Ldfld:
            case Libs.Mono.Cecil.Cil.Code.Ldflda:
            case Libs.Mono.Cecil.Cil.Code.Ldsfld:
            case Libs.Mono.Cecil.Cil.Code.Ldsflda:
            case Libs.Mono.Cecil.Cil.Code.Stfld:
            case Libs.Mono.Cecil.Cil.Code.Stsfld:
            {
                var fieldReference = (FieldReference)instructionDefinition.Operand;

                var declaringBound = Execution.Types.Ensuring.EnsureBound(conversion, fieldReference.DeclaringType);

                if (declaringBound == null || (declaringBound is ConvertedTypeDefinition_I convertedType &&
                                               Types.Building.CheckForPhase3Dependency(convertedType, (ConvertedTypeDefinition_I)routine.DeclaringType, true)))
                {
                    return(false);
                }

                var fieldInfo = Models.Fields.ResolveFieldReference(conversion, routine.DeclaringType, declaringBound, fieldReference);

                Generation.Emit(conversion, stream, opCode, fieldInfo);

                break;
            }

            case Libs.Mono.Cecil.Cil.Code.Ldtoken:
            {
                var typeReference = instructionDefinition.Operand as TypeReference;

                System.Type resolvedType;

                if (typeReference is GenericParameter genericParameter)
                {
                    if (!Instructions.GetGenericParameterType(conversion, routine.DeclaringType, routine,
                                                              genericParameter, out resolvedType))
                    {
                        return(false);
                    }
                }
                else
                {
                    var operandDeclaringType = Execution.Types.Ensuring.EnsureBound(conversion, typeReference);

                    if (operandDeclaringType == null || (operandDeclaringType is ConvertedTypeDefinition_I convertedType &&
                                                         Types.Building.CheckForPhase3Dependency(convertedType, (ConvertedTypeDefinition_I)routine.DeclaringType, true)))
                    {
                        return(false);
                    }

                    resolvedType = operandDeclaringType.UnderlyingType;
                }

                Generation.Emit(conversion, stream, opCode, resolvedType);

                break;
            }


            case Libs.Mono.Cecil.Cil.Code.Newobj:
            {
                var methodReference = (MethodReference)instructionDefinition.Operand;

                var operandDeclaringType = Execution.Types.Ensuring.EnsureBound(conversion, methodReference.DeclaringType);

                if (operandDeclaringType == null || (operandDeclaringType is ConvertedTypeDefinition_I convertedType &&
                                                     Types.Building.CheckForPhase3Dependency(convertedType, (ConvertedTypeDefinition_I)routine.DeclaringType, true)))
                {
                    return(false);
                }

                var found = Constructors.Getting.GetConstructor(conversion, routine.DeclaringType, operandDeclaringType, methodReference, out MemberInfo memberInfo);

                if (!found)
                {
                    throw new Exception("Constructor not found.  This needs to gracefully exit and comeback.");
                }

                if (memberInfo is ConstructorInfo constructorInfo)
                {
                    Generation.Emit(conversion, stream, opCode, constructorInfo);
                }
                else if (memberInfo is MethodInfo methodInfo)
                {
                    // Possible for multidimensional array creation
                    Generation.Emit(conversion, stream, opCode, methodInfo);
                }
                else
                {
                    throw new System.Exception("Not a constructor or  method");
                }

                break;
            }

            case Libs.Mono.Cecil.Cil.Code.Switch:
            {
                var instructions = (Instruction[])instructionDefinition.Operand;

                int[] offsets = new int[instructions.Length];

                for (int i = 0; i < instructions.Length; i++)
                {
                    var relativeOffsetModifier = (4 + 4 * instructions.Length + instructionDefinition.Offset + 1);

                    offsets[i] = instructions[i].Offset - relativeOffsetModifier;
                }

                Generation.Emit(conversion, stream, opCode, offsets);

                break;
            }

            default:
            {
                //No = 214,
                throw new System.Exception($"Code {instructionDefinition.OpCode.Code.ToString()} not handled.");
            }
            }

            return(true);
        }
Ejemplo n.º 13
0
 public byte[] GetLocalSignature(ILConversion conversion, ConvertedRoutine convertedRoutine)
 {
     return(LocalVariableSignatures.GetLocalSignature(conversion, convertedRoutine));
 }
Ejemplo n.º 14
0
        public bool GetGenericParameterType(ILConversion conversion, ConvertedTypeDefinitionMask_I input, ConvertedRoutine routine, GenericParameter genericParameter, out System.Type type)
        {
            switch (genericParameter.Type)
            {
            case GenericParameterType.Method:
            {
                var method = (ConvertedBuiltMethod)routine;

                var operandDeclaringType = method.DeclaringType;

                if ((operandDeclaringType is ConvertedTypeDefinition_I convertedType) &&
                    Types.Building.CheckForPhase3Dependency(convertedType, (ConvertedTypeDefinition_I)routine.DeclaringType, true))
                {
                    type = null;
                    return(false);
                }

                type = method.TypeParameters.Builders[genericParameter.Position];

                return(true);
            }

            case GenericParameterType.Type:
            {
                var declaringType = genericParameter.DeclaringType;

                var boundType = Execution.Types.Ensuring.EnsureBound(conversion, declaringType);

                if ((boundType is ConvertedTypeDefinition_I convertedType) &&
                    Types.Building.CheckForPhase3Dependency(convertedType, (ConvertedTypeDefinition_I)routine.DeclaringType, true))
                {
                    type = null;
                    return(false);
                }

                var x = (ConvertedTypeDefinitionWithTypeParameters_I)boundType;

                type = x.TypeParameters.Builders[genericParameter.Position];

                return(true);
            }

            default:
            {
                throw new System.Exception("Not a method or a type.");
            }
            }
        }
        public byte[] GetLocalSignature(ILConversion conversion, ConvertedRoutine routine)
        {
            ConvertedLocalVariableSignature signature = CreateLocalVariableSignature(conversion);

            throw new NotImplementedException();
        }
Ejemplo n.º 16
0
        public void Preprocess(ILConversion conversion, ConvertedRoutine routine)
        {
            if (routine.IsExceptionHandlingInfoPreprocessed)
            {
                return;
            }

            routine.IsExceptionHandlingInfoPreprocessed = true;

            routine.ExceptionHandlingInfo = new ExceptionHandlingInfo();

            var handlingInfo = routine.ExceptionHandlingInfo;

            var methodDefinition = (MethodDefinition)routine.MethodReference;

            var methodDefinitionBody = methodDefinition.Body;

            if (!methodDefinitionBody.HasExceptionHandlers)
            {
                return;
            }

            foreach (var exceptionBlock in methodDefinitionBody.ExceptionHandlers)
            {
                switch (exceptionBlock.HandlerType)
                {
                case ExceptionHandlerType.Filter:
                {
                    var filterBlock = new FilterBlock()
                    {
                        TryStartOffset    = exceptionBlock.TryStart.Offset,
                        TryEndOffset      = exceptionBlock.TryEnd.Offset,
                        HandlerEndOffset  = exceptionBlock.HandlerEnd.Offset,
                        FilterStartOffset = exceptionBlock.FilterStart?.Offset ?? -1,
                        ExceptionHandler  = exceptionBlock
                    };

                    handlingInfo.ExceptionBlocks.Add(filterBlock);

                    AddEvent(conversion, ExceptionBlockEventKind.Begin, handlingInfo, exceptionBlock.TryStart.Offset, filterBlock);
                    AddEvent(conversion, ExceptionBlockEventKind.Finally, handlingInfo, exceptionBlock.HandlerStart.Offset, filterBlock);
                    AddEvent(conversion, ExceptionBlockEventKind.EndBlock, handlingInfo, exceptionBlock.HandlerEnd.Offset, filterBlock);

                    break;
                }

                case ExceptionHandlerType.Fault:
                {
                    var faultBlock = new FaultBlock()
                    {
                        TryStartOffset    = exceptionBlock.TryStart.Offset,
                        TryEndOffset      = exceptionBlock.TryEnd.Offset,
                        HandlerEndOffset  = exceptionBlock.HandlerEnd.Offset,
                        FilterStartOffset = exceptionBlock.FilterStart?.Offset ?? -1,
                        ExceptionHandler  = exceptionBlock
                    };

                    handlingInfo.ExceptionBlocks.Add(faultBlock);

                    AddEvent(conversion, ExceptionBlockEventKind.Begin, handlingInfo, exceptionBlock.TryStart.Offset, faultBlock);
                    AddEvent(conversion, ExceptionBlockEventKind.Finally, handlingInfo, exceptionBlock.HandlerStart.Offset, faultBlock);
                    AddEvent(conversion, ExceptionBlockEventKind.EndBlock, handlingInfo, exceptionBlock.HandlerEnd.Offset, faultBlock);

                    break;
                }

                case ExceptionHandlerType.Finally:
                {
                    var finallyBlock = new TryFinallyBlock()
                    {
                        TryStartOffset    = exceptionBlock.TryStart.Offset,
                        TryEndOffset      = exceptionBlock.TryEnd.Offset,
                        HandlerEndOffset  = exceptionBlock.HandlerEnd.Offset,
                        FilterStartOffset = exceptionBlock.FilterStart?.Offset ?? -1,
                        ExceptionHandler  = exceptionBlock
                    };

                    handlingInfo.ExceptionBlocks.Add(finallyBlock);

                    AddEvent(conversion, ExceptionBlockEventKind.Begin, handlingInfo, exceptionBlock.TryStart.Offset, finallyBlock);
                    AddEvent(conversion, ExceptionBlockEventKind.Finally, handlingInfo, exceptionBlock.HandlerStart.Offset, finallyBlock);
                    AddEvent(conversion, ExceptionBlockEventKind.EndBlock, handlingInfo, exceptionBlock.HandlerEnd.Offset, finallyBlock);

                    break;
                }

                case ExceptionHandlerType.Catch:
                {
                    TryCatchBlock tryCatchBlock = null;

                    for (int i = 0; i < handlingInfo.TryCatchEntries.Count; i++)
                    {
                        var x = handlingInfo.TryCatchEntries[i];

                        if (x.TryStartOffset == exceptionBlock.TryStart.Offset && x.TryEndOffset == exceptionBlock.TryEnd.Offset)
                        {
                            tryCatchBlock = x;
                        }
                    }

                    if (tryCatchBlock == null)
                    {
                        tryCatchBlock = new TryCatchBlock()
                        {
                            // The first instruction that is included in the try catch block
                            TryStartOffset = exceptionBlock.TryStart.Offset,
                            // Gets the first instruction of the catch statement
                            TryEndOffset = exceptionBlock.TryEnd.Offset,
                            // Gets the first instruction that is outside of the catch statement
                            HandlerEndOffset  = exceptionBlock.HandlerEnd.Offset,
                            FilterStartOffset = exceptionBlock.FilterStart?.Offset ?? -1,
                            HandlerEntries    = new Dictionary <int, List <ExceptionHandler> >()
                        };

                        handlingInfo.TryCatchEntries.Add(tryCatchBlock);

                        handlingInfo.ExceptionBlocks.Add(tryCatchBlock);

                        System.Diagnostics.Debug.WriteLine($"Try-Catch:  BEGIN @ {exceptionBlock.TryStart.Offset.ToString("X2")}");

                        AddEvent(conversion, ExceptionBlockEventKind.Begin, handlingInfo, exceptionBlock.TryStart.Offset, tryCatchBlock);
                    }

                    if (!tryCatchBlock.HandlerEntries.TryGetValue(exceptionBlock.HandlerStart.Offset, out List <ExceptionHandler> list))
                    {
                        list = new List <ExceptionHandler>();

                        tryCatchBlock.HandlerEntries.Add(exceptionBlock.HandlerStart.Offset, list);
                    }

                    list.Add(exceptionBlock);

                    System.Diagnostics.Debug.WriteLine($"Try-Catch:  CATCH @ {exceptionBlock.HandlerStart.Offset.ToString("X2")}");
                    AddEvent(conversion, ExceptionBlockEventKind.Catch, handlingInfo, exceptionBlock.HandlerStart.Offset, tryCatchBlock, exceptionBlock);

                    break;
                }

                default:
                {
                    throw new NotSupportedException();
                }
                }
            }

            for (int i = 0; i < handlingInfo.TryCatchEntries.Count; i++)
            {
                var tryCatchBlock = handlingInfo.TryCatchEntries[i];

                ExceptionHandler lastHandlerEntry = null;

                var handlerEntriesListList = tryCatchBlock.HandlerEntries.Values.ToList();

                for (int j = 0; j < handlerEntriesListList.Count; j++)
                {
                    var currentHandlerEntryList = handlerEntriesListList[j];

                    for (int k = 0; k < currentHandlerEntryList.Count; k++)
                    {
                        var currentHandlerEntry = currentHandlerEntryList[k];

                        if (lastHandlerEntry == null)
                        {
                            lastHandlerEntry = currentHandlerEntry;
                        }
                        else if (currentHandlerEntry.HandlerEnd.Offset > lastHandlerEntry.HandlerEnd.Offset)
                        {
                            lastHandlerEntry = currentHandlerEntry;
                        }
                    }
                }

                if (lastHandlerEntry == null)
                {
                    continue;
                }

                System.Diagnostics.Debug.WriteLine($"Try-Catch:  END CATCH @ {lastHandlerEntry.HandlerEnd.Offset.ToString("X2")}");

                AddEvent(conversion, ExceptionBlockEventKind.EndBlock, handlingInfo, lastHandlerEntry.HandlerEnd.Offset, tryCatchBlock);
            }
        }
Ejemplo n.º 17
0
        public bool BuildBody(ILConversion conversion, ConvertedRoutine routine)
        {
            // If for some reason this is being called on a method that is not a method definition, then go ahead and mark it fully built
            // and return true, as there is nothing else to be done.
            // POSSIBLE ERROR CONDITION IN THE FUTURE.  NEED TO SEE HOW INTERFACES DEFINITIONS ARE HANDLED.
            if (!routine.MethodReference.IsDefinition)
            {
                throw new System.Exception("The non-method definitions body is being emitted.  This should not occur and should have been prevented " +
                                           "by the caller.");
            }

            if (routine.EmitState.Body == null)
            {
                routine.EmitState.Body = new ConvertedRoutineBodyEmitState();
            }

            var bodyEmitState = routine.EmitState.Body;

            // If the body has already been fully built, then all the information is in the emit state.
            if (bodyEmitState.BodyFullyBuilt)
            {
                return(true);
            }

            var methodDefinition = (MethodDefinition)routine.MethodReference;

            // 1) Build the local variable signature.
            //    This is an array of bytes that contain the serialized local variable
            //    structure. Specify null if the method has no local variables.  This method returns false
            //    if a dependency is detected that is not yet been satisfied.
            if (!LocalVariableSignatures.GetLocalSignature(conversion, routine))
            {
                // Dependency found that was not satisfied.
                return(false);
            }



            // 2) Build the IL Stream.  This method returns false if a dependency is detected that is not yet
            //    been satisfied.
            if (!IL.EmitILStream(conversion, routine))
            {
                // Dependency found that was not satisfied.
                return(false);
            }

            // 3) Build the IL Stream.  This method returns false if a dependency is detected that is not yet
            //    been satisfied.
            if (!ExceptionHandling.GetExceptionHandlerList(conversion, routine))
            {
                // Dependency found that was not satisfied.
                return(false);
            }

            // 4) Set max stack - This is put last in case the IL code ever computes the max stack size and cannot be determined
            //                    prior to IL emission.
            bodyEmitState.MaxStack = methodDefinition.Body.MaxStackSize;

            // Mark the methods body as fully built.
            bodyEmitState.BodyFullyBuilt = true;

            // Do unsatisfied dependencies were found.
            return(true);
        }
Ejemplo n.º 18
0
        public void ProcessInstruction(ILConversion conversion, ConvertedRoutine routine, Instruction instruction)
        {
            var info = routine.ExceptionHandlingInfo;

            var ilGenerator = routine.IlGenerator;

            var methodReference = routine.MethodReference;

            if (!methodReference.IsDefinition)
            {
                return;
            }

            var methodDefintion = (MethodDefinition)methodReference;


            if (!methodDefintion.Body.HasExceptionHandlers)
            {
                return;
            }

            if (!info.Events.TryGetValue(instruction.Offset, out List <ExceptionBlockEventEntry> events))
            {
                return;
            }

            foreach (var eventEntry in events)
            {
                switch (eventEntry.Kind)
                {
                case ExceptionBlockEventKind.Begin:
                {
                    System.Diagnostics.Debug.WriteLine($"try     @ {instruction.Offset.ToString("X2")}");

                    ilGenerator.BeginExceptionBlock();
                    break;
                }

                case ExceptionBlockEventKind.Catch:
                {
                    System.Diagnostics.Debug.WriteLine($"catch   @ {instruction.Offset.ToString("X2")}");
                    var typeReference = eventEntry.ExceptionHandler.CatchType;

                    var declaringType = Execution.Types.Ensuring.EnsureToType(conversion, typeReference);

                    ilGenerator.BeginCatchBlock(declaringType);

                    break;
                }

                case ExceptionBlockEventKind.Finally:
                {
                    System.Diagnostics.Debug.WriteLine($"finally @ {instruction.Offset.ToString("X2")}");
                    ilGenerator.BeginFinallyBlock();
                    break;
                }

                case ExceptionBlockEventKind.Fault:
                {
                    ilGenerator.BeginFaultBlock();
                    break;
                }

                case ExceptionBlockEventKind.Filter:
                {
                    ilGenerator.BeginExceptFilterBlock();
                    break;
                }

                case ExceptionBlockEventKind.EndBlock:
                {
                    System.Diagnostics.Debug.WriteLine($"end     @ {instruction.Offset.ToString("X2")}");
                    ilGenerator.EndExceptionBlock();
                    break;
                }
                }
            }
        }