Skip to content

Instantly share code, notes, and snippets.

@pCYSl5EDgo
Created January 28, 2019 09:46
Show Gist options
  • Save pCYSl5EDgo/c8d10196b868a6a792c97a6e577c419b to your computer and use it in GitHub Desktop.
Save pCYSl5EDgo/c8d10196b868a6a792c97a6e577c419b to your computer and use it in GitHub Desktop.
using System;
using System.Diagnostics;
using UnityEngine;
using Unity.Burst;
using Unity.Jobs;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using System.Reflection;
using System.Reflection.Emit;
using static System.Reflection.Emit.OpCodes;
public class TestManager : MonoBehaviour
{
public unsafe interface IAccessor : IJobParallelFor
{
int* GetPtr();
void SetPtr(int* value);
JobHandle Schedule();
}
private const int V = 50000;
IAccessor accessor;
void Start()
{
const string ModuleName = "Moc";
const string FileName = ModuleName + ".dll";
AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(ModuleName), AssemblyBuilderAccess.RunAndSave);
var moduleBulder = assemblyBuilder.DefineDynamicModule(ModuleName, FileName);
var typeBuilder = moduleBulder.DefineType("BURSTJOB",
TypeAttributes.Public | TypeAttributes.AnsiClass | TypeAttributes.Sealed | TypeAttributes.SequentialLayout,
typeof(System.ValueType),
new Type[] { typeof(IAccessor), typeof(IJobParallelFor) });
typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(typeof(BurstCompileAttribute).GetConstructor(Type.EmptyTypes), Array.Empty<object>()));
var intPtrType = typeof(int).MakePointerType();
var field0 = typeBuilder.DefineField("ptr",
intPtrType,
FieldAttributes.Public);
field0.SetCustomAttribute(new CustomAttributeBuilder(typeof(NativeDisableUnsafePtrRestrictionAttribute).GetConstructor(Type.EmptyTypes), Array.Empty<object>()));
const MethodAttributes Attributes = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.NewSlot | MethodAttributes.HideBySig;
var schedule = typeBuilder.DefineMethod("Schedule", Attributes, typeof(JobHandle), Type.EmptyTypes);
{
var il = schedule.GetILGenerator();
var local = il.DeclareLocal(typeof(JobHandle));
il.Emit(Ldarg_0);
il.Emit(Ldobj, typeBuilder);
il.Emit(Ldc_I4, V);
il.Emit(Ldc_I4, 1024);
il.Emit(Ldloca_S, 0);
il.Emit(Initobj, typeof(JobHandle));
il.Emit(Ldloc_0);
il.EmitCall(Call, typeof(IJobParallelForExtensions).GetMethod("Schedule").MakeGenericMethod(typeBuilder), Type.EmptyTypes);
il.Emit(Ret);
}
var execute = typeBuilder.DefineMethod("Execute", Attributes, CallingConventions.Standard, typeof(void), new Type[] { typeof(int) });
{
var il = execute.GetILGenerator();
il.Emit(Ldarg_0);
il.Emit(Ldfld, field0);
il.Emit(Ldarg_1);
il.Emit(Conv_I);
il.Emit(Ldc_I4_4);
il.Emit(Mul);
il.Emit(Add);
il.Emit(Ldarg_1);
il.Emit(Stind_I4);
il.Emit(Ret);
}
var setPtr = typeBuilder.DefineMethod("SetPtr", Attributes, CallingConventions.Standard, typeof(void), new[] { intPtrType });
{
var il = setPtr.GetILGenerator();
il.Emit(Ldarg_0);
il.Emit(Ldarg_1);
il.Emit(Stfld, field0);
il.Emit(Ret);
}
var getPtr = typeBuilder.DefineMethod("GetPtr", Attributes, CallingConventions.Standard, intPtrType, Type.EmptyTypes);
{
var il = getPtr.GetILGenerator();
il.Emit(Ldarg_0);
il.Emit(Ldfld, field0);
il.Emit(Ret);
}
accessor = (IAccessor)Activator.CreateInstance(typeBuilder.CreateType());
assemblyBuilder.Save(FileName);
Verify(assemblyBuilder);
}
unsafe void Update()
{
using (var array = new NativeArray<int>(V, Allocator.TempJob))
{
accessor.SetPtr((int*)array.GetUnsafePtr());
accessor.Schedule().Complete();
}
}
static void Verify(params AssemblyBuilder[] builders)
{
var path = @"C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.7.2 Tools\x64\PEVerify.exe";
foreach (var targetDll in builders)
{
var psi = new ProcessStartInfo(path, targetDll.GetName().Name + ".dll")
{
CreateNoWindow = true,
WindowStyle = ProcessWindowStyle.Hidden,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false
};
var p = Process.Start(psi);
var data = p.StandardOutput.ReadToEnd();
Console.WriteLine(data);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment