InSharp 1.0.2
dotnet add package InSharp --version 1.0.2
NuGet\Install-Package InSharp -Version 1.0.2
<PackageReference Include="InSharp" Version="1.0.2" />
paket add InSharp --version 1.0.2
#r "nuget: InSharp, 1.0.2"
// 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
InSharp
Library for runtime MSIL functions compilation
How to use
Create ILGen object
ILGen<[Method delegate type]> gen = new ILGen<[Method delegate type]>([Mathod name], [enable private fields and classes access]);
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
- Use class Expr to use operators (Example:
gen.Return
to return valuegen.If
/gen.ElseIf
/gen.Else
/gen.EndIf
for if constructiongen.While
/gen.EndWhile
for while cycles
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 valueILTemplate.StaticMemberGetter
- for stastic class members get. As CommonMember getter, but the return function doesn't receive the object instance argumentILTemplate.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 valueStaticMemberSetter
- for static members set. Result Action< object > is without object instance argInstanceMemberSetter
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 typeCommonStaticCallShell
- 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 typeInstanceActionCallShell
- 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
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- LowLevelOpsHelper (>= 1.0.1)
- System.Reflection.Emit.ILGeneration (>= 4.7.0)
- System.Reflection.Emit.Lightweight (>= 4.7.0)
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.