MethodBuilder
MethodBuilderRequest is used to acquire a MethodBuilder.
// Request to create method builder for "MyFunction"
IRequestFor<MethodBuilder> myFunc = new MethodBuilderRequest(
Name: "MyFunction",
Attributes: MethodAttributes.Public | MethodAttributes.Virtual,
ReturnType: typeof(int),
ParameterTypes: typeof(int));
Opcodes are added to method request.
// Request to create il generator
IRequestFor<ILGenerator> il = ILGeneratorRequest.Default;
// Define labels
IRequestFor<Label> trueLabel = new LabelRequest(), falseLabel = new LabelRequest();
// "return x < 5 ? 0 : 1"
il = il.Append(OpCodes.Ldarg_1).Append(OpCodes.Ldc_I4_5).Append(OpCodes.Clt).Append(OpCodes.Brtrue_S, falseLabel);
// true: return 1;
il = il.Append(new MarkLabelRequest(trueLabel)).Append(OpCodes.Ldc_I4_1).Append(OpCodes.Ret);
// false: return 0;
il = il.Append(new MarkLabelRequest(falseLabel)).Append(OpCodes.Ldc_I4_0).Append(OpCodes.Ret);
// Add il to "MyFunction"
myFunc = myFunc.Append(il);
Method request is added to type request.
// Request to create type builder
IRequestFor<TypeBuilder> typeBuilder = new TypeBuilderRequest(
nameRequest: "MyClass6x",
attributes: TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass);
// Add "MyFunction" to type request
typeBuilder = typeBuilder.Append(myFunc);
MethodRequest is gets built as part of type request.
// Request to build type
IRequestFor<Type> type = new TypeRequest(typeBuilder);
// Request to create new instance
IRequestFor<Object> newRequest = type.NewRequest();
// Print request
newRequest.PrintTreeTo(Console.Out);
// Get instance
object instance = service.GetRequired<IRequestFor<object>, object>(newRequest);
// Evaluate: value = 4 < 5 ? 0 : 1;
int value = (int)instance.GetType().GetMethod("MyFunction", new Type[] { typeof(int) })!.Invoke(instance, new object[] { 4 })!;
// Print
Console.WriteLine(value);
Opcodes can also be added to List<IRequestFor<ILGenerator>> to conserve object[] array allocations.
// Request to create il generator
List<IRequest> il = new();
// Define labels
IRequestFor<Label> trueLabel = new LabelRequest(), falseLabel = new LabelRequest();
// "return x < 5 ? 0 : 1"
il.Add(OpCodes.Ldarg_1).Add(OpCodes.Ldc_I4_5).Add(OpCodes.Clt).Add(OpCodes.Brtrue_S, falseLabel);
// true: return 1;
il.Add(new MarkLabelRequest(trueLabel));
il.Add(OpCodes.Ldc_I4_1);
il.Add(OpCodes.Ret);
// false: return 0;
il.Add(new MarkLabelRequest(falseLabel));
il.Add(OpCodes.Ldc_I4_0);
il.Add(OpCodes.Ret);
// Add il to "MyFunction"
myFunc = myFunc.Append(ILGeneratorRequest.Default.Append(il));
Full Example
Full example
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
using Avalanche.Emit;
using Avalanche.Service;
public class methodbuilder
{
public static void Run()
{
{
// Service that handles assembly builder, module builder and types
IService service = Services.Create((ServiceHandlers.Instance, EmitHandlers.Instance), CachePolicies.Default);
// <1>
// Request to create method builder for "MyFunction"
IRequestFor<MethodBuilder> myFunc = new MethodBuilderRequest(
Name: "MyFunction",
Attributes: MethodAttributes.Public | MethodAttributes.Virtual,
ReturnType: typeof(int),
ParameterTypes: typeof(int));
// </1>
// <2>
// Request to create il generator
IRequestFor<ILGenerator> il = ILGeneratorRequest.Default;
// Define labels
IRequestFor<Label> trueLabel = new LabelRequest(), falseLabel = new LabelRequest();
// "return x < 5 ? 0 : 1"
il = il.Append(OpCodes.Ldarg_1).Append(OpCodes.Ldc_I4_5).Append(OpCodes.Clt).Append(OpCodes.Brtrue_S, falseLabel);
// true: return 1;
il = il.Append(new MarkLabelRequest(trueLabel)).Append(OpCodes.Ldc_I4_1).Append(OpCodes.Ret);
// false: return 0;
il = il.Append(new MarkLabelRequest(falseLabel)).Append(OpCodes.Ldc_I4_0).Append(OpCodes.Ret);
// Add il to "MyFunction"
myFunc = myFunc.Append(il);
// </2>
// <3>
// Request to create type builder
IRequestFor<TypeBuilder> typeBuilder = new TypeBuilderRequest(
nameRequest: "MyClass6x",
attributes: TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass);
// Add "MyFunction" to type request
typeBuilder = typeBuilder.Append(myFunc);
// </3>
// <4>
// Request to build type
IRequestFor<Type> type = new TypeRequest(typeBuilder);
// Request to create new instance
IRequestFor<Object> newRequest = type.NewRequest();
// Print request
newRequest.PrintTreeTo(Console.Out);
// Get instance
object instance = service.GetRequired<IRequestFor<object>, object>(newRequest);
// Evaluate: value = 4 < 5 ? 0 : 1;
int value = (int)instance.GetType().GetMethod("MyFunction", new Type[] { typeof(int) })!.Invoke(instance, new object[] { 4 })!;
// Print
Console.WriteLine(value);
// </4>
}
{
// Service that handles assembly builder, module builder and types
IService service = Services.Create((ServiceHandlers.Instance, EmitHandlers.Instance), CachePolicies.Default);
// Request to create method builder for "MyFunction"
IRequestFor<MethodBuilder> myFunc = new MethodBuilderRequest(
Name: "MyFunction",
Attributes: MethodAttributes.Public | MethodAttributes.Virtual,
ReturnType: typeof(int),
ParameterTypes: typeof(int));
// <11>
// Request to create il generator
List<IRequest> il = new();
// Define labels
IRequestFor<Label> trueLabel = new LabelRequest(), falseLabel = new LabelRequest();
// "return x < 5 ? 0 : 1"
il.Add(OpCodes.Ldarg_1).Add(OpCodes.Ldc_I4_5).Add(OpCodes.Clt).Add(OpCodes.Brtrue_S, falseLabel);
// true: return 1;
il.Add(new MarkLabelRequest(trueLabel));
il.Add(OpCodes.Ldc_I4_1);
il.Add(OpCodes.Ret);
// false: return 0;
il.Add(new MarkLabelRequest(falseLabel));
il.Add(OpCodes.Ldc_I4_0);
il.Add(OpCodes.Ret);
// Add il to "MyFunction"
myFunc = myFunc.Append(ILGeneratorRequest.Default.Append(il));
// </11>
// Request to create type builder
IRequestFor<TypeBuilder> typeBuilder = new TypeBuilderRequest(
nameRequest: "MyClass6z",
attributes: TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass);
// Add "MyFunction" to type request
typeBuilder = typeBuilder.Append(myFunc);
// Request to build type
IRequestFor<Type> type = new TypeRequest(typeBuilder);
// Request to create new instance
IRequestFor<Object> newRequest = type.NewRequest();
// Print request
newRequest.PrintTreeTo(Console.Out);
// Get instance
object instance = service.GetRequired<IRequestFor<object>, object>(newRequest);
// Evaluate: value = 4 < 5 ? 0 : 1;
int value = (int)instance.GetType().GetMethod("MyFunction", new Type[] { typeof(int) })!.Invoke(instance, new object[] { 4 })!;
// Print
Console.WriteLine(value);
}
}
}