Skip to content

Commit b84426a

Browse files
authored
fix: RPC ILPP generating invalid IL code when using this instead of this ref for the FastBufferReader/FastBufferWriter parameter of an extension method. (#1393)
* fix: RPC ILPP generating invalid IL code when using `this` instead of `this ref` for the FastBufferReader/FastBufferWriter parameter of an extension method. Also updated the test so both `this` and `this ref` are exercised - the documentation says to use `this`, but `this ref` was what worked... so for backward compatibility both have to be supported. * Changelog * standards fix
1 parent 19b34f1 commit b84426a

File tree

3 files changed

+189
-34
lines changed

3 files changed

+189
-34
lines changed

com.unity.netcode.gameobjects/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
1313
### Fixed
1414

1515
- Fixed in-scene NetworkObjects that are moved into the DDOL scene not getting restored to their original active state (enabled/disabled) after a full scene transition (#1354)
16+
- Fixed invalid IL code being generated when using `this` instead of `this ref` for the FastBufferReader/FastBufferWriter parameter of an extension method. (#1393)
1617
- Fixed an issue where if you are running as a server (not host) the LoadEventCompleted and UnloadEventCompleted events would fire early by the NetworkSceneManager (#1379)
1718

1819
### Changed

com.unity.netcode.gameobjects/Editor/CodeGen/NetworkBehaviourILPP.cs

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -575,21 +575,28 @@ private MethodReference GetFastBufferWriterWriteMethod(string name, TypeReferenc
575575
{
576576
if (method.GenericParameters[0].HasConstraints)
577577
{
578+
var meetsConstraints = true;
578579
foreach (var constraint in method.GenericParameters[0].Constraints)
579580
{
580581
var resolvedConstraint = constraint.Resolve();
581582

582583
if (
583584
(resolvedConstraint.IsInterface &&
584-
checkType.HasInterface(resolvedConstraint.FullName))
585+
!checkType.HasInterface(resolvedConstraint.FullName))
585586
|| (resolvedConstraint.IsClass &&
586-
checkType.Resolve().IsSubclassOf(resolvedConstraint.FullName)))
587+
!checkType.Resolve().IsSubclassOf(resolvedConstraint.FullName))
588+
|| (resolvedConstraint.Name == "ValueType" && !checkType.IsValueType))
587589
{
588-
var instanceMethod = new GenericInstanceMethod(method);
589-
instanceMethod.GenericArguments.Add(checkType);
590-
return instanceMethod;
590+
meetsConstraints = false;
591+
break;
591592
}
592593
}
594+
if (meetsConstraints)
595+
{
596+
var instanceMethod = new GenericInstanceMethod(method);
597+
instanceMethod.GenericArguments.Add(checkType);
598+
return instanceMethod;
599+
}
593600
}
594601
}
595602
}
@@ -970,17 +977,23 @@ private void InjectWriteAndCallBlocks(MethodDefinition methodDefinition, CustomA
970977
// writer.WriteValueSafe(param) for value types, OR
971978
// writer.WriteValueSafe(param, -1, 0) for arrays of value types, OR
972979
// writer.WriteValueSafe(param, false) for strings
973-
instructions.Add(processor.Create(OpCodes.Ldloca, serializerLocIdx));
974980
var method = methodRef.Resolve();
975981
var checkParameter = method.Parameters[0];
976982
var isExtensionMethod = false;
977-
if (checkParameter.ParameterType.Resolve() ==
978-
m_FastBufferWriter_TypeRef.MakeByReferenceType().Resolve())
983+
if (methodRef.Resolve().DeclaringType != m_FastBufferWriter_TypeRef.Resolve())
979984
{
980985
isExtensionMethod = true;
981986
checkParameter = method.Parameters[1];
982987
}
983-
if (checkParameter.IsIn)
988+
if (!isExtensionMethod || method.Parameters[0].ParameterType.IsByReference)
989+
{
990+
instructions.Add(processor.Create(OpCodes.Ldloca, serializerLocIdx));
991+
}
992+
else
993+
{
994+
instructions.Add(processor.Create(OpCodes.Ldloc, serializerLocIdx));
995+
}
996+
if (checkParameter.IsIn || checkParameter.IsOut || checkParameter.ParameterType.IsByReference)
984997
{
985998
instructions.Add(processor.Create(OpCodes.Ldarga, paramIndex + 1));
986999
}
@@ -1291,7 +1304,18 @@ private MethodDefinition GenerateStaticHandler(MethodDefinition methodDefinition
12911304
if (foundMethodRef)
12921305
{
12931306
// reader.ReadValueSafe(out localVar);
1294-
processor.Emit(OpCodes.Ldarga, 1);
1307+
1308+
var checkParameter = methodRef.Resolve().Parameters[0];
1309+
1310+
var isExtensionMethod = methodRef.Resolve().DeclaringType != m_FastBufferReader_TypeRef.Resolve();
1311+
if (!isExtensionMethod || checkParameter.ParameterType.IsByReference)
1312+
{
1313+
processor.Emit(OpCodes.Ldarga, 1);
1314+
}
1315+
else
1316+
{
1317+
processor.Emit(OpCodes.Ldarg, 1);
1318+
}
12951319
processor.Emit(OpCodes.Ldloca, localIndex);
12961320
if (paramType == typeSystem.String)
12971321
{

0 commit comments

Comments
 (0)