Skip to content

Commit

Permalink
[mono] Add SwiftError support for Swift reverse pinvokes (dotnet#101122)
Browse files Browse the repository at this point in the history
* initialized swift reverse pinvokes for mini jit arm64

* added comments

* fixed reverse pinvokes error passing on arm64

* implemented swift reverse pinvoke error passing on amd64

* disable SwiftErrorHandling tests on mono interpreter for now

* add comments
  • Loading branch information
jkurdek authored and Ruihan-Yin committed May 30, 2024
1 parent 8bee264 commit 61b4ead
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 20 deletions.
36 changes: 26 additions & 10 deletions src/mono/mono/mini/mini-amd64.c
Original file line number Diff line number Diff line change
Expand Up @@ -1990,13 +1990,18 @@ mono_arch_allocate_vars (MonoCompile *cfg)
}
case ArgSwiftError: {
ins->opcode = OP_REGOFFSET;
ins->inst_basereg = cfg->frame_reg;
ins->inst_offset = ainfo->offset + ARGS_OFFSET;
offset = ALIGN_TO (offset, sizeof (target_mgreg_t));
ins->inst_basereg = cfg->frame_reg;
ins->inst_offset = offset;
offset += sizeof (target_mgreg_t);

cfg->arch.swift_error_var = ins;
cfg->used_int_regs |= (size_t)(1 << AMD64_R12);

/* In the n2m case, the error register functions as an extra return register
* and is thus is not treated as callee-saved.
*/
if (cfg->method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE)
cfg->used_int_regs |= (size_t)(1 << AMD64_R12);
}
break;
default:
Expand Down Expand Up @@ -4280,8 +4285,13 @@ emit_move_return_value (MonoCompile *cfg, MonoInst *ins, guint8 *code)
guint32 quad;

if (cfg->arch.swift_error_var) {
amd64_mov_reg_membase (code, AMD64_R11, cfg->arch.swift_error_var->inst_basereg, cfg->arch.swift_error_var->inst_offset, sizeof (target_mgreg_t));
amd64_mov_membase_reg (code, AMD64_R11, 0, AMD64_R12, sizeof (target_mgreg_t));
if (cfg->method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) {
amd64_mov_reg_membase (code, AMD64_R11, cfg->arch.swift_error_var->inst_basereg, cfg->arch.swift_error_var->inst_offset, sizeof (target_mgreg_t));
amd64_mov_membase_reg (code, AMD64_R11, 0, AMD64_R12, sizeof (target_mgreg_t));
}
else if (cfg->method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED) {
amd64_mov_reg_membase (code, AMD64_R12, cfg->arch.swift_error_var->inst_basereg, cfg->arch.swift_error_var->inst_offset, sizeof (target_mgreg_t));
}
}

/* Move return value to the target register */
Expand Down Expand Up @@ -8248,11 +8258,17 @@ MONO_RESTORE_WARNING
amd64_mov_membase_reg (code, ins->inst_basereg, ins->inst_offset, ainfo->reg, 8);
break;
case ArgSwiftError:
if (ainfo->offset) {
amd64_mov_reg_membase (code, AMD64_R11, AMD64_RBP, ARGS_OFFSET + ainfo->offset, 8);
amd64_mov_membase_reg (code, cfg->arch.swift_error_var->inst_basereg, cfg->arch.swift_error_var->inst_offset, AMD64_R11, sizeof (target_mgreg_t));
} else {
amd64_mov_membase_reg (code, cfg->arch.swift_error_var->inst_basereg, cfg->arch.swift_error_var->inst_offset, ainfo->reg, sizeof (target_mgreg_t));
if (cfg->method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) {
if (ainfo->offset) {
amd64_mov_reg_membase (code, AMD64_R11, AMD64_RBP, ARGS_OFFSET + ainfo->offset, 8);
amd64_mov_membase_reg (code, cfg->arch.swift_error_var->inst_basereg, cfg->arch.swift_error_var->inst_offset, AMD64_R11, sizeof (target_mgreg_t));
} else {
amd64_mov_membase_reg (code, cfg->arch.swift_error_var->inst_basereg, cfg->arch.swift_error_var->inst_offset, ainfo->reg, sizeof (target_mgreg_t));
}
} else if (cfg->method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED) {
/* Relies on arguments being passed on the stack */
amd64_lea_membase (code, AMD64_R11, cfg->arch.swift_error_var->inst_basereg, cfg->arch.swift_error_var->inst_offset);
amd64_mov_membase_reg (code, ins->inst_basereg, ins->inst_offset, AMD64_R11, 8);
}
break;
default:
Expand Down
32 changes: 24 additions & 8 deletions src/mono/mono/mini/mini-arm64.c
Original file line number Diff line number Diff line change
Expand Up @@ -2887,7 +2887,12 @@ mono_arch_allocate_vars (MonoCompile *cfg)
offset += size;

cfg->arch.swift_error_var = ins;
cfg->used_int_regs |= 1 << ARMREG_R21;

/* In the n2m case, the error register functions as an extra return register
* and is thus is not treated as callee-saved.
*/
if (cfg->method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE)
cfg->used_int_regs |= 1 << ARMREG_R21;
break;
}
default:
Expand Down Expand Up @@ -3731,8 +3736,13 @@ emit_move_return_value (MonoCompile *cfg, guint8 * code, MonoInst *ins)
MonoCallInst *call;

if (cfg->arch.swift_error_var) {
code = emit_ldrx (code, ARMREG_IP0, cfg->arch.swift_error_var->inst_basereg, GTMREG_TO_INT (cfg->arch.swift_error_var->inst_offset));
code = emit_strx (code, ARMREG_R21, ARMREG_IP0, 0);
if (cfg->method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) {
code = emit_ldrx (code, ARMREG_IP0, cfg->arch.swift_error_var->inst_basereg, GTMREG_TO_INT (cfg->arch.swift_error_var->inst_offset));
code = emit_strx (code, ARMREG_R21, ARMREG_IP0, 0);
} else if (cfg->method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED) {
/* Load the value of SwiftError into R21 */
code = emit_ldrx (code, ARMREG_R21, cfg->arch.swift_error_var->inst_basereg, GTMREG_TO_INT (cfg->arch.swift_error_var->inst_offset));
}
}

call = (MonoCallInst*)ins;
Expand Down Expand Up @@ -5937,11 +5947,17 @@ emit_move_args (MonoCompile *cfg, guint8 *code)
code = emit_strfpq (code, ainfo->reg, ins->inst_basereg, GTMREG_TO_INT (ins->inst_offset));
break;
case ArgSwiftError:
if (ainfo->offset) {
code = emit_ldrx (code, ARMREG_IP0, cfg->arch.args_reg, ainfo->offset);
code = emit_strx (code, ARMREG_IP0, cfg->arch.swift_error_var->inst_basereg, GTMREG_TO_INT (cfg->arch.swift_error_var->inst_offset));
} else {
code = emit_strx (code, ainfo->reg, cfg->arch.swift_error_var->inst_basereg, GTMREG_TO_INT (cfg->arch.swift_error_var->inst_offset));
if (cfg->method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) {
if (ainfo->offset) {
code = emit_ldrx (code, ARMREG_IP0, cfg->arch.args_reg, ainfo->offset);
code = emit_strx (code, ARMREG_IP0, cfg->arch.swift_error_var->inst_basereg, GTMREG_TO_INT (cfg->arch.swift_error_var->inst_offset));
} else {
code = emit_strx (code, ainfo->reg, cfg->arch.swift_error_var->inst_basereg, GTMREG_TO_INT (cfg->arch.swift_error_var->inst_offset));
}
} else if (cfg->method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED) {
arm_addx_imm (code, ARMREG_IP0, cfg->arch.swift_error_var->inst_basereg, GTMREG_TO_INT (cfg->arch.swift_error_var->inst_offset));
/* Relies on arguments being passed on the stack */
code = emit_strx (code, ARMREG_IP0, ins->inst_basereg, GTMREG_TO_INT (ins->inst_offset));
}
break;
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ public unsafe static void TestSwiftErrorOnStackNotThrown()
}

[Fact]
[SkipOnMono("needs reverse P/Invoke support")]
public static unsafe void TestUnmanagedCallersOnly()
{
SwiftError error;
Expand All @@ -144,7 +143,6 @@ public static unsafe void TestUnmanagedCallersOnly()
}

[Fact]
[SkipOnMono("needs reverse P/Invoke support")]
public static unsafe void TestUnmanagedCallersOnlyWithReturn()
{
SwiftError error;
Expand Down
3 changes: 3 additions & 0 deletions src/tests/issues.targets
Original file line number Diff line number Diff line change
Expand Up @@ -2191,6 +2191,9 @@
<ExcludeList Include = "$(XUnitTestBinBase)/JIT/Directed/Arrays/nintindexoutofrange/**">
<Issue>https://github.com/dotnet/runtime/issues/71656</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/Interop/Swift/SwiftErrorHandling/**">
<Issue>Reverse P/Invokes not supported yet</Issue>
</ExcludeList>
<!-- End interpreter issues -->
</ItemGroup>

Expand Down

0 comments on commit 61b4ead

Please sign in to comment.