Skip to content

Commit 49e22fe

Browse files
aykevldeadprogram
authored andcommitted
runtime: load sp and pc inside tinygo_longjmp
This is a small change to make it easier to support architectures that need to restore more than just the sp and pc registers. In particular, it is needed for the AVR architecture that needs to restore the frame pointer (Y register).
1 parent c119721 commit 49e22fe

File tree

7 files changed

+24
-19
lines changed

7 files changed

+24
-19
lines changed

src/runtime/asm_386.S

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ tinygo_scanCurrentStack:
2828
tinygo_longjmp:
2929
// Note: the code we jump to assumes eax is set to a non-zero value if we
3030
// jump from here.
31-
movl 8(%esp), %eax // jumpPC (stash in volatile register)
32-
movl 4(%esp), %esp // jumpSP
31+
movl 4(%esp), %eax
32+
movl 0(%eax), %esp // jumpSP
33+
movl 4(%eax), %eax // jumpPC (stash in volatile register)
3334
jmpl *%eax

src/runtime/asm_amd64.S

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,11 @@ tinygo_longjmp:
3737
.global _tinygo_longjmp
3838
_tinygo_longjmp:
3939
#endif
40-
// Note: the code we jump to assumes rax is non-zero so we have to load it
41-
// with some value here.
42-
movq $1, %rax
43-
movq %rdi, %rsp // jumpSP
44-
jmpq *%rsi // jumpPC
40+
// Note: the code we jump to assumes rax is set to a non-zero value if we
41+
// jump from here, so we use rax as the temporary value for jumpPC.
42+
movq 0(%rdi), %rsp // jumpSP
43+
movq 8(%rdi), %rax // jumpPC
44+
jmpq *%rax
4545

4646

4747
#ifdef __MACH__ // Darwin

src/runtime/asm_amd64_windows.S

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ tinygo_scanCurrentStack:
2424
.section .text.tinygo_longjmp,"ax"
2525
.global tinygo_longjmp
2626
tinygo_longjmp:
27-
// Note: the code we jump to assumes rax is non-zero so we have to load it
28-
// with some value here.
29-
movq $1, %rax
30-
movq %rcx, %rsp // jumpSP
31-
jmpq *%rdx // jumpPC
27+
// Note: the code we jump to assumes rax is set to a non-zero value if we
28+
// jump from here, so we use rax as the temporary value for jumpPC.
29+
movq 0(%rcx), %rsp // jumpSP
30+
movq 8(%rcx), %rax // jumpPC
31+
jmpq *%rax

src/runtime/asm_arm.S

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ tinygo_longjmp:
4040
.cfi_startproc
4141
// Note: the code we jump to assumes r0 is set to a non-zero value if we
4242
// jump from here (which is conveniently already the case).
43+
44+
ldm r0, {r0, r1}
4345
mov sp, r0 // jumpSP
4446
mov pc, r1 // jumpPC
4547
.cfi_endproc

src/runtime/asm_arm64.S

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,6 @@ tinygo_longjmp:
4343
#endif
4444
// Note: the code we jump to assumes x0 is set to a non-zero value if we
4545
// jump from here (which is conveniently already the case).
46-
mov sp, x0 // jumpSP
47-
br x1 // jumpPC
46+
ldp x1, x2, [x0] // jumpSP, jumpPC
47+
mov sp, x1
48+
br x2

src/runtime/asm_riscv.S

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ tinygo_scanCurrentStack:
4646
.global tinygo_longjmp
4747
tinygo_longjmp:
4848
// Note: the code we jump to assumes a0 is non-zero, which is already the
49-
// case because that's jumpSP (the stack pointer).
50-
mv sp, a0 // jumpSP
51-
jr a1 // jumpPC
49+
// case because that's the defer frame pointer.
50+
lw sp, 0(a0) // jumpSP
51+
lw a1, REGSIZE(a0) // jumpPC
52+
jr a1

src/runtime/panic.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ func trap()
1313
// Inline assembly stub. It is essentially C longjmp but modified a bit for the
1414
// purposes of TinyGo. It restores the stack pointer and jumps to the given pc.
1515
//export tinygo_longjmp
16-
func tinygo_longjmp(sp, pc unsafe.Pointer)
16+
func tinygo_longjmp(frame *task.DeferFrame)
1717

1818
// Compiler intrinsic.
1919
// Returns whether recover is supported on the current architecture.
@@ -26,7 +26,7 @@ func _panic(message interface{}) {
2626
if frame != nil {
2727
frame.PanicValue = message
2828
frame.Panicking = true
29-
tinygo_longjmp(frame.JumpSP, frame.JumpPC)
29+
tinygo_longjmp(frame)
3030
// unreachable
3131
}
3232
}

0 commit comments

Comments
 (0)