Some support for NativeAOT was written in #67783 but the test didn't actually pass because of these missing pieces.
if (typeArg.IsByRef
|| typeArg.IsPointer
|| typeArg.IsFunctionPointer
- || typeArg.IsVoid
- || typeArg.IsByRefLike)
+ || typeArg.IsVoid)
{
ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadGeneral, type);
}
{
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);
}
}
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)
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)
<Type Name="InterfacesTests+UseFrobber`2[InterfacesTests+FrobtasticFrobberStruct,[System.String, netstandard]]" Dynamic="Required All" />
<Type Name="ConstraintsTests+TypeWithClassConstraint`1[[System.Object, netstandard]]" Dynamic="Required All"/>
- <Type Name="ConstraintsTests+TypeRequiringIFoo`1[[System.Object, netstandard]]" Dynamic="Required All"/>
+ <Type Name="ConstraintsTests+TypeRequiringIFoo`1[[ConstraintsTests+IFoo]]" Dynamic="Required All"/>
<Type Name="ConstraintsTests+TypeWithPrivateCtor" Dynamic="Required All"/>
<Type Name="ConstraintsTests+TypeWithNewConstraint`1[[System.Object, netstandard]]" Dynamic="Required All"/>
<Type Name="ConstraintsTests+TypeWithSelfReferenceConstraint`2[[System.Object, netstandard],[System.Object, netstandard]]" Dynamic="Required All"/>