private static void AddHelloWorldToMethod(MethodDefDeclaration targetMethod, IMethod consoleWriteLine)
        {
            // Removes the original code from the method body. Without this, you would get exceptions:
            InstructionBlock originalCode = targetMethod.MethodBody.RootInstructionBlock;

            originalCode.Detach();

            // Replaces the method body's content:
            InstructionBlock root = targetMethod.MethodBody.CreateInstructionBlock();

            targetMethod.MethodBody.RootInstructionBlock = root;

            InstructionBlock    helloWorldBlock    = root.AddChildBlock();
            InstructionSequence helloWorldSequence = helloWorldBlock.AddInstructionSequence();

            using (var writer = InstructionWriter.GetInstance())
            {
                // Add instructions to the beginning of the method body:
                writer.AttachInstructionSequence(helloWorldSequence);

                // Say that what follows is compiler-generated code:
                writer.EmitSymbolSequencePoint(SymbolSequencePoint.Hidden);

                // Emit a call to Console.WriteLine("Hello, world!"):
                writer.EmitInstructionString(OpCodeNumber.Ldstr, "Hello, world!");
                writer.EmitInstructionMethod(OpCodeNumber.Call, consoleWriteLine);

                writer.DetachInstructionSequence();
            }

            // Re-adding the original code at the end:
            root.AddChildBlock(originalCode);
        }
Ejemplo n.º 2
0
        private void ReplaceOperator(TypeDefDeclaration enhancedType, MethodDefDeclaration equalityMethodDef,
                                     bool negate)
        {
            InstructionBlock originalCode = equalityMethodDef.MethodBody.RootInstructionBlock;

            originalCode.Detach();

            InstructionBlock root = equalityMethodDef.MethodBody.CreateInstructionBlock();

            equalityMethodDef.MethodBody.RootInstructionBlock = root;
            var newSequence = root.AddInstructionSequence();

            using (var writer = InstructionWriter.GetInstance())
            {
                writer.AttachInstructionSequence(newSequence);

                if (enhancedType.IsValueType())
                {
                    var canonicalType = enhancedType.GetCanonicalGenericInstance();
                    writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                    writer.EmitInstructionType(OpCodeNumber.Box, canonicalType);
                    writer.EmitInstruction(OpCodeNumber.Ldarg_1);
                    writer.EmitInstructionType(OpCodeNumber.Box, canonicalType);
                }
                else
                {
                    writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                    writer.EmitInstruction(OpCodeNumber.Ldarg_1);
                }

                writer.EmitInstructionMethod(OpCodeNumber.Call, this.staticEqualsMethod);

                if (negate)
                {
                    writer.EmitInstruction(OpCodeNumber.Ldc_I4_0);
                    writer.EmitInstruction(OpCodeNumber.Ceq);
                }

                writer.EmitInstruction(OpCodeNumber.Ret);

                writer.DetachInstructionSequence();
            }
        }