Skip to content

Commit

Permalink
fix: don't convert null arrays to empty array (#913)
Browse files Browse the repository at this point in the history
* fix: don't convert null arrays to empty array

* Add comments with generated code

* Document array reader

* Improve comments a little bit
  • Loading branch information
paulpach authored and miwarnec committed Jun 19, 2019
1 parent 5ae379d commit dd758ca
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 25 deletions.
31 changes: 20 additions & 11 deletions Assets/Mirror/Editor/Weaver/Readers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,40 +151,48 @@ static MethodDefinition GenerateArrayReadFunc(TypeReference variable, int recurs

ILProcessor worker = readerFunc.Body.GetILProcessor();

// int length = reader.ReadPackedInt32();
worker.Append(worker.Create(OpCodes.Ldarg_0));
worker.Append(worker.Create(OpCodes.Call, Weaver.NetworkReadUInt16));
worker.Append(worker.Create(OpCodes.Call, Weaver.NetworkReaderReadPackedInt32));
worker.Append(worker.Create(OpCodes.Stloc_0));
worker.Append(worker.Create(OpCodes.Ldloc_0));

Instruction labelEmptyArray = worker.Create(OpCodes.Nop);
worker.Append(worker.Create(OpCodes.Brtrue, labelEmptyArray));

// return empty array
// if (length < 0) {
// return null
// }
worker.Append(worker.Create(OpCodes.Ldloc_0));
worker.Append(worker.Create(OpCodes.Ldc_I4_0));
worker.Append(worker.Create(OpCodes.Newarr, variable.GetElementType()));
Instruction labelEmptyArray = worker.Create(OpCodes.Nop);
worker.Append(worker.Create(OpCodes.Bge, labelEmptyArray));
// return null
worker.Append(worker.Create(OpCodes.Ldnull));
worker.Append(worker.Create(OpCodes.Ret));

// create the actual array
worker.Append(labelEmptyArray);


// T value = new T[length];
worker.Append(worker.Create(OpCodes.Ldloc_0));
worker.Append(worker.Create(OpCodes.Newarr, variable.GetElementType()));
worker.Append(worker.Create(OpCodes.Stloc_1));


// for (int i=0; i< length ; i++) {
worker.Append(worker.Create(OpCodes.Ldc_I4_0));
worker.Append(worker.Create(OpCodes.Stloc_2));

// loop start
Instruction labelHead = worker.Create(OpCodes.Nop);
worker.Append(worker.Create(OpCodes.Br, labelHead));

// loop body
Instruction labelBody = worker.Create(OpCodes.Nop);
worker.Append(labelBody);
// value[i] = reader.ReadT();
worker.Append(worker.Create(OpCodes.Ldloc_1));
worker.Append(worker.Create(OpCodes.Ldloc_2));
worker.Append(worker.Create(OpCodes.Ldelema, variable.GetElementType()));
worker.Append(worker.Create(OpCodes.Ldarg_0));
worker.Append(worker.Create(OpCodes.Call, elementReadFunc));
worker.Append(worker.Create(OpCodes.Stobj, variable.GetElementType()));


worker.Append(worker.Create(OpCodes.Ldloc_2));
worker.Append(worker.Create(OpCodes.Ldc_I4_1));
worker.Append(worker.Create(OpCodes.Add));
Expand All @@ -196,6 +204,7 @@ static MethodDefinition GenerateArrayReadFunc(TypeReference variable, int recurs
worker.Append(worker.Create(OpCodes.Ldloc_0));
worker.Append(worker.Create(OpCodes.Blt, labelBody));

// return value;
worker.Append(worker.Create(OpCodes.Ldloc_1));
worker.Append(worker.Create(OpCodes.Ret));
return readerFunc;
Expand Down
7 changes: 6 additions & 1 deletion Assets/Mirror/Editor/Weaver/Weaver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,11 @@ class Weaver
public static MethodReference NetworkServerGetLocalClientActive;
public static MethodReference NetworkClientGetActive;
public static MethodReference getBehaviourIsServer;
public static MethodReference NetworkReaderReadPackedInt32;
public static MethodReference NetworkReaderReadPackedUInt32;
public static MethodReference NetworkReaderReadPackedUInt64;
public static MethodReference NetworkWriterWritePackedUInt64;
public static MethodReference NetworkWriterWritePackedInt32;
public static MethodReference NetworkReaderReadPackedUInt64;

public static MethodReference NetworkReadUInt16;
public static MethodReference NetworkWriteUInt16;
Expand Down Expand Up @@ -309,11 +311,14 @@ static void SetupTargetTypes()

NetworkWriterWriteInt16 = Resolvers.ResolveMethodWithArg(NetworkWriterType, CurrentAssembly, "Write", int16Type);

NetworkReaderReadPackedInt32 = Resolvers.ResolveMethod(NetworkReaderType, CurrentAssembly, "ReadPackedInt32");
NetworkReaderReadPackedUInt32 = Resolvers.ResolveMethod(NetworkReaderType, CurrentAssembly, "ReadPackedUInt32");
NetworkReaderReadPackedUInt64 = Resolvers.ResolveMethod(NetworkReaderType, CurrentAssembly, "ReadPackedUInt64");

NetworkWriterWritePackedInt32 = Resolvers.ResolveMethod(NetworkWriterType, CurrentAssembly, "WritePackedInt32");
NetworkWriterWritePackedUInt64 = Resolvers.ResolveMethod(NetworkWriterType, CurrentAssembly, "WritePackedUInt64");


NetworkReadUInt16 = Resolvers.ResolveMethod(NetworkReaderType, CurrentAssembly, "ReadUInt16");
NetworkWriteUInt16 = Resolvers.ResolveMethodWithArg(NetworkWriterType, CurrentAssembly, "Write", uint16Type);

Expand Down
32 changes: 19 additions & 13 deletions Assets/Mirror/Editor/Weaver/Writers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -214,36 +214,38 @@ static MethodDefinition GenerateArrayWriteFunc(TypeReference variable, int recur
writerFunc.Parameters.Add(new ParameterDefinition("writer", ParameterAttributes.None, Weaver.CurrentAssembly.MainModule.ImportReference(Weaver.NetworkWriterType)));
writerFunc.Parameters.Add(new ParameterDefinition("value", ParameterAttributes.None, Weaver.CurrentAssembly.MainModule.ImportReference(variable)));

writerFunc.Body.Variables.Add(new VariableDefinition(Weaver.uint16Type));
writerFunc.Body.Variables.Add(new VariableDefinition(Weaver.uint16Type));
writerFunc.Body.Variables.Add(new VariableDefinition(Weaver.int32Type));
writerFunc.Body.Variables.Add(new VariableDefinition(Weaver.int32Type));
writerFunc.Body.InitLocals = true;

ILProcessor worker = writerFunc.Body.GetILProcessor();

// null check
// if (value == null)
// {
// writer.WritePackedInt32(-1);
// return;
// }
Instruction labelNull = worker.Create(OpCodes.Nop);
worker.Append(worker.Create(OpCodes.Ldarg_1));
worker.Append(worker.Create(OpCodes.Brtrue, labelNull));

worker.Append(worker.Create(OpCodes.Ldarg_0));
worker.Append(worker.Create(OpCodes.Ldc_I4_0));
worker.Append(worker.Create(OpCodes.Call, Weaver.NetworkWriteUInt16));
worker.Append(worker.Create(OpCodes.Ldc_I4_M1));
worker.Append(worker.Create(OpCodes.Call, Weaver.NetworkWriterWritePackedInt32));
worker.Append(worker.Create(OpCodes.Ret));

// setup array length local variable
// int length = value.Length;
worker.Append(labelNull);
worker.Append(worker.Create(OpCodes.Ldarg_1));
worker.Append(worker.Create(OpCodes.Ldlen));
worker.Append(worker.Create(OpCodes.Conv_I4));
worker.Append(worker.Create(OpCodes.Conv_U2));
worker.Append(worker.Create(OpCodes.Stloc_0));

//write length
// writer.WritePackedInt32(length);
worker.Append(worker.Create(OpCodes.Ldarg_0));
worker.Append(worker.Create(OpCodes.Ldloc_0));
worker.Append(worker.Create(OpCodes.Call, Weaver.NetworkWriteUInt16));
worker.Append(worker.Create(OpCodes.Call, Weaver.NetworkWriterWritePackedInt32));

// start loop
// for (int i=0; i< value.length; i++) {
worker.Append(worker.Create(OpCodes.Ldc_I4_0));
worker.Append(worker.Create(OpCodes.Stloc_1));
Instruction labelHead = worker.Create(OpCodes.Nop);
Expand All @@ -252,26 +254,30 @@ static MethodDefinition GenerateArrayWriteFunc(TypeReference variable, int recur
// loop body
Instruction labelBody = worker.Create(OpCodes.Nop);
worker.Append(labelBody);
// writer.Write(value[i]);
worker.Append(worker.Create(OpCodes.Ldarg_0));
worker.Append(worker.Create(OpCodes.Ldarg_1));
worker.Append(worker.Create(OpCodes.Ldloc_1));
worker.Append(worker.Create(OpCodes.Ldelema, variable.GetElementType()));
worker.Append(worker.Create(OpCodes.Ldobj, variable.GetElementType()));
worker.Append(worker.Create(OpCodes.Call, elementWriteFunc));


worker.Append(worker.Create(OpCodes.Ldloc_1));
worker.Append(worker.Create(OpCodes.Ldc_I4_1));
worker.Append(worker.Create(OpCodes.Add));
worker.Append(worker.Create(OpCodes.Conv_U2));
worker.Append(worker.Create(OpCodes.Stloc_1));

// loop while check

// end for loop
worker.Append(labelHead);
worker.Append(worker.Create(OpCodes.Ldloc_1));
worker.Append(worker.Create(OpCodes.Ldarg_1));
worker.Append(worker.Create(OpCodes.Ldlen));
worker.Append(worker.Create(OpCodes.Conv_I4));
worker.Append(worker.Create(OpCodes.Blt, labelBody));

// return
worker.Append(worker.Create(OpCodes.Ret));
return writerFunc;
}
Expand Down

0 comments on commit dd758ca

Please sign in to comment.