public ICompiledMethod <T> Compile <T>(TypeReference[] parameters, IEnumerable <Instruction> instructions, IEnumerable <VariableDefinition> variables)
        {
            Type[]        resolvedParameter = parameters.Select(_typeResolver.Resolve).ToArray();
            DynamicMethod method            = new DynamicMethod("Execute", typeof(T), resolvedParameter, true);

            IILGenerator generator = new ILGeneratorWrapper(method.GetILGenerator());

            Dictionary <VariableReference, LocalBuilder> locals = AddVariables(generator, variables);

            AddInstructions(generator, instructions, locals);

            return(new CompiledDynamicMethod <T>(method));
        }
        public void EmitDouble_EmitsProvidedInstructions(double value)
        {
            var method = new DynamicMethod("Test", typeof(double), new Type[0]);
            var generator = method.GetILGenerator();

            var subject = new ILGeneratorWrapper(generator);

            // Act
            subject.Emit(OpCodes.Ldc_R8, value);
            subject.Emit(OpCodes.Ret);
            double result = (double)method.Invoke(null, new object[0]);

            // Assert
            Assert.AreEqual(value, result);
        }
        public void DeclareLocal_EmitsProvidedInstructions(byte value)
        {
            var method = new DynamicMethod("Test", typeof(byte), new Type[0]);
            var generator = method.GetILGenerator();

            var subject = new ILGeneratorWrapper(generator);

            // Act
            var local = subject.DeclareLocal(typeof(byte), false);
            subject.Emit(OpCodes.Ldc_I4_S, value);
            subject.Emit(OpCodes.Stloc, local);
            subject.Emit(OpCodes.Ldloc, local);
            subject.Emit(OpCodes.Ret);
            byte result = (byte)method.Invoke(null, new object[0]);

            // Assert
            Assert.AreEqual(value, result);
        }
        public void EmitBranch_EmitsProvidedInstructions(int value)
        {
            var method = new DynamicMethod("Test", typeof(int), new Type[0]);
            var generator = method.GetILGenerator();

            var subject = new ILGeneratorWrapper(generator);

            // Act
            var label = subject.DefineLabel();
            subject.Emit(OpCodes.Ldc_I4, value);
            subject.Emit(OpCodes.Br, label);
            subject.Emit(OpCodes.Ldc_I4, 123);
            subject.MarkLabel(label);
            subject.Emit(OpCodes.Ret);
            int result = (int)method.Invoke(null, new object[0]);

            // Assert
            Assert.AreEqual(value, result);
        }
        public void EmitSwitch_EmitsProvidedInstructions(int value)
        {
            var method = new DynamicMethod("Test", typeof(int), new Type[0]);
            var generator = method.GetILGenerator();

            var subject = new ILGeneratorWrapper(generator);

            // Act
            var endOfMethod = subject.DefineLabel();
            var labels = new[] { subject.DefineLabel(), subject.DefineLabel() };

            subject.Emit(OpCodes.Ldc_I4_0);
            subject.Emit(OpCodes.Switch, labels);
            subject.MarkLabel(labels[0]);
            subject.Emit(OpCodes.Ldc_I4, value);
            subject.Emit(OpCodes.Br_S, endOfMethod);
            subject.MarkLabel(labels[1]);
            subject.Emit(OpCodes.Ldc_I4_8, value);
            subject.Emit(OpCodes.Br_S, endOfMethod);
            subject.MarkLabel(endOfMethod);
            subject.Emit(OpCodes.Ret);

            int result = (int)method.Invoke(null, new object[0]);

            // Assert
            Assert.AreEqual(value, result);
        }
        public void EmitString_EmitsProvidedInstructions(string message)
        {
            var method = new DynamicMethod("Test", typeof(string), new Type[0]);
            var generator = method.GetILGenerator();

            var subject = new ILGeneratorWrapper(generator);

            // Act
            subject.Emit(OpCodes.Ldstr, message);
            subject.Emit(OpCodes.Ret);
            string result = (string)method.Invoke(null, new object[0]);

            // Assert
            Assert.AreEqual(message, result);
        }