InSharp 1.0.2

Install-Package InSharp -Version 1.0.2
dotnet add package InSharp --version 1.0.2
<PackageReference Include="InSharp" Version="1.0.2" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add InSharp --version 1.0.2
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: InSharp, 1.0.2"
#r directive can be used in F# Interactive, C# scripting and .NET Interactive. Copy this into the interactive tool or source code of the script to reference the package.
// Install InSharp as a Cake Addin
#addin nuget:?package=InSharp&version=1.0.2

// Install InSharp as a Cake Tool
#tool nuget:?package=InSharp&version=1.0.2
The NuGet Team does not provide support for this client. Please contact its maintainers for support.

InSharp

Library for runtime MSIL functions compilation

How to use

  1. Create ILGen object ILGen<[Method delegate type]> gen = new ILGen<[Method delegate type]>([Mathod name], [enable private fields and classes access]);

  2. Write code with statements

    • gen.Line for statements
      • Use class Expr to use operators (Example: Expr.Mul(gen.args[0], gen.Const(3.5f)), Expr.Greater(gen.args[0], 0))
      • To set value use Set method (Example: gen.Line(i.Set(0));) !Set is the statement and must be in gen.Line
    • gen.Return to return value
    • gen.If / gen.ElseIf / gen.Else / gen.EndIf for if construction
    • gen.While / gen.EndWhile for while cycles
  3. Call gen.compile([enable debug info]); to compile your function

Simple shell get/set/call/construct functions

Maybe you need only to compile function-caller / constructor / setter / getter for unknown type? You can use ILTemplate for these tasks:

Memebr getters
  • ILTemplate.CommonMemberGetter - for static and instance class members get. Returns Func<object, object>, where the first argument - object instance (if instance member) and the return value - field value
  • ILTemplate.StaticMemberGetter - for stastic class members get. As CommonMember getter, but the return function doesn't receive the object instance argument
  • ILTemplate.InstanceMemberGetter - for instance class members get. The first argument of the return function - object instance, return value - field value
Member setters
  • CommonMemberSetter - for static and instance class members set. Returns Action<object, object> where first argument - object instance (for instance fields) and the second - set value
  • StaticMemberSetter - for static members set. Result Action< object > is without object instance arg
  • InstanceMemberSetter for instance members set. Returns Action<object, object> where first argument - object instance and second - set value
Class constructor
  • Use CommonObjectCreator to compile function Func<object[], object>, that calls constructor with args in array of object and returns a new object instance
Method call shell
  • CommonCallShell - call shell for static and instance class methods, with and without return type. Returns Func<object, object[], object> , where the first argument - class instance (if calls instance function), the second - call function args array. Returns null, if call method has no return type
  • CommonStaticCallShell - call shell for static class methods with and without return type. Returns Func<object[], object>, where the first argument - call function args array.
  • StaticActionCallShell - call shell for static class methods without return type. Returns Action<object[]>, where the first argument - call function args array.
  • StaticFunctionCallShell - call shell for static class methods without return type. Returns Func<object[], object>, where the first argument - call function args array.
  • CommonInstanceCallShell - call shell for instance class methods with and without return type. Returns Func<object, object[], object> where the first arg - object instance, the second - function call args array. Returns null, if the call method has no return type
  • InstanceActionCallShell - call shell for instance class methods without return type. Returns Action<object, object[]> where the first arg - object instance, the second - function call args array.
  • InstanceFunctionCallShell - call shell for instance class methods with return type. Returns Func<object, object[], object> where the first arg - object instance, the second - function call args array.

Example 1

Function returns (first arg) * 3.5

ILGen<Func<int, float>> gen = new ILGen<Func<int, float>>("Example1_func", true);

//Function
gen.Return( Expr.Mul(gen.args[0], gen.Const(3.5f)) ) ;

var func = gen.compile(true); //Our function

Console.WriteLine("Result: {0}", func(15));

Example 2

If/elseif/else constructions

var gen = new ILGen<Action<int>>("TestFunc5_1", true);

//Function
gen.If(Expr.Greater(gen.args[0], 0));
//If arg0 > 0
gen.Line(Expr.CallStatic(typeof(Console), "WriteLine", "{0} is positive", Expr.CreateArray(typeof(object), gen.args[0])));
gen.ElseIf(Expr.Less(gen.args[0], 0));
//Else if arg0 < 0
gen.Line(Expr.CallStatic(typeof(Console), "WriteLine", "{0} is negative", Expr.CreateArray(typeof(object), gen.args[0])));
gen.Else();
//else (arg0 == 0)
gen.Line(Expr.CallStatic(typeof(Console), "WriteLine", "Zero"));
gen.EndIf();


var func = gen.compile(true);

Example 3

Fibonacci numbers array gen

var gen = new ILGen<Func<int, long[]>>("TestFunc6", true);

//Function
ILVar resultArray = gen.DeclareVar(typeof(long[]));
ILVar arrayIndex = gen.DeclareVar(typeof(int));
gen.Line(resultArray.Set(Expr.InitArray(typeof(long), gen.args[0])));
gen.Line(resultArray.Index(0).Set(0));
gen.Line(resultArray.Index(1).Set(1));
gen.Line(arrayIndex.Set(2));
gen.While(Expr.NotEquals(arrayIndex, resultArray.ArrayLength));
	gen.Line(resultArray.Index(arrayIndex).Set(resultArray.Index(arrayIndex - 1) + resultArray.Index(arrayIndex - 2)));
	gen.Line(arrayIndex.Set(arrayIndex + 1));
gen.EndWhile();
gen.Return(resultArray);

var func = gen.compile(true);

Example 4

Double fields of unknown type sum function

var gen = new ILGen<Func<T, double>>(typeof(T).Name + "_fields_sum", true);

ILVar counter = gen.DeclareVar<double>();
gen.Line(counter.Set(0.0));
foreach(FieldInfo fieldInfo in typeof(T).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Where(info => info.FieldType == typeof(double)))
	gen.Line(counter.Set(counter + gen.args[0].Field(fieldInfo)));
gen.Return(counter);

var func = gen.compile(true);

Example 5

Create a matrix and output it to console

var gen = new ILGen<Action>("TestFunc14", true);

ILVar matrix = gen.DeclareVar(typeof(int[,]));
gen.Line(matrix.Set(Expr.CreateArray(typeof(int), new Expr[] { 
		1, 2, 3,
		4, 5, 6,
		7, 8, 9
	}, new int[] { 3, 3})));

ILVar index1 = gen.DeclareVar(typeof(int));
gen.Line( index1.Set(0) );
ILVar index2 = gen.DeclareVar(typeof(int));
gen.Line( index2.Set(0) );
ILVar lineString = gen.DeclareVar(typeof(string));

gen.While( Expr.Less(index1, matrix.GetArrayDimensionLength(0)) );
	gen.Line( lineString.Set("") );
	gen.Line( index2.Set(0) );
	gen.While( Expr.Less(index2, matrix.GetArrayDimensionLength(1)) );
		gen.Line( lineString.Set(Expr.Add(Expr.Add(lineString, matrix.Index(index1, index2).CompatiblePass(typeof(string))), "; ")) );
		gen.Line( index2.Set(Expr.Add(index2, 1)) );
	gen.EndWhile();
	
	gen.Line(Expr.CallStatic(typeof(Console), "WriteLine", lineString));

	gen.Line( index1.Set(Expr.Add(index1, 1)) );
gen.EndWhile();

var func =  gen.compile(true);

Example 6

Create delegate instance and call it

delegate int TestDelegate(int a, int b);

public static int testAddition(int a, int b) {
	Console.WriteLine($"Call testAddition with args a = {a}, b = {b}");
	return a + b;
}

public static void testFunc17() { 
	var gen = new ILGen<Func<int, int, int>>("TestFunc17", true);
	ILVar delegateVar = gen.DeclareVar(typeof(TestDelegate));

	gen.Line(delegateVar.Set(Expr.CreateDelegate(typeof(TestDelegate), Expr.NULL, typeof(Program).GetMethod("testAddition", BindingFlags.Public | BindingFlags.Static))));
	gen.Return(delegateVar.Invoke(gen.args[0], gen.args[1]));

	var func = gen.compile(true);
	int result = func(5, 6);
	Console.WriteLine($"Result: {result}");
}

More examples

IL compile
IL create by templates

Also

To see MSIL code, I used ILSpy. Codes to view MSIL are in ShowCode

NuGet packages (1)

Showing the top 1 NuGet packages that depend on InSharp:

Package Downloads
SerializeMethodsAutoBuilder

C# library for auto build serialize and deserialize to byte array methods for given type (based on NetBinSerializer).

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.2 82 5/16/2021
1.0.1 60 5/16/2021
1.0.0 67 5/13/2021