Skip to content

Commit c392a6c

Browse files
Use GetUninitializedObject to marshal LayoutClass (#113529)
The marshalling rule is that `Marshal.PtrToStructure` will use the parameterless constructor to create instance and refuse working if there isn't one, but p/invoke will use `GetUninitializedObject` and ignore any constructors.
1 parent 474a1af commit c392a6c

File tree

2 files changed

+16
-11
lines changed

2 files changed

+16
-11
lines changed

src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -680,11 +680,9 @@ protected override void TransformNativeToManaged(ILCodeStream codeStream)
680680
LoadManagedValue(codeStream);
681681
codeStream.Emit(ILOpcode.brtrue, lNonNull);
682682

683-
MethodDesc ctor = ManagedType.GetParameterlessConstructor();
684-
if (ctor == null)
685-
throw new InvalidProgramException();
686-
687-
codeStream.Emit(ILOpcode.newobj, emitter.NewToken(ctor));
683+
codeStream.Emit(ILOpcode.ldtoken, emitter.NewToken(ManagedType));
684+
codeStream.Emit(ILOpcode.call, emitter.NewToken(InteropTypes.GetType(Context).GetMethod("GetTypeFromHandle", null)));
685+
codeStream.Emit(ILOpcode.call, emitter.NewToken(InteropTypes.GetRuntimeHelpers(Context).GetKnownMethod("GetUninitializedObject", null)));
688686
StoreManagedValue(codeStream);
689687

690688
codeStream.EmitLabel(lNonNull);
@@ -736,12 +734,9 @@ protected override void AllocManagedToNative(ILCodeStream codeStream)
736734
protected override void AllocNativeToManaged(ILCodeStream codeStream)
737735
{
738736
ILEmitter emitter = _ilCodeStreams.Emitter;
739-
740-
MethodDesc ctor = ManagedType.GetParameterlessConstructor();
741-
if (ctor == null)
742-
throw new InvalidProgramException();
743-
744-
codeStream.Emit(ILOpcode.newobj, emitter.NewToken(ctor));
737+
codeStream.Emit(ILOpcode.ldtoken, emitter.NewToken(ManagedType));
738+
codeStream.Emit(ILOpcode.call, emitter.NewToken(InteropTypes.GetType(Context).GetMethod("GetTypeFromHandle", null)));
739+
codeStream.Emit(ILOpcode.call, emitter.NewToken(InteropTypes.GetRuntimeHelpers(Context).GetKnownMethod("GetUninitializedObject", null)));
745740
StoreManagedValue(codeStream);
746741
}
747742

src/coreclr/tools/Common/TypeSystem/Interop/InteropTypes.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ public static MetadataType GetGC(TypeSystemContext context)
1212
return context.SystemModule.GetKnownType("System", "GC");
1313
}
1414

15+
public static MetadataType GetType(TypeSystemContext context)
16+
{
17+
return context.SystemModule.GetKnownType("System", "Type");
18+
}
19+
1520
public static MetadataType GetSafeHandle(TypeSystemContext context)
1621
{
1722
return context.SystemModule.GetKnownType("System.Runtime.InteropServices", "SafeHandle");
@@ -32,6 +37,11 @@ public static MetadataType GetPInvokeMarshal(TypeSystemContext context)
3237
return context.SystemModule.GetKnownType("System.Runtime.InteropServices", "PInvokeMarshal");
3338
}
3439

40+
public static MetadataType GetRuntimeHelpers(TypeSystemContext context)
41+
{
42+
return context.SystemModule.GetKnownType("System.Runtime.CompilerServices", "RuntimeHelpers");
43+
}
44+
3545
public static MetadataType GetMarshal(TypeSystemContext context)
3646
{
3747
return context.SystemModule.GetKnownType("System.Runtime.InteropServices", "Marshal");

0 commit comments

Comments
 (0)