Initial project commit

This commit is contained in:
2026-01-08 16:50:20 +00:00
commit f0c5a8b267
29596 changed files with 4861782 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
using Mono.Cecil;
namespace Unity.Jobs.CodeGen
{
static class TypeReferenceExtensions
{
public static TypeDefinition CheckedResolve(this TypeReference typeReference)
{
return typeReference.Resolve() ?? throw new ResolutionException(typeReference);
}
}
static class MethodReferenceExtensions
{
/// <summary>
/// Generates a closed/specialized MethodReference for the given method and types[]
/// e.g.
/// struct Foo { T Bar<T>(T val) { return default(T); }
///
/// In this case, if one would like a reference to "Foo::int Bar(int val)" this method will construct such a method
/// reference when provided the open "T Bar(T val)" method reference and the TypeReferences to the types you'd like
/// specified as generic arguments (in this case a TypeReference to "int" would be passed in).
/// </summary>
/// <param name="method"></param>
/// <param name="types"></param>
/// <returns></returns>
public static MethodReference MakeGenericInstanceMethod(this MethodReference method,
params TypeReference[] types)
{
var result = new GenericInstanceMethod(method);
foreach (var type in types)
result.GenericArguments.Add(type);
return result;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3e09463226731fa409854248a8059507
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,389 @@
using System;
using System.Collections.Generic;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Cecil.Rocks;
using Unity.CompilationPipeline.Common.ILPostProcessing;
using Unity.Jobs.LowLevel.Unsafe;
using MethodAttributes = Mono.Cecil.MethodAttributes;
using MethodBody = Mono.Cecil.Cil.MethodBody;
using TypeAttributes = Mono.Cecil.TypeAttributes;
namespace Unity.Jobs.CodeGen
{
internal partial class JobsILPostProcessor : ILPostProcessor
{
private static readonly string ProducerAttributeName = typeof(JobProducerTypeAttribute).FullName;
private static readonly string RegisterGenericJobTypeAttributeName = typeof(RegisterGenericJobTypeAttribute).FullName;
public static MethodReference AttributeConstructorReferenceFor(Type attributeType, ModuleDefinition module)
{
return module.ImportReference(attributeType.GetConstructor(Array.Empty<Type>()));
}
private TypeReference LaunderTypeRef(TypeReference r_)
{
ModuleDefinition mod = AssemblyDefinition.MainModule;
TypeDefinition def = r_.Resolve();
TypeReference result;
if (r_ is GenericInstanceType git)
{
var gt = new GenericInstanceType(LaunderTypeRef(def));
foreach (var gp in git.GenericParameters)
{
gt.GenericParameters.Add(gp);
}
foreach (var ga in git.GenericArguments)
{
gt.GenericArguments.Add(LaunderTypeRef(ga));
}
result = gt;
}
else
{
result = new TypeReference(def.Namespace, def.Name, def.Module, def.Scope, def.IsValueType);
if (def.DeclaringType != null)
{
result.DeclaringType = LaunderTypeRef(def.DeclaringType);
}
}
return mod.ImportReference(result);
}
// http://www.isthe.com/chongo/src/fnv/hash_64a.c
static ulong StableHash_FNV1A64(string text)
{
ulong result = 14695981039346656037;
foreach (var c in text)
{
result = 1099511628211 * (result ^ (byte)(c & 255));
result = 1099511628211 * (result ^ (byte)(c >> 8));
}
return result;
}
bool PostProcessImpl()
{
bool anythingChanged = false;
var asmDef = AssemblyDefinition;
var funcDef = new MethodDefinition("CreateJobReflectionData",
MethodAttributes.Static | MethodAttributes.Public | MethodAttributes.HideBySig,
asmDef.MainModule.ImportReference(typeof(void)));
// This must use a stable hash code function (do not using string.GetHashCode)
var autoClassName = $"__JobReflectionRegistrationOutput__{StableHash_FNV1A64(asmDef.FullName)}";
funcDef.Body.InitLocals = false;
var classDef = new TypeDefinition("", autoClassName, TypeAttributes.Class, asmDef.MainModule.ImportReference(typeof(object)));
classDef.IsBeforeFieldInit = false;
classDef.CustomAttributes.Add(new CustomAttribute(AttributeConstructorReferenceFor(typeof(DOTSCompilerGeneratedAttribute), asmDef.MainModule)));
classDef.Methods.Add(funcDef);
var body = funcDef.Body;
var processor = body.GetILProcessor();
// Setup instructions used for try/catch wrapping all earlyinit calls
// for this assembly's job types
var workStartOp = processor.Create(OpCodes.Nop);
var workDoneOp = Instruction.Create(OpCodes.Nop);
var handler = Instruction.Create(OpCodes.Nop);
var landingPad = Instruction.Create(OpCodes.Nop);
processor.Append(workStartOp);
var genericJobs = new List<TypeReference>();
var visited = new HashSet<string>();
foreach (var attr in asmDef.CustomAttributes)
{
if (attr.AttributeType.FullName != RegisterGenericJobTypeAttributeName)
continue;
var typeRef = (TypeReference)attr.ConstructorArguments[0].Value;
var openType = typeRef.Resolve();
if (!typeRef.IsGenericInstance || !openType.IsValueType)
{
DiagnosticMessages.Add(UserError.DC3001(openType));
continue;
}
genericJobs.Add(typeRef);
visited.Add(typeRef.FullName);
}
CollectGenericTypeInstances(AssemblyDefinition, genericJobs, visited);
foreach (var t in asmDef.MainModule.Types)
{
anythingChanged |= VisitJobStructs(t, processor, body);
}
foreach (var t in genericJobs)
{
anythingChanged |= VisitJobStructs(t, processor, body);
}
// Now that we have generated all reflection info
// finish wrapping the ops in a try catch now
var lastWorkOp = processor.Body.Instructions[processor.Body.Instructions.Count-1];
processor.Append(handler);
var earlyInitHelpersDef = asmDef.MainModule.ImportReference(typeof(EarlyInitHelpers)).Resolve();
MethodDefinition jobReflectionDataCreationFailedDef = null;
foreach (var method in earlyInitHelpersDef.Methods)
{
if (method.Name == nameof(EarlyInitHelpers.JobReflectionDataCreationFailed))
{
jobReflectionDataCreationFailedDef = method;
break;
}
}
var errorHandler = asmDef.MainModule.ImportReference(jobReflectionDataCreationFailedDef);
processor.Append(Instruction.Create(OpCodes.Call, errorHandler));
processor.Append(landingPad);
var leaveSuccess = Instruction.Create(OpCodes.Leave, landingPad);
var leaveFail = Instruction.Create(OpCodes.Leave, landingPad);
processor.InsertAfter(lastWorkOp, leaveSuccess);
processor.InsertBefore(landingPad, leaveFail);
var exc = new ExceptionHandler(ExceptionHandlerType.Catch);
exc.TryStart = workStartOp;
exc.TryEnd = leaveSuccess.Next;
exc.HandlerStart = handler;
exc.HandlerEnd = leaveFail.Next;
exc.CatchType = asmDef.MainModule.ImportReference(typeof(Exception));
body.ExceptionHandlers.Add(exc);
processor.Emit(OpCodes.Ret);
if (anythingChanged)
{
var ctorFuncDef = new MethodDefinition("EarlyInit", MethodAttributes.Static | MethodAttributes.Public | MethodAttributes.HideBySig, asmDef.MainModule.ImportReference(typeof(void)));
if (!Defines.Contains("UNITY_EDITOR"))
{
// Needs to run automatically in the player, but we need to
// exclude this attribute when building for the editor, or
// it will re-run the registration for every enter play mode.
var loadTypeEnumType = asmDef.MainModule.ImportReference(typeof(UnityEngine.RuntimeInitializeLoadType));
var attributeCtor = asmDef.MainModule.ImportReference(typeof(UnityEngine.RuntimeInitializeOnLoadMethodAttribute).GetConstructor(new[] { typeof(UnityEngine.RuntimeInitializeLoadType) }));
var attribute = new CustomAttribute(attributeCtor);
attribute.ConstructorArguments.Add(new CustomAttributeArgument(loadTypeEnumType, UnityEngine.RuntimeInitializeLoadType.AfterAssembliesLoaded));
ctorFuncDef.CustomAttributes.Add(attribute);
}
else
{
// Needs to run automatically in the editor.
var attributeCtor2 = asmDef.MainModule.ImportReference(typeof(UnityEditor.InitializeOnLoadMethodAttribute).GetConstructor(Type.EmptyTypes));
ctorFuncDef.CustomAttributes.Add(new CustomAttribute(attributeCtor2));
}
ctorFuncDef.Body.InitLocals = false;
var p = ctorFuncDef.Body.GetILProcessor();
p.Emit(OpCodes.Call, funcDef);
p.Emit(OpCodes.Ret);
classDef.Methods.Add(ctorFuncDef);
asmDef.MainModule.Types.Add(classDef);
}
return anythingChanged;
}
private bool VisitJobStructInterfaces(TypeReference jobTypeRef, TypeDefinition jobType, TypeDefinition currentType, ILProcessor processor, MethodBody body)
{
bool didAnything = false;
if (currentType.HasInterfaces && jobType.IsValueType)
{
foreach (var iface in currentType.Interfaces)
{
var idef = iface.InterfaceType.CheckedResolve();
foreach (var attr in idef.CustomAttributes)
{
if (attr.AttributeType.FullName == ProducerAttributeName)
{
var producerRef = (TypeReference)attr.ConstructorArguments[0].Value;
var launderedType = LaunderTypeRef(jobTypeRef);
didAnything |= GenerateCalls(producerRef, launderedType, body, processor);
}
if (currentType.IsInterface)
{
// Generic jobs need to be either reference in fully closed form, or registered explicitly with an attribute.
if (iface.InterfaceType.GenericParameters.Count == 0)
didAnything |= VisitJobStructInterfaces(jobTypeRef, jobType, idef, processor, body);
}
}
}
}
foreach (var nestedType in currentType.NestedTypes)
{
didAnything |= VisitJobStructs(nestedType, processor, body);
}
return didAnything;
}
private bool VisitJobStructs(TypeReference t, ILProcessor processor, MethodBody body)
{
if (t.GenericParameters.Count > 0)
{
// Generic jobs need to be either reference in fully closed form, or registered explicitly with an attribute.
return false;
}
var rt = t.CheckedResolve();
return VisitJobStructInterfaces(t, rt, rt, processor, body);
}
private bool GenerateCalls(TypeReference producerRef, TypeReference jobStructType, MethodBody body, ILProcessor processor)
{
try
{
var carrierType = producerRef.CheckedResolve();
MethodDefinition methodToCall = null;
while (carrierType != null)
{
methodToCall = null;
foreach (var method in carrierType.GetMethods())
{
if(method.IsStatic && method.IsPublic && method.Parameters.Count == 0 && method.Name == "EarlyJobInit")
{
methodToCall = method;
break;
}
}
if (methodToCall != null)
break;
carrierType = carrierType.DeclaringType;
}
// Legacy jobs lazy initialize.
if (methodToCall == null)
return false;
var asm = AssemblyDefinition.MainModule;
var mref = asm.ImportReference(asm.ImportReference(methodToCall).MakeGenericInstanceMethod(jobStructType));
processor.Append(Instruction.Create(OpCodes.Call, mref));
return true;
}
catch (Exception ex)
{
DiagnosticMessages.Add(InternalCompilerError.DCICE300(producerRef, jobStructType, ex));
}
return false;
}
private static void CollectGenericTypeInstances(AssemblyDefinition assembly, List<TypeReference> types, HashSet<string> visited)
{
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// WARNING: THIS CODE HAS TO BE MAINTAINED IN SYNC WITH BurstReflection.cs in Unity.Burst package
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// From: https://gist.github.com/xoofx/710aaf86e0e8c81649d1261b1ef9590e
if (assembly == null) throw new ArgumentNullException(nameof(assembly));
const int mdMaxCount = 1 << 24;
foreach (var module in assembly.Modules)
{
for (int i = 1; i < mdMaxCount; i++)
{
// Token base id for TypeSpec
const int mdTypeSpec = 0x1B000000;
var token = module.LookupToken(mdTypeSpec | i);
if (token is GenericInstanceType type)
{
if (type.IsGenericInstance && !type.ContainsGenericParameter)
{
CollectGenericTypeInstances(type, types, visited);
}
} else if (token == null) break;
}
for (int i = 1; i < mdMaxCount; i++)
{
// Token base id for MethodSpec
const int mdMethodSpec = 0x2B000000;
var token = module.LookupToken(mdMethodSpec | i);
if (token is GenericInstanceMethod method)
{
foreach (var argType in method.GenericArguments)
{
if (argType.IsGenericInstance && !argType.ContainsGenericParameter)
{
CollectGenericTypeInstances(argType, types, visited);
}
}
}
else if (token == null) break;
}
for (int i = 1; i < mdMaxCount; i++)
{
// Token base id for Field
const int mdField = 0x04000000;
var token = module.LookupToken(mdField | i);
if (token is FieldReference field)
{
var fieldType = field.FieldType;
if (fieldType.IsGenericInstance && !fieldType.ContainsGenericParameter)
{
CollectGenericTypeInstances(fieldType, types, visited);
}
}
else if (token == null) break;
}
}
}
private static void CollectGenericTypeInstances(TypeReference type, List<TypeReference> types, HashSet<string> visited)
{
if (type.IsPrimitive) return;
if (!visited.Add(type.FullName)) return;
// Add only concrete types
if (type.IsGenericInstance && !type.ContainsGenericParameter)
{
types.Add(type);
}
// Collect recursively generic type arguments
var genericInstanceType = type as GenericInstanceType;
if (genericInstanceType != null)
{
foreach (var genericTypeArgument in genericInstanceType.GenericArguments)
{
if (!genericTypeArgument.IsPrimitive)
{
CollectGenericTypeInstances(genericTypeArgument, types, visited);
}
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 303e5975f34d18c4d81f25c4af12839a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,335 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Threading;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Unity.CompilationPipeline.Common.Diagnostics;
using Unity.CompilationPipeline.Common.ILPostProcessing;
namespace Unity.Jobs.CodeGen
{
// Jobs ILPP entry point
internal partial class JobsILPostProcessor : ILPostProcessor
{
AssemblyDefinition AssemblyDefinition;
List<DiagnosticMessage> DiagnosticMessages = new List<DiagnosticMessage>();
public HashSet<string> Defines { get; private set; }
public override ILPostProcessResult Process(ICompiledAssembly compiledAssembly)
{
bool madeAnyChange = false;
Defines = new HashSet<string>(compiledAssembly.Defines);
try
{
AssemblyDefinition = AssemblyDefinitionFor(compiledAssembly);
}
catch (BadImageFormatException)
{
return new ILPostProcessResult(null, DiagnosticMessages);
}
try
{
// This only works because the PostProcessorAssemblyResolver is explicitly loading
// transitive dependencies (and then some) and so if we can't find a references to
// Unity.Jobs (via EarlyInitHelpers) in there than we are confident the assembly doesn't need processing
var earlyInitHelpers = AssemblyDefinition.MainModule.ImportReference(typeof(EarlyInitHelpers)).CheckedResolve();
}
catch (ResolutionException)
{
return new ILPostProcessResult(null, DiagnosticMessages);
}
madeAnyChange = PostProcessImpl();
// Hack to remove circular references
var selfName = AssemblyDefinition.Name.FullName;
foreach (var referenceName in AssemblyDefinition.MainModule.AssemblyReferences)
{
if (referenceName.FullName == selfName)
{
AssemblyDefinition.MainModule.AssemblyReferences.Remove(referenceName);
break;
}
}
if (!madeAnyChange)
return new ILPostProcessResult(null, DiagnosticMessages);
bool hasError = false;
foreach (var d in DiagnosticMessages)
{
if (d.DiagnosticType == DiagnosticType.Error)
{
hasError = true;
break;
}
}
if (hasError)
return new ILPostProcessResult(null, DiagnosticMessages);
var pe = new MemoryStream();
var pdb = new MemoryStream();
var writerParameters = new WriterParameters
{
SymbolWriterProvider = new PortablePdbWriterProvider(), SymbolStream = pdb, WriteSymbols = true
};
AssemblyDefinition.Write(pe, writerParameters);
return new ILPostProcessResult(new InMemoryAssembly(pe.ToArray(), pdb.ToArray()), DiagnosticMessages);
}
public override ILPostProcessor GetInstance()
{
return this;
}
public override bool WillProcess(ICompiledAssembly compiledAssembly)
{
if (compiledAssembly.Name.EndsWith("CodeGen.Tests", StringComparison.Ordinal))
return false;
if (compiledAssembly.InMemoryAssembly.PdbData == null || compiledAssembly.InMemoryAssembly.PeData == null)
return false;
var referencesCollections = false;
if (compiledAssembly.Name == "Unity.Collections")
{
return true;
}
for (int i = 0; i < compiledAssembly.References.Length; ++i)
{
var fileName = Path.GetFileNameWithoutExtension(compiledAssembly.References[i]);
if (fileName == "Unity.Collections")
{
referencesCollections = true;
break;
}
}
if (!referencesCollections) return false;
return true;
}
// *******************************************************************************
// ** NOTE
// ** Everything below this is a copy of the same process used in EntitiesILPostProcessor and
// ** should stay synced with it.
// *******************************************************************************
class PostProcessorAssemblyResolver : IAssemblyResolver
{
private readonly HashSet<string> _referenceDirectories;
private Dictionary<string, HashSet<string>> _referenceToPathMap;
Dictionary<string, AssemblyDefinition> _cache = new Dictionary<string, AssemblyDefinition>();
private ICompiledAssembly _compiledAssembly;
private AssemblyDefinition _selfAssembly;
public PostProcessorAssemblyResolver(ICompiledAssembly compiledAssembly)
{
_compiledAssembly = compiledAssembly;
_referenceToPathMap = new Dictionary<string, HashSet<string>>();
_referenceDirectories = new HashSet<string>();
foreach (var reference in compiledAssembly.References)
{
var assemblyName = Path.GetFileNameWithoutExtension(reference);
if (!_referenceToPathMap.TryGetValue(assemblyName, out var fileList))
{
fileList = new HashSet<string>();
_referenceToPathMap.Add(assemblyName, fileList);
}
fileList.Add(reference);
_referenceDirectories.Add(Path.GetDirectoryName(reference));
}
}
public void Dispose()
{
}
public AssemblyDefinition Resolve(AssemblyNameReference name)
{
return Resolve(name, new ReaderParameters(ReadingMode.Deferred));
}
public AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters)
{
{
if (name.Name == _compiledAssembly.Name)
return _selfAssembly;
var fileName = FindFile(name);
if (fileName == null)
return null;
var cacheKey = fileName;
if (_cache.TryGetValue(cacheKey, out var result))
return result;
parameters.AssemblyResolver = this;
var ms = MemoryStreamFor(fileName);
var pdb = fileName + ".pdb";
if (File.Exists(pdb))
parameters.SymbolStream = MemoryStreamFor(pdb);
var assemblyDefinition = AssemblyDefinition.ReadAssembly(ms, parameters);
_cache.Add(cacheKey, assemblyDefinition);
return assemblyDefinition;
}
}
private string FindFile(AssemblyNameReference name)
{
if (_referenceToPathMap.TryGetValue(name.Name, out var paths))
{
if (paths.Count == 1)
{
var enumerator = paths.GetEnumerator();
// enumerators begin before the first element
enumerator.MoveNext();
return enumerator.Current;
}
// If we have more than one assembly with the same name loaded we now need to figure out which one
// is being requested based on the AssemblyNameReference
foreach (var path in paths)
{
var onDiskAssemblyName = AssemblyName.GetAssemblyName(path);
if (onDiskAssemblyName.FullName == name.FullName)
return path;
}
throw new ArgumentException($"Tried to resolve a reference in assembly '{name.FullName}' however the assembly could not be found. Known references which did not match: \n{string.Join("\n",paths)}");
}
// Unfortunately the current ICompiledAssembly API only provides direct references.
// It is very much possible that a postprocessor ends up investigating a type in a directly
// referenced assembly, that contains a field that is not in a directly referenced assembly.
// if we don't do anything special for that situation, it will fail to resolve. We should fix this
// in the ILPostProcessing api. As a workaround, we rely on the fact here that the indirect references
// are always located next to direct references, so we search in all directories of direct references we
// got passed, and if we find the file in there, we resolve to it.
foreach (var parentDir in _referenceDirectories)
{
var candidate = Path.Combine(parentDir, name.Name + ".dll");
if (File.Exists(candidate))
{
if (!_referenceToPathMap.TryGetValue(candidate, out var referencePaths))
{
referencePaths = new HashSet<string>();
_referenceToPathMap.Add(candidate, referencePaths);
}
referencePaths.Add(candidate);
return candidate;
}
}
return null;
}
static MemoryStream MemoryStreamFor(string fileName)
{
return Retry(10, TimeSpan.FromSeconds(1), () => {
byte[] byteArray;
using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
byteArray = new byte[fs.Length];
var readLength = fs.Read(byteArray, 0, (int)fs.Length);
if (readLength != fs.Length)
throw new InvalidOperationException("File read length is not full length of file.");
}
return new MemoryStream(byteArray);
});
}
private static MemoryStream Retry(int retryCount, TimeSpan waitTime, Func<MemoryStream> func)
{
try
{
return func();
}
catch (IOException)
{
if (retryCount == 0)
throw;
Console.WriteLine($"Caught IO Exception, trying {retryCount} more times");
Thread.Sleep(waitTime);
return Retry(retryCount - 1, waitTime, func);
}
}
public void AddAssemblyDefinitionBeingOperatedOn(AssemblyDefinition assemblyDefinition)
{
_selfAssembly = assemblyDefinition;
}
}
internal static AssemblyDefinition AssemblyDefinitionFor(ICompiledAssembly compiledAssembly)
{
var resolver = new PostProcessorAssemblyResolver(compiledAssembly);
var readerParameters = new ReaderParameters
{
SymbolStream = new MemoryStream(compiledAssembly.InMemoryAssembly.PdbData),
SymbolReaderProvider = new PortablePdbReaderProvider(),
AssemblyResolver = resolver,
ReflectionImporterProvider = new PostProcessorReflectionImporterProvider(),
ReadingMode = ReadingMode.Immediate
};
var peStream = new MemoryStream(compiledAssembly.InMemoryAssembly.PeData);
var assemblyDefinition = AssemblyDefinition.ReadAssembly(peStream, readerParameters);
//apparently, it will happen that when we ask to resolve a type that lives inside Unity.Jobs, and we
//are also postprocessing Unity.Jobs, type resolving will fail, because we do not actually try to resolve
//inside the assembly we are processing. Let's make sure we do that, so that we can use postprocessor features inside
//unity.Jobs itself as well.
resolver.AddAssemblyDefinitionBeingOperatedOn(assemblyDefinition);
return assemblyDefinition;
}
}
internal class PostProcessorReflectionImporterProvider : IReflectionImporterProvider
{
public IReflectionImporter GetReflectionImporter(ModuleDefinition module)
{
return new PostProcessorReflectionImporter(module);
}
}
internal class PostProcessorReflectionImporter : DefaultReflectionImporter
{
private const string SystemPrivateCoreLib = "System.Private.CoreLib";
private AssemblyNameReference _correctCorlib;
public PostProcessorReflectionImporter(ModuleDefinition module) : base(module)
{
_correctCorlib = default;
foreach (var a in module.AssemblyReferences)
{
if (a.Name == "mscorlib" || a.Name == "netstandard" || a.Name == SystemPrivateCoreLib)
{
_correctCorlib = a;
break;
}
}
}
public override AssemblyNameReference ImportReference(AssemblyName reference)
{
if (_correctCorlib != null && reference.Name == SystemPrivateCoreLib)
return _correctCorlib;
return base.ImportReference(reference);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9b544eddbc9bfd24fad9da6ddbe65962
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,22 @@
{
"name": "Unity.Collections.CodeGen",
"references": [
"Unity.Burst",
"Unity.Collections",
"Unity.Properties"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": true,
"overrideReferences": true,
"precompiledReferences": [
"Mono.Cecil.dll",
"Mono.Cecil.Rocks.dll",
"Mono.Cecil.Pdb.dll",
"Unity.IL2CPP",
"Unity.IL2CPP.Common"
],
"autoReferenced": false
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 8baa6eabecd47164e94a1eb92b18f394
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,46 @@
using System;
using System.IO;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Unity.CompilationPipeline.Common.Diagnostics;
namespace Unity.Jobs.CodeGen
{
static class InternalCompilerError
{
public static DiagnosticMessage DCICE300(TypeReference producerReference, TypeReference jobStructType, Exception ex)
{
return UserError.MakeError(nameof(DCICE300), $"Unexpected error while generating automatic registration for job provider {producerReference.FullName} via job struct {jobStructType.FullName}. Please report this error.\nException: {ex.Message}");
}
}
static class UserError
{
public static DiagnosticMessage DC3001(TypeReference type)
{
return MakeError(nameof(DC3001), $"{type.FullName}: [RegisterGenericJobType] requires an instance of a generic value type");
}
static DiagnosticMessage MakeInternal(DiagnosticType type, string errorCode, string messageData)
{
var result = new DiagnosticMessage {Column = 0, Line = 0, DiagnosticType = type, File = ""};
if (errorCode.Contains("ICE"))
{
messageData = messageData + " Seeing this error indicates a bug in the DOTS Job code-generators. We'd appreciate a bug report (About->Report a Bug...). Thnx! <3";
}
var errorType = type == DiagnosticType.Error ? "error" : "warning";
messageData = $"{errorType} {errorCode}: {messageData}";
result.MessageData = messageData;
return result;
}
public static DiagnosticMessage MakeError(string errorCode, string messageData)
{
return MakeInternal(DiagnosticType.Error, errorCode, messageData);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2d53df25c7f81aa419ea121140c42d6b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: