Readers: remove static WeavingFailed references

This commit is contained in:
vis2k 2021-08-20 21:25:56 +08:00
parent c358358f1d
commit 2a1929f7f1
8 changed files with 62 additions and 62 deletions

View File

@ -79,7 +79,7 @@ protected static void InvokeCmdCmdThrust(NetworkBehaviour obj, NetworkReader rea
((ShipControl)obj).CmdThrust(reader.ReadSingle(), (int)reader.ReadPackedUInt32()); ((ShipControl)obj).CmdThrust(reader.ReadSingle(), (int)reader.ReadPackedUInt32());
} }
*/ */
public static MethodDefinition ProcessCommandInvoke(WeaverTypes weaverTypes, Readers readers, Logger Log, TypeDefinition td, MethodDefinition method, MethodDefinition cmdCallFunc) public static MethodDefinition ProcessCommandInvoke(WeaverTypes weaverTypes, Readers readers, Logger Log, TypeDefinition td, MethodDefinition method, MethodDefinition cmdCallFunc, ref bool WeavingFailed)
{ {
MethodDefinition cmd = new MethodDefinition(Weaver.InvokeRpcPrefix + method.Name, MethodDefinition cmd = new MethodDefinition(Weaver.InvokeRpcPrefix + method.Name,
MethodAttributes.Family | MethodAttributes.Static | MethodAttributes.HideBySig, MethodAttributes.Family | MethodAttributes.Static | MethodAttributes.HideBySig,
@ -94,7 +94,7 @@ public static MethodDefinition ProcessCommandInvoke(WeaverTypes weaverTypes, Rea
worker.Emit(OpCodes.Ldarg_0); worker.Emit(OpCodes.Ldarg_0);
worker.Emit(OpCodes.Castclass, td); worker.Emit(OpCodes.Castclass, td);
if (!NetworkBehaviourProcessor.ReadArguments(method, readers, Log, worker, RemoteCallType.Command)) if (!NetworkBehaviourProcessor.ReadArguments(method, readers, Log, worker, RemoteCallType.Command, ref WeavingFailed))
return null; return null;
AddSenderConnection(method, worker); AddSenderConnection(method, worker);

View File

@ -576,7 +576,7 @@ void DeserializeNetworkIdentityField(WeaverTypes weaverTypes, FieldDefinition sy
// reader. for 'reader.Read()' below // reader. for 'reader.Read()' below
worker.Emit(OpCodes.Ldarg_1); worker.Emit(OpCodes.Ldarg_1);
// Read() // Read()
worker.Emit(OpCodes.Call, readers.GetReadFunc(weaverTypes.Import<uint>())); worker.Emit(OpCodes.Call, readers.GetReadFunc(weaverTypes.Import<uint>(), ref WeavingFailed));
// netId // netId
worker.Emit(OpCodes.Stfld, netIdField); worker.Emit(OpCodes.Stfld, netIdField);
@ -677,7 +677,7 @@ void DeserializeNetworkBehaviourField(WeaverTypes weaverTypes, FieldDefinition s
// reader. for 'reader.Read()' below // reader. for 'reader.Read()' below
worker.Emit(OpCodes.Ldarg_1); worker.Emit(OpCodes.Ldarg_1);
// Read() // Read()
worker.Emit(OpCodes.Call, readers.GetReadFunc(weaverTypes.Import<NetworkBehaviour.NetworkBehaviourSyncVar>())); worker.Emit(OpCodes.Call, readers.GetReadFunc(weaverTypes.Import<NetworkBehaviour.NetworkBehaviourSyncVar>(), ref WeavingFailed));
// netId // netId
worker.Emit(OpCodes.Stfld, netIdField); worker.Emit(OpCodes.Stfld, netIdField);
@ -741,7 +741,7 @@ void DeserializeNormalField(WeaverTypes weaverTypes, FieldDefinition syncVar, IL
} }
*/ */
MethodReference readFunc = readers.GetReadFunc(syncVar.FieldType); MethodReference readFunc = readers.GetReadFunc(syncVar.FieldType, ref WeavingFailed);
if (readFunc == null) if (readFunc == null)
{ {
Log.Error($"{syncVar.Name} has unsupported type. Use a supported Mirror type instead", syncVar); Log.Error($"{syncVar.Name} has unsupported type. Use a supported Mirror type instead", syncVar);
@ -861,7 +861,7 @@ void GenerateDeSerialization(ref bool WeavingFailed)
// get dirty bits // get dirty bits
serWorker.Append(serWorker.Create(OpCodes.Ldarg_1)); serWorker.Append(serWorker.Create(OpCodes.Ldarg_1));
serWorker.Append(serWorker.Create(OpCodes.Call, readers.GetReadFunc(weaverTypes.Import<ulong>()))); serWorker.Append(serWorker.Create(OpCodes.Call, readers.GetReadFunc(weaverTypes.Import<ulong>(), ref WeavingFailed)));
serWorker.Append(serWorker.Create(OpCodes.Stloc_0)); serWorker.Append(serWorker.Create(OpCodes.Stloc_0));
// conditionally read each syncvar // conditionally read each syncvar
@ -891,7 +891,7 @@ void GenerateDeSerialization(ref bool WeavingFailed)
netBehaviourSubclass.Methods.Add(serialize); netBehaviourSubclass.Methods.Add(serialize);
} }
public static bool ReadArguments(MethodDefinition method, Readers readers, Logger Log, ILProcessor worker, RemoteCallType callType) public static bool ReadArguments(MethodDefinition method, Readers readers, Logger Log, ILProcessor worker, RemoteCallType callType, ref bool WeavingFailed)
{ {
// read each argument // read each argument
// example result // example result
@ -921,7 +921,7 @@ public static bool ReadArguments(MethodDefinition method, Readers readers, Logge
} }
MethodReference readFunc = readers.GetReadFunc(param.ParameterType); MethodReference readFunc = readers.GetReadFunc(param.ParameterType, ref WeavingFailed);
if (readFunc == null) if (readFunc == null)
{ {
@ -1125,7 +1125,7 @@ void ProcessClientRpc(HashSet<string> names, MethodDefinition md, CustomAttribut
// need null check here because ProcessRpcCall returns null if it can't write all the args // need null check here because ProcessRpcCall returns null if it can't write all the args
if (rpcCallFunc == null) { return; } if (rpcCallFunc == null) { return; }
MethodDefinition rpcFunc = RpcProcessor.ProcessRpcInvoke(weaverTypes, writers, readers, Log, netBehaviourSubclass, md, rpcCallFunc); MethodDefinition rpcFunc = RpcProcessor.ProcessRpcInvoke(weaverTypes, writers, readers, Log, netBehaviourSubclass, md, rpcCallFunc, ref WeavingFailed);
if (rpcFunc != null) if (rpcFunc != null)
{ {
clientRpcInvocationFuncs.Add(rpcFunc); clientRpcInvocationFuncs.Add(rpcFunc);
@ -1155,7 +1155,7 @@ void ProcessTargetRpc(HashSet<string> names, MethodDefinition md, CustomAttribut
MethodDefinition rpcCallFunc = TargetRpcProcessor.ProcessTargetRpcCall(weaverTypes, writers, Log, netBehaviourSubclass, md, targetRpcAttr, ref WeavingFailed); MethodDefinition rpcCallFunc = TargetRpcProcessor.ProcessTargetRpcCall(weaverTypes, writers, Log, netBehaviourSubclass, md, targetRpcAttr, ref WeavingFailed);
MethodDefinition rpcFunc = TargetRpcProcessor.ProcessTargetRpcInvoke(weaverTypes, readers, Log, netBehaviourSubclass, md, rpcCallFunc); MethodDefinition rpcFunc = TargetRpcProcessor.ProcessTargetRpcInvoke(weaverTypes, readers, Log, netBehaviourSubclass, md, rpcCallFunc, ref WeavingFailed);
if (rpcFunc != null) if (rpcFunc != null)
{ {
targetRpcInvocationFuncs.Add(rpcFunc); targetRpcInvocationFuncs.Add(rpcFunc);
@ -1192,7 +1192,7 @@ void ProcessCommand(HashSet<string> names, MethodDefinition md, CustomAttribute
MethodDefinition cmdCallFunc = CommandProcessor.ProcessCommandCall(weaverTypes, writers, Log, netBehaviourSubclass, md, commandAttr, ref WeavingFailed); MethodDefinition cmdCallFunc = CommandProcessor.ProcessCommandCall(weaverTypes, writers, Log, netBehaviourSubclass, md, commandAttr, ref WeavingFailed);
MethodDefinition cmdFunc = CommandProcessor.ProcessCommandInvoke(weaverTypes, readers, Log, netBehaviourSubclass, md, cmdCallFunc); MethodDefinition cmdFunc = CommandProcessor.ProcessCommandInvoke(weaverTypes, readers, Log, netBehaviourSubclass, md, cmdCallFunc, ref WeavingFailed);
if (cmdFunc != null) if (cmdFunc != null)
{ {
commandInvocationFuncs.Add(cmdFunc); commandInvocationFuncs.Add(cmdFunc);

View File

@ -11,7 +11,7 @@ namespace Mirror.Weaver
{ {
public static class ReaderWriterProcessor public static class ReaderWriterProcessor
{ {
public static bool Process(AssemblyDefinition CurrentAssembly, Writers writers, Readers readers) public static bool Process(AssemblyDefinition CurrentAssembly, Writers writers, Readers readers, ref bool WeavingFailed)
{ {
foreach (Assembly unityAsm in CompilationPipeline.GetAssemblies()) foreach (Assembly unityAsm in CompilationPipeline.GetAssemblies())
{ {
@ -20,15 +20,15 @@ public static bool Process(AssemblyDefinition CurrentAssembly, Writers writers,
using (DefaultAssemblyResolver asmResolver = new DefaultAssemblyResolver()) using (DefaultAssemblyResolver asmResolver = new DefaultAssemblyResolver())
using (AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(unityAsm.outputPath, new ReaderParameters { ReadWrite = false, ReadSymbols = false, AssemblyResolver = asmResolver })) using (AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(unityAsm.outputPath, new ReaderParameters { ReadWrite = false, ReadSymbols = false, AssemblyResolver = asmResolver }))
{ {
ProcessAssemblyClasses(CurrentAssembly, assembly, writers, readers); ProcessAssemblyClasses(CurrentAssembly, assembly, writers, readers, ref WeavingFailed);
} }
} }
} }
return ProcessAssemblyClasses(CurrentAssembly, CurrentAssembly, writers, readers); return ProcessAssemblyClasses(CurrentAssembly, CurrentAssembly, writers, readers, ref WeavingFailed);
} }
static bool ProcessAssemblyClasses(AssemblyDefinition CurrentAssembly, AssemblyDefinition assembly, Writers writers, Readers readers) static bool ProcessAssemblyClasses(AssemblyDefinition CurrentAssembly, AssemblyDefinition assembly, Writers writers, Readers readers, ref bool WeavingFailed)
{ {
bool modified = false; bool modified = false;
foreach (TypeDefinition klass in assembly.MainModule.Types) foreach (TypeDefinition klass in assembly.MainModule.Types)
@ -46,24 +46,24 @@ static bool ProcessAssemblyClasses(AssemblyDefinition CurrentAssembly, AssemblyD
foreach (TypeDefinition klass in assembly.MainModule.Types) foreach (TypeDefinition klass in assembly.MainModule.Types)
{ {
// if assembly has any network message then it is modified // if assembly has any network message then it is modified
modified |= LoadMessageReadWriter(CurrentAssembly.MainModule, writers, readers, klass); modified |= LoadMessageReadWriter(CurrentAssembly.MainModule, writers, readers, klass, ref WeavingFailed);
} }
return modified; return modified;
} }
static bool LoadMessageReadWriter(ModuleDefinition module, Writers writers, Readers readers, TypeDefinition klass) static bool LoadMessageReadWriter(ModuleDefinition module, Writers writers, Readers readers, TypeDefinition klass, ref bool WeavingFailed)
{ {
bool modified = false; bool modified = false;
if (!klass.IsAbstract && !klass.IsInterface && klass.ImplementsInterface<NetworkMessage>()) if (!klass.IsAbstract && !klass.IsInterface && klass.ImplementsInterface<NetworkMessage>())
{ {
readers.GetReadFunc(module.ImportReference(klass)); readers.GetReadFunc(module.ImportReference(klass), ref WeavingFailed);
writers.GetWriteFunc(module.ImportReference(klass)); writers.GetWriteFunc(module.ImportReference(klass));
modified = true; modified = true;
} }
foreach (TypeDefinition td in klass.NestedTypes) foreach (TypeDefinition td in klass.NestedTypes)
{ {
modified |= LoadMessageReadWriter(module, writers, readers, td); modified |= LoadMessageReadWriter(module, writers, readers, td, ref WeavingFailed);
} }
return modified; return modified;
} }

View File

@ -6,7 +6,7 @@ namespace Mirror.Weaver
// Processes [Rpc] methods in NetworkBehaviour // Processes [Rpc] methods in NetworkBehaviour
public static class RpcProcessor public static class RpcProcessor
{ {
public static MethodDefinition ProcessRpcInvoke(WeaverTypes weaverTypes, Writers writers, Readers readers, Logger Log, TypeDefinition td, MethodDefinition md, MethodDefinition rpcCallFunc) public static MethodDefinition ProcessRpcInvoke(WeaverTypes weaverTypes, Writers writers, Readers readers, Logger Log, TypeDefinition td, MethodDefinition md, MethodDefinition rpcCallFunc, ref bool WeavingFailed)
{ {
MethodDefinition rpc = new MethodDefinition( MethodDefinition rpc = new MethodDefinition(
Weaver.InvokeRpcPrefix + md.Name, Weaver.InvokeRpcPrefix + md.Name,
@ -22,7 +22,7 @@ public static MethodDefinition ProcessRpcInvoke(WeaverTypes weaverTypes, Writers
worker.Emit(OpCodes.Ldarg_0); worker.Emit(OpCodes.Ldarg_0);
worker.Emit(OpCodes.Castclass, td); worker.Emit(OpCodes.Castclass, td);
if (!NetworkBehaviourProcessor.ReadArguments(md, readers, Log, worker, RemoteCallType.ClientRpc)) if (!NetworkBehaviourProcessor.ReadArguments(md, readers, Log, worker, RemoteCallType.ClientRpc, ref WeavingFailed))
return null; return null;
// invoke actual command function // invoke actual command function

View File

@ -22,7 +22,7 @@ public static List<FieldDefinition> FindSyncObjectsFields(Writers writers, Reade
continue; continue;
} }
GenerateReadersAndWriters(writers, readers, fd.FieldType); GenerateReadersAndWriters(writers, readers, fd.FieldType, ref WeavingFailed);
syncObjects.Add(fd); syncObjects.Add(fd);
} }
@ -33,7 +33,7 @@ public static List<FieldDefinition> FindSyncObjectsFields(Writers writers, Reade
} }
// Generates serialization methods for synclists // Generates serialization methods for synclists
static void GenerateReadersAndWriters(Writers writers, Readers readers, TypeReference tr) static void GenerateReadersAndWriters(Writers writers, Readers readers, TypeReference tr, ref bool WeavingFailed)
{ {
if (tr is GenericInstanceType genericInstance) if (tr is GenericInstanceType genericInstance)
{ {
@ -41,7 +41,7 @@ static void GenerateReadersAndWriters(Writers writers, Readers readers, TypeRefe
{ {
if (!argument.IsGenericParameter) if (!argument.IsGenericParameter)
{ {
readers.GetReadFunc(argument); readers.GetReadFunc(argument, ref WeavingFailed);
writers.GetWriteFunc(argument); writers.GetWriteFunc(argument);
} }
} }
@ -49,7 +49,7 @@ static void GenerateReadersAndWriters(Writers writers, Readers readers, TypeRefe
if (tr != null) if (tr != null)
{ {
GenerateReadersAndWriters(writers, readers, tr.Resolve().BaseType); GenerateReadersAndWriters(writers, readers, tr.Resolve().BaseType, ref WeavingFailed);
} }
} }
} }

View File

@ -13,7 +13,7 @@ public static bool HasNetworkConnectionParameter(MethodDefinition md)
md.Parameters[0].ParameterType.Is<NetworkConnection>(); md.Parameters[0].ParameterType.Is<NetworkConnection>();
} }
public static MethodDefinition ProcessTargetRpcInvoke(WeaverTypes weaverTypes, Readers readers, Logger Log, TypeDefinition td, MethodDefinition md, MethodDefinition rpcCallFunc) public static MethodDefinition ProcessTargetRpcInvoke(WeaverTypes weaverTypes, Readers readers, Logger Log, TypeDefinition td, MethodDefinition md, MethodDefinition rpcCallFunc, ref bool WeavingFailed)
{ {
MethodDefinition rpc = new MethodDefinition(Weaver.InvokeRpcPrefix + md.Name, MethodAttributes.Family | MethodDefinition rpc = new MethodDefinition(Weaver.InvokeRpcPrefix + md.Name, MethodAttributes.Family |
MethodAttributes.Static | MethodAttributes.Static |
@ -45,7 +45,7 @@ public static MethodDefinition ProcessTargetRpcInvoke(WeaverTypes weaverTypes, R
} }
// process reader parameters and skip first one if first one is NetworkConnection // process reader parameters and skip first one if first one is NetworkConnection
if (!NetworkBehaviourProcessor.ReadArguments(md, readers, Log, worker, RemoteCallType.TargetRpc)) if (!NetworkBehaviourProcessor.ReadArguments(md, readers, Log, worker, RemoteCallType.TargetRpc, ref WeavingFailed))
return null; return null;
// invoke actual command function // invoke actual command function

View File

@ -49,7 +49,7 @@ void RegisterReadFunc(TypeReference typeReference, MethodDefinition newReaderFun
} }
// Finds existing reader for type, if non exists trys to create one // Finds existing reader for type, if non exists trys to create one
public MethodReference GetReadFunc(TypeReference variable) public MethodReference GetReadFunc(TypeReference variable, ref bool WeavingFailed)
{ {
if (readFuncs.TryGetValue(variable, out MethodReference foundFunc)) if (readFuncs.TryGetValue(variable, out MethodReference foundFunc))
{ {
@ -58,11 +58,11 @@ public MethodReference GetReadFunc(TypeReference variable)
else else
{ {
TypeReference importedVariable = assembly.MainModule.ImportReference(variable); TypeReference importedVariable = assembly.MainModule.ImportReference(variable);
return GenerateReader(importedVariable); return GenerateReader(importedVariable, ref WeavingFailed);
} }
} }
MethodReference GenerateReader(TypeReference variableReference) MethodReference GenerateReader(TypeReference variableReference, ref bool WeavingFailed)
{ {
// Arrays are special, if we resolve them, we get the element type, // Arrays are special, if we resolve them, we get the element type,
// so the following ifs might choke on it for scriptable objects // so the following ifs might choke on it for scriptable objects
@ -73,11 +73,11 @@ MethodReference GenerateReader(TypeReference variableReference)
if (variableReference.IsMultidimensionalArray()) if (variableReference.IsMultidimensionalArray())
{ {
Log.Error($"{variableReference.Name} is an unsupported type. Multidimensional arrays are not supported", variableReference); Log.Error($"{variableReference.Name} is an unsupported type. Multidimensional arrays are not supported", variableReference);
Weaver.WeavingFailed = true; WeavingFailed = true;
return null; return null;
} }
return GenerateReadCollection(variableReference, variableReference.GetElementType(), nameof(NetworkReaderExtensions.ReadArray)); return GenerateReadCollection(variableReference, variableReference.GetElementType(), nameof(NetworkReaderExtensions.ReadArray), ref WeavingFailed);
} }
TypeDefinition variableDefinition = variableReference.Resolve(); TypeDefinition variableDefinition = variableReference.Resolve();
@ -86,32 +86,32 @@ MethodReference GenerateReader(TypeReference variableReference)
if (variableDefinition == null) if (variableDefinition == null)
{ {
Log.Error($"{variableReference.Name} is not a supported type", variableReference); Log.Error($"{variableReference.Name} is not a supported type", variableReference);
Weaver.WeavingFailed = true; WeavingFailed = true;
return null; return null;
} }
else if (variableReference.IsByReference) else if (variableReference.IsByReference)
{ {
// error?? // error??
Log.Error($"Cannot pass type {variableReference.Name} by reference", variableReference); Log.Error($"Cannot pass type {variableReference.Name} by reference", variableReference);
Weaver.WeavingFailed = true; WeavingFailed = true;
return null; return null;
} }
// use existing func for known types // use existing func for known types
if (variableDefinition.IsEnum) if (variableDefinition.IsEnum)
{ {
return GenerateEnumReadFunc(variableReference); return GenerateEnumReadFunc(variableReference, ref WeavingFailed);
} }
else if (variableDefinition.Is(typeof(ArraySegment<>))) else if (variableDefinition.Is(typeof(ArraySegment<>)))
{ {
return GenerateArraySegmentReadFunc(variableReference); return GenerateArraySegmentReadFunc(variableReference, ref WeavingFailed);
} }
else if (variableDefinition.Is(typeof(List<>))) else if (variableDefinition.Is(typeof(List<>)))
{ {
GenericInstanceType genericInstance = (GenericInstanceType)variableReference; GenericInstanceType genericInstance = (GenericInstanceType)variableReference;
TypeReference elementType = genericInstance.GenericArguments[0]; TypeReference elementType = genericInstance.GenericArguments[0];
return GenerateReadCollection(variableReference, elementType, nameof(NetworkReaderExtensions.ReadList)); return GenerateReadCollection(variableReference, elementType, nameof(NetworkReaderExtensions.ReadList), ref WeavingFailed);
} }
else if (variableReference.IsDerivedFrom<NetworkBehaviour>()) else if (variableReference.IsDerivedFrom<NetworkBehaviour>())
{ {
@ -122,41 +122,41 @@ MethodReference GenerateReader(TypeReference variableReference)
if (variableDefinition.IsDerivedFrom<UnityEngine.Component>()) if (variableDefinition.IsDerivedFrom<UnityEngine.Component>())
{ {
Log.Error($"Cannot generate reader for component type {variableReference.Name}. Use a supported type or provide a custom reader", variableReference); Log.Error($"Cannot generate reader for component type {variableReference.Name}. Use a supported type or provide a custom reader", variableReference);
Weaver.WeavingFailed = true; WeavingFailed = true;
return null; return null;
} }
if (variableReference.Is<UnityEngine.Object>()) if (variableReference.Is<UnityEngine.Object>())
{ {
Log.Error($"Cannot generate reader for {variableReference.Name}. Use a supported type or provide a custom reader", variableReference); Log.Error($"Cannot generate reader for {variableReference.Name}. Use a supported type or provide a custom reader", variableReference);
Weaver.WeavingFailed = true; WeavingFailed = true;
return null; return null;
} }
if (variableReference.Is<UnityEngine.ScriptableObject>()) if (variableReference.Is<UnityEngine.ScriptableObject>())
{ {
Log.Error($"Cannot generate reader for {variableReference.Name}. Use a supported type or provide a custom reader", variableReference); Log.Error($"Cannot generate reader for {variableReference.Name}. Use a supported type or provide a custom reader", variableReference);
Weaver.WeavingFailed = true; WeavingFailed = true;
return null; return null;
} }
if (variableDefinition.HasGenericParameters) if (variableDefinition.HasGenericParameters)
{ {
Log.Error($"Cannot generate reader for generic variable {variableReference.Name}. Use a supported type or provide a custom reader", variableReference); Log.Error($"Cannot generate reader for generic variable {variableReference.Name}. Use a supported type or provide a custom reader", variableReference);
Weaver.WeavingFailed = true; WeavingFailed = true;
return null; return null;
} }
if (variableDefinition.IsInterface) if (variableDefinition.IsInterface)
{ {
Log.Error($"Cannot generate reader for interface {variableReference.Name}. Use a supported type or provide a custom reader", variableReference); Log.Error($"Cannot generate reader for interface {variableReference.Name}. Use a supported type or provide a custom reader", variableReference);
Weaver.WeavingFailed = true; WeavingFailed = true;
return null; return null;
} }
if (variableDefinition.IsAbstract) if (variableDefinition.IsAbstract)
{ {
Log.Error($"Cannot generate reader for abstract class {variableReference.Name}. Use a supported type or provide a custom reader", variableReference); Log.Error($"Cannot generate reader for abstract class {variableReference.Name}. Use a supported type or provide a custom reader", variableReference);
Weaver.WeavingFailed = true; WeavingFailed = true;
return null; return null;
} }
return GenerateClassOrStructReadFunction(variableReference); return GenerateClassOrStructReadFunction(variableReference, ref WeavingFailed);
} }
MethodReference GetNetworkBehaviourReader(TypeReference variableReference) MethodReference GetNetworkBehaviourReader(TypeReference variableReference)
@ -173,7 +173,7 @@ MethodReference GetNetworkBehaviourReader(TypeReference variableReference)
return readFunc; return readFunc;
} }
MethodDefinition GenerateEnumReadFunc(TypeReference variable) MethodDefinition GenerateEnumReadFunc(TypeReference variable, ref bool WeavingFailed)
{ {
MethodDefinition readerFunc = GenerateReaderFunction(variable); MethodDefinition readerFunc = GenerateReaderFunction(variable);
@ -182,14 +182,14 @@ MethodDefinition GenerateEnumReadFunc(TypeReference variable)
worker.Emit(OpCodes.Ldarg_0); worker.Emit(OpCodes.Ldarg_0);
TypeReference underlyingType = variable.Resolve().GetEnumUnderlyingType(); TypeReference underlyingType = variable.Resolve().GetEnumUnderlyingType();
MethodReference underlyingFunc = GetReadFunc(underlyingType); MethodReference underlyingFunc = GetReadFunc(underlyingType, ref WeavingFailed);
worker.Emit(OpCodes.Call, underlyingFunc); worker.Emit(OpCodes.Call, underlyingFunc);
worker.Emit(OpCodes.Ret); worker.Emit(OpCodes.Ret);
return readerFunc; return readerFunc;
} }
MethodDefinition GenerateArraySegmentReadFunc(TypeReference variable) MethodDefinition GenerateArraySegmentReadFunc(TypeReference variable, ref bool WeavingFailed)
{ {
GenericInstanceType genericInstance = (GenericInstanceType)variable; GenericInstanceType genericInstance = (GenericInstanceType)variable;
TypeReference elementType = genericInstance.GenericArguments[0]; TypeReference elementType = genericInstance.GenericArguments[0];
@ -201,7 +201,7 @@ MethodDefinition GenerateArraySegmentReadFunc(TypeReference variable)
// $array = reader.Read<[T]>() // $array = reader.Read<[T]>()
ArrayType arrayType = elementType.MakeArrayType(); ArrayType arrayType = elementType.MakeArrayType();
worker.Emit(OpCodes.Ldarg_0); worker.Emit(OpCodes.Ldarg_0);
worker.Emit(OpCodes.Call, GetReadFunc(arrayType)); worker.Emit(OpCodes.Call, GetReadFunc(arrayType, ref WeavingFailed));
// return new ArraySegment<T>($array); // return new ArraySegment<T>($array);
worker.Emit(OpCodes.Newobj, weaverTypes.ArraySegmentConstructorReference.MakeHostInstanceGeneric(assembly.MainModule, genericInstance)); worker.Emit(OpCodes.Newobj, weaverTypes.ArraySegmentConstructorReference.MakeHostInstanceGeneric(assembly.MainModule, genericInstance));
@ -227,11 +227,11 @@ MethodDefinition GenerateReaderFunction(TypeReference variable)
return readerFunc; return readerFunc;
} }
MethodDefinition GenerateReadCollection(TypeReference variable, TypeReference elementType, string readerFunction) MethodDefinition GenerateReadCollection(TypeReference variable, TypeReference elementType, string readerFunction, ref bool WeavingFailed)
{ {
MethodDefinition readerFunc = GenerateReaderFunction(variable); MethodDefinition readerFunc = GenerateReaderFunction(variable);
// generate readers for the element // generate readers for the element
GetReadFunc(elementType); GetReadFunc(elementType, ref WeavingFailed);
ModuleDefinition module = assembly.MainModule; ModuleDefinition module = assembly.MainModule;
TypeReference readerExtensions = module.ImportReference(typeof(NetworkReaderExtensions)); TypeReference readerExtensions = module.ImportReference(typeof(NetworkReaderExtensions));
@ -252,7 +252,7 @@ MethodDefinition GenerateReadCollection(TypeReference variable, TypeReference el
return readerFunc; return readerFunc;
} }
MethodDefinition GenerateClassOrStructReadFunction(TypeReference variable) MethodDefinition GenerateClassOrStructReadFunction(TypeReference variable, ref bool WeavingFailed)
{ {
MethodDefinition readerFunc = GenerateReaderFunction(variable); MethodDefinition readerFunc = GenerateReaderFunction(variable);
@ -264,23 +264,23 @@ MethodDefinition GenerateClassOrStructReadFunction(TypeReference variable)
TypeDefinition td = variable.Resolve(); TypeDefinition td = variable.Resolve();
if (!td.IsValueType) if (!td.IsValueType)
GenerateNullCheck(worker); GenerateNullCheck(worker, ref WeavingFailed);
CreateNew(variable, worker, td); CreateNew(variable, worker, td, ref WeavingFailed);
ReadAllFields(variable, worker); ReadAllFields(variable, worker, ref WeavingFailed);
worker.Emit(OpCodes.Ldloc_0); worker.Emit(OpCodes.Ldloc_0);
worker.Emit(OpCodes.Ret); worker.Emit(OpCodes.Ret);
return readerFunc; return readerFunc;
} }
void GenerateNullCheck(ILProcessor worker) void GenerateNullCheck(ILProcessor worker, ref bool WeavingFailed)
{ {
// if (!reader.ReadBoolean()) { // if (!reader.ReadBoolean()) {
// return null; // return null;
// } // }
worker.Emit(OpCodes.Ldarg_0); worker.Emit(OpCodes.Ldarg_0);
worker.Emit(OpCodes.Call, GetReadFunc(weaverTypes.Import<bool>())); worker.Emit(OpCodes.Call, GetReadFunc(weaverTypes.Import<bool>(), ref WeavingFailed));
Instruction labelEmptyArray = worker.Create(OpCodes.Nop); Instruction labelEmptyArray = worker.Create(OpCodes.Nop);
worker.Emit(OpCodes.Brtrue, labelEmptyArray); worker.Emit(OpCodes.Brtrue, labelEmptyArray);
@ -291,7 +291,7 @@ void GenerateNullCheck(ILProcessor worker)
} }
// Initialize the local variable with a new instance // Initialize the local variable with a new instance
void CreateNew(TypeReference variable, ILProcessor worker, TypeDefinition td) void CreateNew(TypeReference variable, ILProcessor worker, TypeDefinition td, ref bool WeavingFailed)
{ {
if (variable.IsValueType) if (variable.IsValueType)
{ {
@ -313,7 +313,7 @@ void CreateNew(TypeReference variable, ILProcessor worker, TypeDefinition td)
if (ctor == null) if (ctor == null)
{ {
Log.Error($"{variable.Name} can't be deserialized because it has no default constructor", variable); Log.Error($"{variable.Name} can't be deserialized because it has no default constructor", variable);
Weaver.WeavingFailed = true; WeavingFailed = true;
return; return;
} }
@ -324,14 +324,14 @@ void CreateNew(TypeReference variable, ILProcessor worker, TypeDefinition td)
} }
} }
void ReadAllFields(TypeReference variable, ILProcessor worker) void ReadAllFields(TypeReference variable, ILProcessor worker, ref bool WeavingFailed)
{ {
foreach (FieldDefinition field in variable.FindAllPublicFields()) foreach (FieldDefinition field in variable.FindAllPublicFields())
{ {
// mismatched ldloca/ldloc for struct/class combinations is invalid IL, which causes crash at runtime // mismatched ldloca/ldloc for struct/class combinations is invalid IL, which causes crash at runtime
OpCode opcode = variable.IsValueType ? OpCodes.Ldloca : OpCodes.Ldloc; OpCode opcode = variable.IsValueType ? OpCodes.Ldloca : OpCodes.Ldloc;
worker.Emit(opcode, 0); worker.Emit(opcode, 0);
MethodReference readFunc = GetReadFunc(field.FieldType); MethodReference readFunc = GetReadFunc(field.FieldType, ref WeavingFailed);
if (readFunc != null) if (readFunc != null)
{ {
worker.Emit(OpCodes.Ldarg_0); worker.Emit(OpCodes.Ldarg_0);
@ -340,7 +340,7 @@ void ReadAllFields(TypeReference variable, ILProcessor worker)
else else
{ {
Log.Error($"{field.Name} has an unsupported type", field); Log.Error($"{field.Name} has an unsupported type", field);
Weaver.WeavingFailed = true; WeavingFailed = true;
} }
FieldReference fieldRef = assembly.MainModule.ImportReference(field); FieldReference fieldRef = assembly.MainModule.ImportReference(field);

View File

@ -156,7 +156,7 @@ public static bool Weave(AssemblyDefinition asmDef)
System.Diagnostics.Stopwatch rwstopwatch = System.Diagnostics.Stopwatch.StartNew(); System.Diagnostics.Stopwatch rwstopwatch = System.Diagnostics.Stopwatch.StartNew();
// Need to track modified from ReaderWriterProcessor too because it could find custom read/write functions or create functions for NetworkMessages // Need to track modified from ReaderWriterProcessor too because it could find custom read/write functions or create functions for NetworkMessages
bool modified = ReaderWriterProcessor.Process(CurrentAssembly, writers, readers); bool modified = ReaderWriterProcessor.Process(CurrentAssembly, writers, readers, ref WeavingFailed);
rwstopwatch.Stop(); rwstopwatch.Stop();
Console.WriteLine($"Find all reader and writers took {rwstopwatch.ElapsedMilliseconds} milliseconds"); Console.WriteLine($"Find all reader and writers took {rwstopwatch.ElapsedMilliseconds} milliseconds");