Skip to content

Commit 5f030e5

Browse files
authored
Merge pull request #1063 from Unity-Technologies/unity-master-ref-return-struct
Use mono_mb_emit_op for CEE_LDOBJ to ensure wrapper data is added for indirect load of a ref return value. (case 1096820)
2 parents b96f9da + 3898ae1 commit 5f030e5

File tree

3 files changed

+21
-1
lines changed

3 files changed

+21
-1
lines changed

mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1755,6 +1755,11 @@ public static ref int get_ref_int() {
17551755
public static ref string get_ref_string() {
17561756
return ref ref_return_string;
17571757
}
1758+
1759+
static BlittableStruct ref_return_struct = new BlittableStruct () { i = 1, d = 2.0 };
1760+
public static ref BlittableStruct get_ref_struct () {
1761+
return ref ref_return_struct;
1762+
}
17581763
}
17591764

17601765
public class SentinelClass : MarshalByRefObject {

mcs/class/Mono.Debugger.Soft/Test/dtest.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4423,6 +4423,13 @@ public void InvokeRefReturnMethod () {
44234423
m = t.GetMethod ("get_ref_string");
44244424
v = t.InvokeMethod (e.Thread, m, null);
44254425
AssertValue ("byref", v);
4426+
4427+
m = t.GetMethod ("get_ref_struct");
4428+
v = t.InvokeMethod (e.Thread, m, null);
4429+
Assert.IsTrue(v is StructMirror);
4430+
var mirror = (StructMirror)v;
4431+
AssertValue (1, mirror["i"]);
4432+
AssertValue (2.0, mirror["d"]);
44264433
}
44274434
} // class DebuggerTests
44284435
} // namespace

mono/metadata/marshal.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4148,10 +4148,18 @@ emit_invoke_call (MonoMethodBuilder *mb, MonoMethod *method,
41484148
}
41494149

41504150
if (sig->ret->byref) {
4151+
int ldind_op;
41514152
/* perform indirect load and return by value */
41524153
MonoType* ret_byval = &mono_class_from_mono_type (sig->ret)->byval_arg;
41534154
g_assert (!ret_byval->byref);
4154-
mono_mb_emit_byte (mb, mono_type_to_ldind (ret_byval));
4155+
ldind_op = mono_type_to_ldind (ret_byval);
4156+
/* taken from similar code in mini-generic-sharing.c
4157+
* we need to use mono_mb_emit_op to add method data when loading
4158+
* a structure since method-to-ir needs this data for wrapper methods */
4159+
if (ldind_op == CEE_LDOBJ)
4160+
mono_mb_emit_op (mb, CEE_LDOBJ, mono_class_from_mono_type (ret_byval));
4161+
else
4162+
mono_mb_emit_byte (mb, ldind_op);
41554163
}
41564164

41574165
switch (sig->ret->type) {

0 commit comments

Comments
 (0)