From: Michal Strehovský Date: Wed, 8 Feb 2023 06:34:39 +0000 (+0900) Subject: Fix handling of the generic byreflike constraint (#81684) X-Git-Tag: accepted/tizen/unified/riscv/20231226.055536~4165 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=600ddea4ddfd4006855b7bbf419cc8d685f6a939;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Fix handling of the generic byreflike constraint (#81684) Some support for NativeAOT was written in #67783 but the test didn't actually pass because of these missing pieces. --- diff --git a/src/coreclr/tools/Common/Compiler/CompilerTypeSystemContext.Validation.cs b/src/coreclr/tools/Common/Compiler/CompilerTypeSystemContext.Validation.cs index dcbccd6..8112602 100644 --- a/src/coreclr/tools/Common/Compiler/CompilerTypeSystemContext.Validation.cs +++ b/src/coreclr/tools/Common/Compiler/CompilerTypeSystemContext.Validation.cs @@ -149,8 +149,7 @@ namespace ILCompiler if (typeArg.IsByRef || typeArg.IsPointer || typeArg.IsFunctionPointer - || typeArg.IsVoid - || typeArg.IsByRefLike) + || typeArg.IsVoid) { ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadGeneral, type); } diff --git a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaGenericParameter.cs b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaGenericParameter.cs index 0ecf1c4..ee59976 100644 --- a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaGenericParameter.cs +++ b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaGenericParameter.cs @@ -103,7 +103,8 @@ namespace Internal.TypeSystem.Ecma { Debug.Assert((int)GenericConstraints.DefaultConstructorConstraint == (int)GenericParameterAttributes.DefaultConstructorConstraint); GenericParameter parameter = _module.MetadataReader.GetGenericParameter(_handle); - return (GenericConstraints)(parameter.Attributes & GenericParameterAttributes.SpecialConstraintMask); + const GenericParameterAttributes mask = GenericParameterAttributes.SpecialConstraintMask | (GenericParameterAttributes)GenericConstraints.AcceptByRefLike; + return (GenericConstraints)(parameter.Attributes & mask); } } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/RootingServiceProvider.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/RootingServiceProvider.cs index 443c463..12a590d 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/RootingServiceProvider.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/RootingServiceProvider.cs @@ -43,19 +43,26 @@ namespace ILCompiler public void AddReflectionRoot(TypeDesc type, string reason) { + _factory.TypeSystemContext.EnsureLoadableType(type); _rootAdder(_factory.ReflectedType(type), reason); } public void AddReflectionRoot(MethodDesc method, string reason) { if (!_factory.MetadataManager.IsReflectionBlocked(method)) + { + _factory.TypeSystemContext.EnsureLoadableMethod(method); _rootAdder(_factory.ReflectedMethod(method), reason); + } } public void AddReflectionRoot(FieldDesc field, string reason) { if (!_factory.MetadataManager.IsReflectionBlocked(field)) + { + _factory.TypeSystemContext.EnsureLoadableType(field.OwningType); _rootAdder(_factory.ReflectedField(field), reason); + } } public void AddCompilationRoot(object o, string reason) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs index 7c6f93b..498d9eb 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs @@ -1098,7 +1098,49 @@ namespace Internal.IL private void ImportBox(int token) { - AddBoxingDependencies((TypeDesc)_methodIL.GetObject(token), "Box"); + var type = (TypeDesc)_methodIL.GetObject(token); + + // There are some sequences of box with ByRefLike types that are allowed + // per the extension to the ECMA-335 specification. + // Everything else is invalid. + if (!type.IsRuntimeDeterminedType && type.IsByRefLike) + { + ILReader reader = new ILReader(_ilBytes, _currentOffset); + ILOpcode nextOpcode = reader.ReadILOpcode(); + + // box ; br_true/false + if (nextOpcode is ILOpcode.brtrue or ILOpcode.brtrue_s or ILOpcode.brfalse or ILOpcode.brfalse_s) + return; + + if (nextOpcode is ILOpcode.unbox_any or ILOpcode.isinst) + { + var type2 = (TypeDesc)_methodIL.GetObject(reader.ReadILToken()); + if (type == type2) + { + // box ; unbox_any with same token + if (nextOpcode == ILOpcode.unbox_any) + return; + + nextOpcode = reader.ReadILOpcode(); + + // box ; isinst ; br_true/false + if (nextOpcode is ILOpcode.brtrue or ILOpcode.brtrue_s or ILOpcode.brfalse or ILOpcode.brfalse_s) + return; + + // box ; isinst ; unbox_any + if (nextOpcode == ILOpcode.unbox_any) + { + type2 = (TypeDesc)_methodIL.GetObject(reader.ReadILToken()); + if (type2 == type) + return; + } + } + } + + ThrowHelper.ThrowInvalidProgramException(); + } + + AddBoxingDependencies(type, "Box"); } private void AddBoxingDependencies(TypeDesc type, string reason) diff --git a/src/tests/nativeaot/SmokeTests/DynamicGenerics/rd.xml b/src/tests/nativeaot/SmokeTests/DynamicGenerics/rd.xml index 6f47355..f656b4e 100644 --- a/src/tests/nativeaot/SmokeTests/DynamicGenerics/rd.xml +++ b/src/tests/nativeaot/SmokeTests/DynamicGenerics/rd.xml @@ -229,7 +229,7 @@ - +