Skip to content

Instantly share code, notes, and snippets.

@ForNeVeR
Created July 3, 2020 16:49
Show Gist options
  • Save ForNeVeR/302b12bcf52ace57d8bfb1703f26e501 to your computer and use it in GitHub Desktop.
Save ForNeVeR/302b12bcf52ace57d8bfb1703f26e501 to your computer and use it in GitHub Desktop.
Call __arglist method with Reflection.Emit
using System;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
namespace ConsoleApp4
{
public class Program
{
public static void Callee(__arglist)
{
var iterator = new ArgIterator(__arglist);
while (iterator.GetRemainingCount() > 0)
{
Console.WriteLine(
__refvalue(iterator.GetNextArg(), string));
}
}
static void Main()
{
var args = new object[] {"a", "b", "×"};
var callee = typeof(Program).GetMethod("Callee", BindingFlags.Static|BindingFlags.Public);
MakeCall(callee, args);
}
private static void MakeCall(MethodInfo callee, object[] args)
{
var name = new AssemblyName("ZOG");
var ass = AssemblyBuilder.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run);
var moduleBuilder = ass.DefineDynamicModule("COG");
var typeBuilder = moduleBuilder.DefineType("MUG",
TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.BeforeFieldInit);
var parameterTypes = args.Select(δ => δ.GetType()).ToArray();
var methodBuilder = typeBuilder.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static,
typeof(void), parameterTypes);
var ilGenerator = methodBuilder.GetILGenerator();
GeneratedCode(ilGenerator, callee, parameterTypes);
var mug = typeBuilder.CreateType();
var main = mug.GetMethod("Main", BindingFlags.Public | BindingFlags.Static);
main.Invoke(null, args);
}
private static void GeneratedCode(ILGenerator ilGenerator, MethodInfo callee, Type[] types)
{
for (var i = 0; i < types.Length; ++i)
ilGenerator.Emit(OpCodes.Ldarg, (short)i);
ilGenerator.EmitCall(OpCodes.Call, callee, types);
ilGenerator.Emit(OpCodes.Ret);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment