diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/TypePreinit.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/TypePreinit.cs index fc7494e1c383b..86cfba92668bc 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/TypePreinit.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/TypePreinit.cs @@ -712,13 +712,11 @@ private Status TryScanMethod(MethodIL methodIL, Value[] parameters, Stack private interface IHasInstanceFields { - void SetField(FieldDesc field, Value value); + bool TrySetField(FieldDesc field, Value value); Value GetField(FieldDesc field); ByRefValue GetFieldAddress(FieldDesc field); } @@ -2505,7 +2503,7 @@ public bool TryAccessElement(int index, out Value value) return true; } - public void SetField(FieldDesc field, Value value) => ThrowHelper.ThrowInvalidProgramException(); + public bool TrySetField(FieldDesc field, Value value) => false; public Value GetField(FieldDesc field) { @@ -2587,7 +2585,7 @@ public override bool Equals(Value value) } Value IHasInstanceFields.GetField(FieldDesc field) => new FieldAccessor(PointedToBytes, PointedToOffset).GetField(field); - void IHasInstanceFields.SetField(FieldDesc field, Value value) => new FieldAccessor(PointedToBytes, PointedToOffset).SetField(field, value); + bool IHasInstanceFields.TrySetField(FieldDesc field, Value value) => new FieldAccessor(PointedToBytes, PointedToOffset).TrySetField(field, value); ByRefValue IHasInstanceFields.GetFieldAddress(FieldDesc field) => new FieldAccessor(PointedToBytes, PointedToOffset).GetFieldAddress(field); public void Initialize(int size) @@ -2925,7 +2923,8 @@ private static byte[] ConstructStringInstance(TypeDesc stringType, ReadOnlySpan< FieldDesc lengthField = stringType.GetField("_stringLength"); Debug.Assert(lengthField.FieldType.IsWellKnownType(WellKnownType.Int32) && lengthField.Offset.AsInt == pointerSize); - new FieldAccessor(bytes).SetField(lengthField, ValueTypeValue.FromInt32(value.Length)); + bool success = new FieldAccessor(bytes).TrySetField(lengthField, ValueTypeValue.FromInt32(value.Length)); + Debug.Assert(success); FieldDesc firstCharField = stringType.GetField("_firstChar"); Debug.Assert(firstCharField.FieldType.IsWellKnownType(WellKnownType.Char) @@ -2949,7 +2948,7 @@ public override bool GetRawData(NodeFactory factory, out object data) public override ReferenceTypeValue ToForeignInstance(int baseInstructionCounter) => this; Value IHasInstanceFields.GetField(FieldDesc field) => new FieldAccessor(_value).GetField(field); - void IHasInstanceFields.SetField(FieldDesc field, Value value) => ThrowHelper.ThrowInvalidProgramException(); + bool IHasInstanceFields.TrySetField(FieldDesc field, Value value) => false; ByRefValue IHasInstanceFields.GetFieldAddress(FieldDesc field) => new FieldAccessor(_value).GetFieldAddress(field); } @@ -2999,7 +2998,7 @@ public bool TryUnboxAny(TypeDesc type, out Value value) } Value IHasInstanceFields.GetField(FieldDesc field) => new FieldAccessor(_data).GetField(field); - void IHasInstanceFields.SetField(FieldDesc field, Value value) => new FieldAccessor(_data).SetField(field, value); + bool IHasInstanceFields.TrySetField(FieldDesc field, Value value) => new FieldAccessor(_data).TrySetField(field, value); ByRefValue IHasInstanceFields.GetFieldAddress(FieldDesc field) => new FieldAccessor(_data).GetFieldAddress(field); public override void WriteFieldData(ref ObjectDataBuilder builder, NodeFactory factory) @@ -3050,7 +3049,7 @@ public ValueTypeValue GetField(FieldDesc field) return result; } - public void SetField(FieldDesc field, Value value) + public bool TrySetField(FieldDesc field, Value value) { Debug.Assert(!field.IsStatic); @@ -3059,7 +3058,7 @@ public void SetField(FieldDesc field, Value value) // Allow setting reference type fields to null. Since this is the only value we can // write, this is a no-op since reference type fields are always null Debug.Assert(value == null); - return; + return true; } int fieldOffset = field.Offset.AsInt; @@ -3067,15 +3066,19 @@ public void SetField(FieldDesc field, Value value) if (fieldOffset + fieldSize > _instanceBytes.Length - _offset) ThrowHelper.ThrowInvalidProgramException(); + if (value is IInternalModelingOnlyValue) + { + return false; + } + if (value is not ValueTypeValue vtValue) { - // This is either invalid IL, or value is one of our modeling-only values - // that don't have a bit representation (e.g. function pointer). ThrowHelper.ThrowInvalidProgramException(); - return; // unreached + return false; // unreached } Array.Copy(vtValue.InstanceBytes, 0, _instanceBytes, _offset + fieldOffset, fieldSize); + return true; } public ByRefValue GetFieldAddress(FieldDesc field)