Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
..
Failed to load latest commit information.
Properties
Add.NonGeneric.cs
Add.cs
Arglist.NonGeneric.cs
Arglist.cs
AutoNamer.cs
Bitwise.NonGeneric.cs
Bitwise.cs
BlogPost.NonGeneric.cs
BlogPost.cs
Boxing.NonGeneric.cs
Boxing.cs
Branches.NonGeneric.cs
Branches.cs
Break.NonGeneric.cs
Break.cs
CallIndirect.NonGeneric.cs
CallIndirect.cs
Calls.NonGeneric.cs
Calls.cs
CastClass.NonGeneric.cs
CastClass.cs
CheckFinite.NonGeneric.cs
CheckFinite.cs
Compares.NonGeneric.cs
Compares.cs
Constructor.NonGeneric.cs
Constructor.cs
Converts.NonGeneric.cs
Converts.cs
CopyBlock.NonGeneric.cs
CopyBlock.cs
CopyObject.NonGeneric.cs
CopyObject.cs
Disassembler.cs
Divide.NonGeneric.cs
Divide.cs
Errors.NonGeneric.cs
Errors.cs
Init.cs
InitializeBlock.NonGeneric.cs
InitializeBlock.cs
InitializeObject.NonGeneric.cs
InitializeObject.cs
Instructions.cs
Internals.cs
IsInstance.NonGeneric.cs
IsInstance.cs
Jump.NonGeneric.cs
Jump.cs
Labels.NonGeneric.cs
Labels.cs
Leave.NonGeneric.cs
Leave.cs
LoadArgumentAddress.NonGeneric.cs
LoadArgumentAddress.cs
LoadArguments.NonGeneric.cs
LoadArguments.cs
LoadConstants.NonGeneric.cs
LoadConstants.cs
LoadElement.NonGeneric.cs
LoadElement.cs
LoadElementAddress.NonGeneric.cs
LoadElementAddress.cs
LoadFieldAddress.NonGeneric.cs
LoadFieldAddress.cs
LoadFields.NonGeneric.cs
LoadFields.cs
LoadFunctionPointer.NonGeneric.cs
LoadFunctionPointer.cs
LoadIndirect.NonGeneric.cs
LoadIndirect.cs
LoadLocal.NonGeneric.cs
LoadLocal.cs
LoadObject.NonGeneric.cs
LoadObject.cs
LoadVirtualFunctionPointer.NonGeneric.cs
LoadVirtualFunctionPointer.cs
LoadlLocalAddress.NonGeneric.cs
LoadlLocalAddress.cs
Local.NonGeneric.cs
Local.cs
LocalAllocate.NonGeneric.cs
LocalAllocate.cs
Methods.NonGeneric.cs
Methods.cs
Multiply.NonGeneric.cs
Multiply.cs
Negate.NonGeneric.cs
Negate.cs
NewArray.NonGeneric.cs
NewArray.cs
NewObject.NonGeneric.cs
NewObject.cs
NoVerification.cs
ReThrow.NonGeneric.cs
ReThrow.cs
Readme.NonGeneric.cs
Readme.cs
Remainder.NonGeneric.cs
Remainder.cs
Return.NonGeneric.cs
Return.cs
Shifts.NonGeneric.cs
Shifts.cs
SigilTests.csproj
SizeOf.NonGeneric.cs
SizeOf.cs
StoreArgument.NonGeneric.cs
StoreArgument.cs
StoreElement.NonGeneric.cs
StoreElement.cs
StoreField.NonGeneric.cs
StoreField.cs
StoreIndirect.NonGeneric.cs
StoreIndirect.cs
StoreLocal.NonGeneric.cs
StoreLocal.cs
StoreObject.NonGeneric.cs
StoreObject.cs
Subtract.NonGeneric.cs
Subtract.cs
Switch.NonGeneric.cs
Switch.cs
Tail.cs
Throw.NonGeneric.cs
Throw.cs
TryCatchFinally.NonGeneric.cs
TryCatchFinally.cs
TypeInitializer.NonGeneric.cs
TypeInitializer.cs
TypedReferences.NonGeneric.cs
TypedReferences.cs
Unbox.NonGeneric.cs
Unbox.cs
Verifiability.cs
Volatile.cs
WriteLine.NonGeneric.cs
WriteLine.cs

Readme.cs

using Microsoft.VisualStudio.TestTools.UnitTesting;
using Sigil;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;

namespace SigilTests
{
    [TestClass, System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
    public partial class Readme
    {
        [TestMethod]
        public void Block1()
        {
            {
                var emiter = Emit<Func<int>>.NewDynamicMethod("MyMethod");
                Assert.IsNotNull(emiter);
            }

            {
                var asm = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("Foo"), AssemblyBuilderAccess.Run);
                var mod = asm.DefineDynamicModule("Bar");

                TypeBuilder myBuilder = mod.DefineType("T");
                var emiter = Emit<Func<int, string>>.BuildMethod(myBuilder, "Static", MethodAttributes.Static | MethodAttributes.Public, CallingConventions.Standard);

                Assert.IsNotNull(emiter);
            }

            {
                var asm = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("Foo"), AssemblyBuilderAccess.Run);
                var mod = asm.DefineDynamicModule("Bar");

                TypeBuilder myBuilder = mod.DefineType("T");
                var emiter = Emit<Func<int, string>>.BuildMethod(myBuilder, "Instance", MethodAttributes.Public, CallingConventions.HasThis);
                // Technically this is a Func<myBuilder, int string>; but because myBuilder isn't complete
                //   the generic parameters skip the `this` reference.  myBuilder will still be available as the
                //   first argument to the method

                Assert.IsNotNull(emiter);
            }
        }

        [TestMethod]
        public void Block2()
        {
            // Create a delegate that sums two integers
            var emiter = Emit<Func<int, int, int>>.NewDynamicMethod("MyMethod");
            emiter.LoadArgument(0);
            emiter.LoadArgument(1);
            emiter.Add();
            emiter.Return();
            var del = emiter.CreateDelegate();

            // prints "473"
            //Console.WriteLine(del(314, 159));
            Assert.AreEqual(473, del(314, 159));
        }

        [TestMethod]
        public void Block3()
        {
            try
            {
                var emiter = Emit<Func<int, string, int>>.NewDynamicMethod("MyMethod");
                emiter.LoadArgument(0);
                emiter.LoadArgument(1);
                emiter.Add();   // Throws a SigilVerificationException, indicating that Add() isn't defined for [int, string]
                emiter.Return();

                Assert.Fail("An exception should have been thrown");
            }
            catch (SigilVerificationException e)
            {
                Assert.AreEqual("Add expected a by ref, double, float, int, long, native int, or pointer; found System.String", e.Message);
            }
        }

        private static bool MayFailFirstCall = true;
        public static void MayFail()
        {
            if (MayFailFirstCall)
            {
                MayFailFirstCall = false;
                return;
            }

            throw new Exception();
        }

        private static bool AlwaysCallCalled;
        public static void AlwaysCall()
        {
            AlwaysCallCalled = true;
        }

        [TestMethod]
        public void Block4()
        {
            MethodInfo mayFail = typeof(Readme).GetMethod("MayFail");
            MethodInfo alwaysCall = typeof(Readme).GetMethod("AlwaysCall");
            var emiter = Emit<Func<string, bool>>.NewDynamicMethod("TryCatchFinally");

            var inputIsNull = emiter.DefineLabel("ifNull");  // names are purely for ease of debugging, and are optional
            var tryCall = emiter.DefineLabel("tryCall");

            emiter.LoadArgument(0);
            emiter.LoadNull();
            emiter.BranchIfEqual(inputIsNull);
            emiter.Branch(tryCall);

            emiter.MarkLabel(inputIsNull);
            emiter.LoadConstant(false);
            emiter.Return();

            emiter.MarkLabel(tryCall);

            var succeeded = emiter.DeclareLocal<bool>("succeeded");
            var t = emiter.BeginExceptionBlock();
            emiter.Call(mayFail);
            emiter.LoadConstant(true);
            emiter.StoreLocal(succeeded);

            var c = emiter.BeginCatchAllBlock(t);
            emiter.Pop();   // Remove exception
            emiter.LoadConstant(false);
            emiter.StoreLocal(succeeded);
            emiter.EndCatchBlock(c);

            var f = emiter.BeginFinallyBlock(t);
            emiter.Call(alwaysCall);
            emiter.EndFinallyBlock(f);

            emiter.EndExceptionBlock(t);

            emiter.LoadLocal(succeeded);
            emiter.Return();

            var del = emiter.CreateDelegate();

            MayFailFirstCall = true;
            AlwaysCallCalled = false;
            Assert.IsTrue(del("hello"));
            Assert.IsTrue(AlwaysCallCalled);

            AlwaysCallCalled = false;
            Assert.IsFalse(del("world"));
            Assert.IsTrue(AlwaysCallCalled);

            AlwaysCallCalled = false;
            Assert.IsFalse(del(null));
            Assert.IsFalse(AlwaysCallCalled);
        }

        [TestMethod]
        public void Block5()
        {
            Action mayFail = () => MayFail();
            Action alwaysCall = () => AlwaysCall();

            Func<string, bool> del =
               s =>
               {
                   if (s == null) return false;

                   bool succeeded;
                   try
                   {
                       mayFail();
                       succeeded = true;
                   }
                   catch
                   {
                       succeeded = false;
                   }
                   finally
                   {
                       alwaysCall();
                   }

                   return succeeded;
               };

            MayFailFirstCall = true;
            AlwaysCallCalled = false;
            Assert.IsTrue(del("hello"));
            Assert.IsTrue(AlwaysCallCalled);

            AlwaysCallCalled = false;
            Assert.IsFalse(del("world"));
            Assert.IsTrue(AlwaysCallCalled);

            AlwaysCallCalled = false;
            Assert.IsFalse(del(null));
            Assert.IsFalse(AlwaysCallCalled);
        }

        [TestMethod]
        public void Block6()
        {
            var emiter = Emit<Func<int>>.NewDynamicMethod("Unconditional");
            var label1 = emiter.DefineLabel("label1");
            var label2 = emiter.DefineLabel("label2");
            var label3 = emiter.DefineLabel("label3");

            emiter.LoadConstant(1);
            emiter.Branch(label1);

            emiter.MarkLabel(label2);
            emiter.LoadConstant(2);
            emiter.Branch(label3);

            emiter.MarkLabel(label1);
            emiter.Branch(label2);

            emiter.MarkLabel(label3); // the top of the stack is the first element
            emiter.Add();
            emiter.Return();

            var d = emiter.CreateDelegate();

            Assert.AreEqual(3, d());
        }
    }
}