Skip to content

Commit 159f005

Browse files
aykevldeadprogram
authored andcommitted
runtime: move *task.DeferFrame here
This is a refactor that makes the next commit simpler. Perhaps it should have been like this from the beginning but I didn't like all the casts.
1 parent 49e22fe commit 159f005

File tree

7 files changed

+45
-50
lines changed

7 files changed

+45
-50
lines changed

compiler/defer.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ func (b *builder) deferInitFunc() {
7171
// possibly broken by the C alloca function).
7272
// The frame pointer is _not_ saved, because it is marked as clobbered
7373
// in the setjmp-like inline assembly.
74-
deferFrameType := b.getLLVMType(b.program.ImportedPackage("internal/task").Members["DeferFrame"].Type())
74+
deferFrameType := b.getLLVMRuntimeType("deferFrame")
7575
b.deferFrame = b.CreateAlloca(deferFrameType, "deferframe.buf")
7676
stackPointer := b.readStackPointer()
7777
b.createRuntimeCall("setupDeferFrame", []llvm.Value{b.deferFrame, stackPointer}, "")

compiler/testdata/channel.ll

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,10 @@ target triple = "wasm32-unknown-wasi"
55

66
%runtime.channel = type { i32, i32, i8, %runtime.channelBlockedList*, i32, i32, i32, i8* }
77
%runtime.channelBlockedList = type { %runtime.channelBlockedList*, %"internal/task.Task"*, %runtime.chanSelectState*, { %runtime.channelBlockedList*, i32, i32 } }
8-
%"internal/task.Task" = type { %"internal/task.Task"*, i8*, i64, %"internal/task.gcData", %"internal/task.state", %"internal/task.DeferFrame"* }
8+
%"internal/task.Task" = type { %"internal/task.Task"*, i8*, i64, %"internal/task.gcData", %"internal/task.state", i8* }
99
%"internal/task.gcData" = type { i8* }
1010
%"internal/task.state" = type { i32, i8*, %"internal/task.stackState", i1 }
1111
%"internal/task.stackState" = type { i32, i32 }
12-
%"internal/task.DeferFrame" = type { i8*, i8*, %"internal/task.DeferFrame"*, i1, %runtime._interface }
13-
%runtime._interface = type { i32, i8* }
1412
%runtime.chanSelectState = type { %runtime.channel*, i8* }
1513

1614
declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*)

compiler/testdata/defer-cortex-m-qemu.ll

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
44
target triple = "thumbv7m-unknown-unknown-eabi"
55

66
%runtime._defer = type { i32, %runtime._defer* }
7-
%"internal/task.DeferFrame" = type { i8*, i8*, %"internal/task.DeferFrame"*, i1, %runtime._interface }
7+
%runtime.deferFrame = type { i8*, i8*, %runtime.deferFrame*, i1, %runtime._interface }
88
%runtime._interface = type { i32, i8* }
99

1010
declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0
@@ -23,16 +23,16 @@ entry:
2323
%defer.alloca = alloca { i32, %runtime._defer* }, align 4
2424
%deferPtr = alloca %runtime._defer*, align 4
2525
store %runtime._defer* null, %runtime._defer** %deferPtr, align 4
26-
%deferframe.buf = alloca %"internal/task.DeferFrame", align 4
26+
%deferframe.buf = alloca %runtime.deferFrame, align 4
2727
%0 = call i8* @llvm.stacksave()
28-
call void @runtime.setupDeferFrame(%"internal/task.DeferFrame"* nonnull %deferframe.buf, i8* %0, i8* undef) #3
28+
call void @runtime.setupDeferFrame(%runtime.deferFrame* nonnull %deferframe.buf, i8* %0, i8* undef) #3
2929
%defer.alloca.repack = getelementptr inbounds { i32, %runtime._defer* }, { i32, %runtime._defer* }* %defer.alloca, i32 0, i32 0
3030
store i32 0, i32* %defer.alloca.repack, align 4
3131
%defer.alloca.repack16 = getelementptr inbounds { i32, %runtime._defer* }, { i32, %runtime._defer* }* %defer.alloca, i32 0, i32 1
3232
store %runtime._defer* null, %runtime._defer** %defer.alloca.repack16, align 4
3333
%1 = bitcast %runtime._defer** %deferPtr to { i32, %runtime._defer* }**
3434
store { i32, %runtime._defer* }* %defer.alloca, { i32, %runtime._defer* }** %1, align 4
35-
%setjmp = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%"internal/task.DeferFrame"* nonnull %deferframe.buf) #4
35+
%setjmp = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%runtime.deferFrame* nonnull %deferframe.buf) #4
3636
%setjmp.result = icmp eq i32 %setjmp, 0
3737
br i1 %setjmp.result, label %2, label %lpad
3838

@@ -56,7 +56,7 @@ rundefers.loop: ; preds = %rundefers.loophead
5656
]
5757

5858
rundefers.callback0: ; preds = %rundefers.loop
59-
%setjmp1 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%"internal/task.DeferFrame"* nonnull %deferframe.buf) #4
59+
%setjmp1 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%runtime.deferFrame* nonnull %deferframe.buf) #4
6060
%setjmp.result2 = icmp eq i32 %setjmp1, 0
6161
br i1 %setjmp.result2, label %4, label %lpad
6262

@@ -68,11 +68,11 @@ rundefers.default: ; preds = %rundefers.loop
6868
unreachable
6969

7070
rundefers.end: ; preds = %rundefers.loophead
71-
call void @runtime.destroyDeferFrame(%"internal/task.DeferFrame"* nonnull %deferframe.buf, i8* undef) #3
71+
call void @runtime.destroyDeferFrame(%runtime.deferFrame* nonnull %deferframe.buf, i8* undef) #3
7272
ret void
7373

7474
recover: ; preds = %rundefers.end3
75-
call void @runtime.destroyDeferFrame(%"internal/task.DeferFrame"* nonnull %deferframe.buf, i8* undef) #3
75+
call void @runtime.destroyDeferFrame(%runtime.deferFrame* nonnull %deferframe.buf, i8* undef) #3
7676
ret void
7777

7878
lpad: ; preds = %rundefers.callback012, %rundefers.callback0, %entry
@@ -94,7 +94,7 @@ rundefers.loop5: ; preds = %rundefers.loophead6
9494
]
9595

9696
rundefers.callback012: ; preds = %rundefers.loop5
97-
%setjmp14 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%"internal/task.DeferFrame"* nonnull %deferframe.buf) #4
97+
%setjmp14 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%runtime.deferFrame* nonnull %deferframe.buf) #4
9898
%setjmp.result15 = icmp eq i32 %setjmp14, 0
9999
br i1 %setjmp.result15, label %6, label %lpad
100100

@@ -112,7 +112,7 @@ rundefers.end3: ; preds = %rundefers.loophead6
112112
; Function Attrs: nofree nosync nounwind willreturn
113113
declare i8* @llvm.stacksave() #2
114114

115-
declare void @runtime.setupDeferFrame(%"internal/task.DeferFrame"* dereferenceable_or_null(24), i8*, i8*) #0
115+
declare void @runtime.setupDeferFrame(%runtime.deferFrame* dereferenceable_or_null(24), i8*, i8*) #0
116116

117117
; Function Attrs: nounwind
118118
define hidden void @"main.deferSimple$1"(i8* %context) unnamed_addr #1 {
@@ -121,7 +121,7 @@ entry:
121121
ret void
122122
}
123123

124-
declare void @runtime.destroyDeferFrame(%"internal/task.DeferFrame"* dereferenceable_or_null(24), i8*) #0
124+
declare void @runtime.destroyDeferFrame(%runtime.deferFrame* dereferenceable_or_null(24), i8*) #0
125125

126126
declare void @runtime.printint32(i32, i8*) #0
127127

@@ -132,9 +132,9 @@ entry:
132132
%defer.alloca = alloca { i32, %runtime._defer* }, align 4
133133
%deferPtr = alloca %runtime._defer*, align 4
134134
store %runtime._defer* null, %runtime._defer** %deferPtr, align 4
135-
%deferframe.buf = alloca %"internal/task.DeferFrame", align 4
135+
%deferframe.buf = alloca %runtime.deferFrame, align 4
136136
%0 = call i8* @llvm.stacksave()
137-
call void @runtime.setupDeferFrame(%"internal/task.DeferFrame"* nonnull %deferframe.buf, i8* %0, i8* undef) #3
137+
call void @runtime.setupDeferFrame(%runtime.deferFrame* nonnull %deferframe.buf, i8* %0, i8* undef) #3
138138
%defer.alloca.repack = getelementptr inbounds { i32, %runtime._defer* }, { i32, %runtime._defer* }* %defer.alloca, i32 0, i32 0
139139
store i32 0, i32* %defer.alloca.repack, align 4
140140
%defer.alloca.repack26 = getelementptr inbounds { i32, %runtime._defer* }, { i32, %runtime._defer* }* %defer.alloca, i32 0, i32 1
@@ -148,7 +148,7 @@ entry:
148148
store { i32, %runtime._defer* }* %defer.alloca, { i32, %runtime._defer* }** %2, align 4
149149
%3 = bitcast %runtime._defer** %deferPtr to { i32, %runtime._defer* }**
150150
store { i32, %runtime._defer* }* %defer.alloca2, { i32, %runtime._defer* }** %3, align 4
151-
%setjmp = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%"internal/task.DeferFrame"* nonnull %deferframe.buf) #4
151+
%setjmp = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%runtime.deferFrame* nonnull %deferframe.buf) #4
152152
%setjmp.result = icmp eq i32 %setjmp, 0
153153
br i1 %setjmp.result, label %4, label %lpad
154154

@@ -173,7 +173,7 @@ rundefers.loop: ; preds = %rundefers.loophead
173173
]
174174

175175
rundefers.callback0: ; preds = %rundefers.loop
176-
%setjmp4 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%"internal/task.DeferFrame"* nonnull %deferframe.buf) #4
176+
%setjmp4 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%runtime.deferFrame* nonnull %deferframe.buf) #4
177177
%setjmp.result5 = icmp eq i32 %setjmp4, 0
178178
br i1 %setjmp.result5, label %6, label %lpad
179179

@@ -182,7 +182,7 @@ rundefers.callback0: ; preds = %rundefers.loop
182182
br label %rundefers.loophead
183183

184184
rundefers.callback1: ; preds = %rundefers.loop
185-
%setjmp7 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%"internal/task.DeferFrame"* nonnull %deferframe.buf) #4
185+
%setjmp7 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%runtime.deferFrame* nonnull %deferframe.buf) #4
186186
%setjmp.result8 = icmp eq i32 %setjmp7, 0
187187
br i1 %setjmp.result8, label %7, label %lpad
188188

@@ -194,11 +194,11 @@ rundefers.default: ; preds = %rundefers.loop
194194
unreachable
195195

196196
rundefers.end: ; preds = %rundefers.loophead
197-
call void @runtime.destroyDeferFrame(%"internal/task.DeferFrame"* nonnull %deferframe.buf, i8* undef) #3
197+
call void @runtime.destroyDeferFrame(%runtime.deferFrame* nonnull %deferframe.buf, i8* undef) #3
198198
ret void
199199

200200
recover: ; preds = %rundefers.end9
201-
call void @runtime.destroyDeferFrame(%"internal/task.DeferFrame"* nonnull %deferframe.buf, i8* undef) #3
201+
call void @runtime.destroyDeferFrame(%runtime.deferFrame* nonnull %deferframe.buf, i8* undef) #3
202202
ret void
203203

204204
lpad: ; preds = %rundefers.callback122, %rundefers.callback018, %rundefers.callback1, %rundefers.callback0, %entry
@@ -221,7 +221,7 @@ rundefers.loop11: ; preds = %rundefers.loophead1
221221
]
222222

223223
rundefers.callback018: ; preds = %rundefers.loop11
224-
%setjmp20 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%"internal/task.DeferFrame"* nonnull %deferframe.buf) #4
224+
%setjmp20 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%runtime.deferFrame* nonnull %deferframe.buf) #4
225225
%setjmp.result21 = icmp eq i32 %setjmp20, 0
226226
br i1 %setjmp.result21, label %9, label %lpad
227227

@@ -230,7 +230,7 @@ rundefers.callback018: ; preds = %rundefers.loop11
230230
br label %rundefers.loophead12
231231

232232
rundefers.callback122: ; preds = %rundefers.loop11
233-
%setjmp24 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%"internal/task.DeferFrame"* nonnull %deferframe.buf) #4
233+
%setjmp24 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%runtime.deferFrame* nonnull %deferframe.buf) #4
234234
%setjmp.result25 = icmp eq i32 %setjmp24, 0
235235
br i1 %setjmp.result25, label %10, label %lpad
236236

compiler/testdata/goroutine-cortex-m-qemu-tasks.ll

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,9 @@ target triple = "thumbv7m-unknown-unknown-eabi"
55

66
%runtime.channel = type { i32, i32, i8, %runtime.channelBlockedList*, i32, i32, i32, i8* }
77
%runtime.channelBlockedList = type { %runtime.channelBlockedList*, %"internal/task.Task"*, %runtime.chanSelectState*, { %runtime.channelBlockedList*, i32, i32 } }
8-
%"internal/task.Task" = type { %"internal/task.Task"*, i8*, i64, %"internal/task.gcData", %"internal/task.state", %"internal/task.DeferFrame"* }
8+
%"internal/task.Task" = type { %"internal/task.Task"*, i8*, i64, %"internal/task.gcData", %"internal/task.state", i8* }
99
%"internal/task.gcData" = type {}
1010
%"internal/task.state" = type { i32, i32* }
11-
%"internal/task.DeferFrame" = type { i8*, i8*, %"internal/task.DeferFrame"*, i1, %runtime._interface }
12-
%runtime._interface = type { i32, i8* }
1311
%runtime.chanSelectState = type { %runtime.channel*, i8* }
1412

1513
@"main$string" = internal unnamed_addr constant [4 x i8] c"test", align 1

compiler/testdata/goroutine-wasm-asyncify.ll

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,10 @@ target triple = "wasm32-unknown-wasi"
55

66
%runtime.channel = type { i32, i32, i8, %runtime.channelBlockedList*, i32, i32, i32, i8* }
77
%runtime.channelBlockedList = type { %runtime.channelBlockedList*, %"internal/task.Task"*, %runtime.chanSelectState*, { %runtime.channelBlockedList*, i32, i32 } }
8-
%"internal/task.Task" = type { %"internal/task.Task"*, i8*, i64, %"internal/task.gcData", %"internal/task.state", %"internal/task.DeferFrame"* }
8+
%"internal/task.Task" = type { %"internal/task.Task"*, i8*, i64, %"internal/task.gcData", %"internal/task.state", i8* }
99
%"internal/task.gcData" = type { i8* }
1010
%"internal/task.state" = type { i32, i8*, %"internal/task.stackState", i1 }
1111
%"internal/task.stackState" = type { i32, i32 }
12-
%"internal/task.DeferFrame" = type { i8*, i8*, %"internal/task.DeferFrame"*, i1, %runtime._interface }
13-
%runtime._interface = type { i32, i8* }
1412
%runtime.chanSelectState = type { %runtime.channel*, i8* }
1513

1614
@"main$string" = internal unnamed_addr constant [4 x i8] c"test", align 1

src/internal/task/task.go

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,7 @@ type Task struct {
2323

2424
// DeferFrame stores a pointer to the (stack allocated) defer frame of the
2525
// goroutine that is used for the recover builtin.
26-
DeferFrame *DeferFrame
27-
}
28-
29-
// DeferFrame is a stack allocated object that stores information for the
30-
// current "defer frame", which is used in functions that use the `defer`
31-
// keyword.
32-
// The compiler knows the JumpPC struct offset.
33-
type DeferFrame struct {
34-
JumpSP unsafe.Pointer // stack pointer to return to
35-
JumpPC unsafe.Pointer // pc to return to
36-
Previous *DeferFrame // previous recover buffer pointer
37-
Panicking bool // true iff this defer frame is panicking
38-
PanicValue interface{} // panic value, might be nil for panic(nil) for example
26+
DeferFrame unsafe.Pointer
3927
}
4028

4129
// getGoroutineStackSize is a compiler intrinsic that returns the stack size for

src/runtime/panic.go

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,29 @@ 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(frame *task.DeferFrame)
16+
func tinygo_longjmp(frame *deferFrame)
1717

1818
// Compiler intrinsic.
1919
// Returns whether recover is supported on the current architecture.
2020
func supportsRecover() bool
2121

22+
// DeferFrame is a stack allocated object that stores information for the
23+
// current "defer frame", which is used in functions that use the `defer`
24+
// keyword.
25+
// The compiler knows about the JumpPC struct offset, so it should not be moved
26+
// without also updating compiler/defer.go.
27+
type deferFrame struct {
28+
JumpSP unsafe.Pointer // stack pointer to return to
29+
JumpPC unsafe.Pointer // pc to return to
30+
Previous *deferFrame // previous recover buffer pointer
31+
Panicking bool // true iff this defer frame is panicking
32+
PanicValue interface{} // panic value, might be nil for panic(nil) for example
33+
}
34+
2235
// Builtin function panic(msg), used as a compiler intrinsic.
2336
func _panic(message interface{}) {
2437
if supportsRecover() {
25-
frame := task.Current().DeferFrame
38+
frame := (*deferFrame)(task.Current().DeferFrame)
2639
if frame != nil {
2740
frame.PanicValue = message
2841
frame.Panicking = true
@@ -49,21 +62,21 @@ func runtimePanic(msg string) {
4962
// that will be used.
5063
//go:inline
5164
//go:nobounds
52-
func setupDeferFrame(frame *task.DeferFrame, jumpSP unsafe.Pointer) {
65+
func setupDeferFrame(frame *deferFrame, jumpSP unsafe.Pointer) {
5366
currentTask := task.Current()
54-
frame.Previous = currentTask.DeferFrame
67+
frame.Previous = (*deferFrame)(currentTask.DeferFrame)
5568
frame.JumpSP = jumpSP
5669
frame.Panicking = false
57-
currentTask.DeferFrame = frame
70+
currentTask.DeferFrame = unsafe.Pointer(frame)
5871
}
5972

6073
// Called right before the return instruction. It pops the defer frame from the
6174
// linked list of defer frames. It also re-raises a panic if the goroutine is
6275
// still panicking.
6376
//go:inline
6477
//go:nobounds
65-
func destroyDeferFrame(frame *task.DeferFrame) {
66-
task.Current().DeferFrame = frame.Previous
78+
func destroyDeferFrame(frame *deferFrame) {
79+
task.Current().DeferFrame = unsafe.Pointer(frame.Previous)
6780
if frame.Panicking {
6881
// We're still panicking!
6982
// Re-raise the panic now.
@@ -83,7 +96,7 @@ func _recover(useParentFrame bool) interface{} {
8396
// TODO: somehow check that recover() is called directly by a deferred
8497
// function in a panicking goroutine. Maybe this can be done by comparing
8598
// the frame pointer?
86-
frame := task.Current().DeferFrame
99+
frame := (*deferFrame)(task.Current().DeferFrame)
87100
if useParentFrame {
88101
// Don't recover panic from the current frame (which can't be panicking
89102
// already), but instead from the previous frame.

0 commit comments

Comments
 (0)