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.
Этот коммит содержится в:
родитель
49e22fe678
коммит
159f0051bb
7 изменённых файлов: 45 добавлений и 50 удалений
|
@ -71,7 +71,7 @@ func (b *builder) deferInitFunc() {
|
|||
// possibly broken by the C alloca function).
|
||||
// The frame pointer is _not_ saved, because it is marked as clobbered
|
||||
// in the setjmp-like inline assembly.
|
||||
deferFrameType := b.getLLVMType(b.program.ImportedPackage("internal/task").Members["DeferFrame"].Type())
|
||||
deferFrameType := b.getLLVMRuntimeType("deferFrame")
|
||||
b.deferFrame = b.CreateAlloca(deferFrameType, "deferframe.buf")
|
||||
stackPointer := b.readStackPointer()
|
||||
b.createRuntimeCall("setupDeferFrame", []llvm.Value{b.deferFrame, stackPointer}, "")
|
||||
|
|
4
compiler/testdata/channel.ll
предоставленный
4
compiler/testdata/channel.ll
предоставленный
|
@ -5,12 +5,10 @@ target triple = "wasm32-unknown-wasi"
|
|||
|
||||
%runtime.channel = type { i32, i32, i8, %runtime.channelBlockedList*, i32, i32, i32, i8* }
|
||||
%runtime.channelBlockedList = type { %runtime.channelBlockedList*, %"internal/task.Task"*, %runtime.chanSelectState*, { %runtime.channelBlockedList*, i32, i32 } }
|
||||
%"internal/task.Task" = type { %"internal/task.Task"*, i8*, i64, %"internal/task.gcData", %"internal/task.state", %"internal/task.DeferFrame"* }
|
||||
%"internal/task.Task" = type { %"internal/task.Task"*, i8*, i64, %"internal/task.gcData", %"internal/task.state", i8* }
|
||||
%"internal/task.gcData" = type { i8* }
|
||||
%"internal/task.state" = type { i32, i8*, %"internal/task.stackState", i1 }
|
||||
%"internal/task.stackState" = type { i32, i32 }
|
||||
%"internal/task.DeferFrame" = type { i8*, i8*, %"internal/task.DeferFrame"*, i1, %runtime._interface }
|
||||
%runtime._interface = type { i32, i8* }
|
||||
%runtime.chanSelectState = type { %runtime.channel*, i8* }
|
||||
|
||||
declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*)
|
||||
|
|
38
compiler/testdata/defer-cortex-m-qemu.ll
предоставленный
38
compiler/testdata/defer-cortex-m-qemu.ll
предоставленный
|
@ -4,7 +4,7 @@ target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
|
|||
target triple = "thumbv7m-unknown-unknown-eabi"
|
||||
|
||||
%runtime._defer = type { i32, %runtime._defer* }
|
||||
%"internal/task.DeferFrame" = type { i8*, i8*, %"internal/task.DeferFrame"*, i1, %runtime._interface }
|
||||
%runtime.deferFrame = type { i8*, i8*, %runtime.deferFrame*, i1, %runtime._interface }
|
||||
%runtime._interface = type { i32, i8* }
|
||||
|
||||
declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0
|
||||
|
@ -23,16 +23,16 @@ entry:
|
|||
%defer.alloca = alloca { i32, %runtime._defer* }, align 4
|
||||
%deferPtr = alloca %runtime._defer*, align 4
|
||||
store %runtime._defer* null, %runtime._defer** %deferPtr, align 4
|
||||
%deferframe.buf = alloca %"internal/task.DeferFrame", align 4
|
||||
%deferframe.buf = alloca %runtime.deferFrame, align 4
|
||||
%0 = call i8* @llvm.stacksave()
|
||||
call void @runtime.setupDeferFrame(%"internal/task.DeferFrame"* nonnull %deferframe.buf, i8* %0, i8* undef) #3
|
||||
call void @runtime.setupDeferFrame(%runtime.deferFrame* nonnull %deferframe.buf, i8* %0, i8* undef) #3
|
||||
%defer.alloca.repack = getelementptr inbounds { i32, %runtime._defer* }, { i32, %runtime._defer* }* %defer.alloca, i32 0, i32 0
|
||||
store i32 0, i32* %defer.alloca.repack, align 4
|
||||
%defer.alloca.repack16 = getelementptr inbounds { i32, %runtime._defer* }, { i32, %runtime._defer* }* %defer.alloca, i32 0, i32 1
|
||||
store %runtime._defer* null, %runtime._defer** %defer.alloca.repack16, align 4
|
||||
%1 = bitcast %runtime._defer** %deferPtr to { i32, %runtime._defer* }**
|
||||
store { i32, %runtime._defer* }* %defer.alloca, { i32, %runtime._defer* }** %1, align 4
|
||||
%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
|
||||
%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
|
||||
%setjmp.result = icmp eq i32 %setjmp, 0
|
||||
br i1 %setjmp.result, label %2, label %lpad
|
||||
|
||||
|
@ -56,7 +56,7 @@ rundefers.loop: ; preds = %rundefers.loophead
|
|||
]
|
||||
|
||||
rundefers.callback0: ; preds = %rundefers.loop
|
||||
%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
|
||||
%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
|
||||
%setjmp.result2 = icmp eq i32 %setjmp1, 0
|
||||
br i1 %setjmp.result2, label %4, label %lpad
|
||||
|
||||
|
@ -68,11 +68,11 @@ rundefers.default: ; preds = %rundefers.loop
|
|||
unreachable
|
||||
|
||||
rundefers.end: ; preds = %rundefers.loophead
|
||||
call void @runtime.destroyDeferFrame(%"internal/task.DeferFrame"* nonnull %deferframe.buf, i8* undef) #3
|
||||
call void @runtime.destroyDeferFrame(%runtime.deferFrame* nonnull %deferframe.buf, i8* undef) #3
|
||||
ret void
|
||||
|
||||
recover: ; preds = %rundefers.end3
|
||||
call void @runtime.destroyDeferFrame(%"internal/task.DeferFrame"* nonnull %deferframe.buf, i8* undef) #3
|
||||
call void @runtime.destroyDeferFrame(%runtime.deferFrame* nonnull %deferframe.buf, i8* undef) #3
|
||||
ret void
|
||||
|
||||
lpad: ; preds = %rundefers.callback012, %rundefers.callback0, %entry
|
||||
|
@ -94,7 +94,7 @@ rundefers.loop5: ; preds = %rundefers.loophead6
|
|||
]
|
||||
|
||||
rundefers.callback012: ; preds = %rundefers.loop5
|
||||
%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
|
||||
%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
|
||||
%setjmp.result15 = icmp eq i32 %setjmp14, 0
|
||||
br i1 %setjmp.result15, label %6, label %lpad
|
||||
|
||||
|
@ -112,7 +112,7 @@ rundefers.end3: ; preds = %rundefers.loophead6
|
|||
; Function Attrs: nofree nosync nounwind willreturn
|
||||
declare i8* @llvm.stacksave() #2
|
||||
|
||||
declare void @runtime.setupDeferFrame(%"internal/task.DeferFrame"* dereferenceable_or_null(24), i8*, i8*) #0
|
||||
declare void @runtime.setupDeferFrame(%runtime.deferFrame* dereferenceable_or_null(24), i8*, i8*) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @"main.deferSimple$1"(i8* %context) unnamed_addr #1 {
|
||||
|
@ -121,7 +121,7 @@ entry:
|
|||
ret void
|
||||
}
|
||||
|
||||
declare void @runtime.destroyDeferFrame(%"internal/task.DeferFrame"* dereferenceable_or_null(24), i8*) #0
|
||||
declare void @runtime.destroyDeferFrame(%runtime.deferFrame* dereferenceable_or_null(24), i8*) #0
|
||||
|
||||
declare void @runtime.printint32(i32, i8*) #0
|
||||
|
||||
|
@ -132,9 +132,9 @@ entry:
|
|||
%defer.alloca = alloca { i32, %runtime._defer* }, align 4
|
||||
%deferPtr = alloca %runtime._defer*, align 4
|
||||
store %runtime._defer* null, %runtime._defer** %deferPtr, align 4
|
||||
%deferframe.buf = alloca %"internal/task.DeferFrame", align 4
|
||||
%deferframe.buf = alloca %runtime.deferFrame, align 4
|
||||
%0 = call i8* @llvm.stacksave()
|
||||
call void @runtime.setupDeferFrame(%"internal/task.DeferFrame"* nonnull %deferframe.buf, i8* %0, i8* undef) #3
|
||||
call void @runtime.setupDeferFrame(%runtime.deferFrame* nonnull %deferframe.buf, i8* %0, i8* undef) #3
|
||||
%defer.alloca.repack = getelementptr inbounds { i32, %runtime._defer* }, { i32, %runtime._defer* }* %defer.alloca, i32 0, i32 0
|
||||
store i32 0, i32* %defer.alloca.repack, align 4
|
||||
%defer.alloca.repack26 = getelementptr inbounds { i32, %runtime._defer* }, { i32, %runtime._defer* }* %defer.alloca, i32 0, i32 1
|
||||
|
@ -148,7 +148,7 @@ entry:
|
|||
store { i32, %runtime._defer* }* %defer.alloca, { i32, %runtime._defer* }** %2, align 4
|
||||
%3 = bitcast %runtime._defer** %deferPtr to { i32, %runtime._defer* }**
|
||||
store { i32, %runtime._defer* }* %defer.alloca2, { i32, %runtime._defer* }** %3, align 4
|
||||
%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
|
||||
%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
|
||||
%setjmp.result = icmp eq i32 %setjmp, 0
|
||||
br i1 %setjmp.result, label %4, label %lpad
|
||||
|
||||
|
@ -173,7 +173,7 @@ rundefers.loop: ; preds = %rundefers.loophead
|
|||
]
|
||||
|
||||
rundefers.callback0: ; preds = %rundefers.loop
|
||||
%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
|
||||
%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
|
||||
%setjmp.result5 = icmp eq i32 %setjmp4, 0
|
||||
br i1 %setjmp.result5, label %6, label %lpad
|
||||
|
||||
|
@ -182,7 +182,7 @@ rundefers.callback0: ; preds = %rundefers.loop
|
|||
br label %rundefers.loophead
|
||||
|
||||
rundefers.callback1: ; preds = %rundefers.loop
|
||||
%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
|
||||
%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
|
||||
%setjmp.result8 = icmp eq i32 %setjmp7, 0
|
||||
br i1 %setjmp.result8, label %7, label %lpad
|
||||
|
||||
|
@ -194,11 +194,11 @@ rundefers.default: ; preds = %rundefers.loop
|
|||
unreachable
|
||||
|
||||
rundefers.end: ; preds = %rundefers.loophead
|
||||
call void @runtime.destroyDeferFrame(%"internal/task.DeferFrame"* nonnull %deferframe.buf, i8* undef) #3
|
||||
call void @runtime.destroyDeferFrame(%runtime.deferFrame* nonnull %deferframe.buf, i8* undef) #3
|
||||
ret void
|
||||
|
||||
recover: ; preds = %rundefers.end9
|
||||
call void @runtime.destroyDeferFrame(%"internal/task.DeferFrame"* nonnull %deferframe.buf, i8* undef) #3
|
||||
call void @runtime.destroyDeferFrame(%runtime.deferFrame* nonnull %deferframe.buf, i8* undef) #3
|
||||
ret void
|
||||
|
||||
lpad: ; preds = %rundefers.callback122, %rundefers.callback018, %rundefers.callback1, %rundefers.callback0, %entry
|
||||
|
@ -221,7 +221,7 @@ rundefers.loop11: ; preds = %rundefers.loophead1
|
|||
]
|
||||
|
||||
rundefers.callback018: ; preds = %rundefers.loop11
|
||||
%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
|
||||
%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
|
||||
%setjmp.result21 = icmp eq i32 %setjmp20, 0
|
||||
br i1 %setjmp.result21, label %9, label %lpad
|
||||
|
||||
|
@ -230,7 +230,7 @@ rundefers.callback018: ; preds = %rundefers.loop11
|
|||
br label %rundefers.loophead12
|
||||
|
||||
rundefers.callback122: ; preds = %rundefers.loop11
|
||||
%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
|
||||
%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
|
||||
%setjmp.result25 = icmp eq i32 %setjmp24, 0
|
||||
br i1 %setjmp.result25, label %10, label %lpad
|
||||
|
||||
|
|
4
compiler/testdata/goroutine-cortex-m-qemu-tasks.ll
предоставленный
4
compiler/testdata/goroutine-cortex-m-qemu-tasks.ll
предоставленный
|
@ -5,11 +5,9 @@ target triple = "thumbv7m-unknown-unknown-eabi"
|
|||
|
||||
%runtime.channel = type { i32, i32, i8, %runtime.channelBlockedList*, i32, i32, i32, i8* }
|
||||
%runtime.channelBlockedList = type { %runtime.channelBlockedList*, %"internal/task.Task"*, %runtime.chanSelectState*, { %runtime.channelBlockedList*, i32, i32 } }
|
||||
%"internal/task.Task" = type { %"internal/task.Task"*, i8*, i64, %"internal/task.gcData", %"internal/task.state", %"internal/task.DeferFrame"* }
|
||||
%"internal/task.Task" = type { %"internal/task.Task"*, i8*, i64, %"internal/task.gcData", %"internal/task.state", i8* }
|
||||
%"internal/task.gcData" = type {}
|
||||
%"internal/task.state" = type { i32, i32* }
|
||||
%"internal/task.DeferFrame" = type { i8*, i8*, %"internal/task.DeferFrame"*, i1, %runtime._interface }
|
||||
%runtime._interface = type { i32, i8* }
|
||||
%runtime.chanSelectState = type { %runtime.channel*, i8* }
|
||||
|
||||
@"main$string" = internal unnamed_addr constant [4 x i8] c"test", align 1
|
||||
|
|
4
compiler/testdata/goroutine-wasm-asyncify.ll
предоставленный
4
compiler/testdata/goroutine-wasm-asyncify.ll
предоставленный
|
@ -5,12 +5,10 @@ target triple = "wasm32-unknown-wasi"
|
|||
|
||||
%runtime.channel = type { i32, i32, i8, %runtime.channelBlockedList*, i32, i32, i32, i8* }
|
||||
%runtime.channelBlockedList = type { %runtime.channelBlockedList*, %"internal/task.Task"*, %runtime.chanSelectState*, { %runtime.channelBlockedList*, i32, i32 } }
|
||||
%"internal/task.Task" = type { %"internal/task.Task"*, i8*, i64, %"internal/task.gcData", %"internal/task.state", %"internal/task.DeferFrame"* }
|
||||
%"internal/task.Task" = type { %"internal/task.Task"*, i8*, i64, %"internal/task.gcData", %"internal/task.state", i8* }
|
||||
%"internal/task.gcData" = type { i8* }
|
||||
%"internal/task.state" = type { i32, i8*, %"internal/task.stackState", i1 }
|
||||
%"internal/task.stackState" = type { i32, i32 }
|
||||
%"internal/task.DeferFrame" = type { i8*, i8*, %"internal/task.DeferFrame"*, i1, %runtime._interface }
|
||||
%runtime._interface = type { i32, i8* }
|
||||
%runtime.chanSelectState = type { %runtime.channel*, i8* }
|
||||
|
||||
@"main$string" = internal unnamed_addr constant [4 x i8] c"test", align 1
|
||||
|
|
|
@ -23,19 +23,7 @@ type Task struct {
|
|||
|
||||
// DeferFrame stores a pointer to the (stack allocated) defer frame of the
|
||||
// goroutine that is used for the recover builtin.
|
||||
DeferFrame *DeferFrame
|
||||
}
|
||||
|
||||
// DeferFrame is a stack allocated object that stores information for the
|
||||
// current "defer frame", which is used in functions that use the `defer`
|
||||
// keyword.
|
||||
// The compiler knows the JumpPC struct offset.
|
||||
type DeferFrame struct {
|
||||
JumpSP unsafe.Pointer // stack pointer to return to
|
||||
JumpPC unsafe.Pointer // pc to return to
|
||||
Previous *DeferFrame // previous recover buffer pointer
|
||||
Panicking bool // true iff this defer frame is panicking
|
||||
PanicValue interface{} // panic value, might be nil for panic(nil) for example
|
||||
DeferFrame unsafe.Pointer
|
||||
}
|
||||
|
||||
// getGoroutineStackSize is a compiler intrinsic that returns the stack size for
|
||||
|
|
|
@ -13,16 +13,29 @@ func trap()
|
|||
// Inline assembly stub. It is essentially C longjmp but modified a bit for the
|
||||
// purposes of TinyGo. It restores the stack pointer and jumps to the given pc.
|
||||
//export tinygo_longjmp
|
||||
func tinygo_longjmp(frame *task.DeferFrame)
|
||||
func tinygo_longjmp(frame *deferFrame)
|
||||
|
||||
// Compiler intrinsic.
|
||||
// Returns whether recover is supported on the current architecture.
|
||||
func supportsRecover() bool
|
||||
|
||||
// DeferFrame is a stack allocated object that stores information for the
|
||||
// current "defer frame", which is used in functions that use the `defer`
|
||||
// keyword.
|
||||
// The compiler knows about the JumpPC struct offset, so it should not be moved
|
||||
// without also updating compiler/defer.go.
|
||||
type deferFrame struct {
|
||||
JumpSP unsafe.Pointer // stack pointer to return to
|
||||
JumpPC unsafe.Pointer // pc to return to
|
||||
Previous *deferFrame // previous recover buffer pointer
|
||||
Panicking bool // true iff this defer frame is panicking
|
||||
PanicValue interface{} // panic value, might be nil for panic(nil) for example
|
||||
}
|
||||
|
||||
// Builtin function panic(msg), used as a compiler intrinsic.
|
||||
func _panic(message interface{}) {
|
||||
if supportsRecover() {
|
||||
frame := task.Current().DeferFrame
|
||||
frame := (*deferFrame)(task.Current().DeferFrame)
|
||||
if frame != nil {
|
||||
frame.PanicValue = message
|
||||
frame.Panicking = true
|
||||
|
@ -49,12 +62,12 @@ func runtimePanic(msg string) {
|
|||
// that will be used.
|
||||
//go:inline
|
||||
//go:nobounds
|
||||
func setupDeferFrame(frame *task.DeferFrame, jumpSP unsafe.Pointer) {
|
||||
func setupDeferFrame(frame *deferFrame, jumpSP unsafe.Pointer) {
|
||||
currentTask := task.Current()
|
||||
frame.Previous = currentTask.DeferFrame
|
||||
frame.Previous = (*deferFrame)(currentTask.DeferFrame)
|
||||
frame.JumpSP = jumpSP
|
||||
frame.Panicking = false
|
||||
currentTask.DeferFrame = frame
|
||||
currentTask.DeferFrame = unsafe.Pointer(frame)
|
||||
}
|
||||
|
||||
// Called right before the return instruction. It pops the defer frame from the
|
||||
|
@ -62,8 +75,8 @@ func setupDeferFrame(frame *task.DeferFrame, jumpSP unsafe.Pointer) {
|
|||
// still panicking.
|
||||
//go:inline
|
||||
//go:nobounds
|
||||
func destroyDeferFrame(frame *task.DeferFrame) {
|
||||
task.Current().DeferFrame = frame.Previous
|
||||
func destroyDeferFrame(frame *deferFrame) {
|
||||
task.Current().DeferFrame = unsafe.Pointer(frame.Previous)
|
||||
if frame.Panicking {
|
||||
// We're still panicking!
|
||||
// Re-raise the panic now.
|
||||
|
@ -83,7 +96,7 @@ func _recover(useParentFrame bool) interface{} {
|
|||
// TODO: somehow check that recover() is called directly by a deferred
|
||||
// function in a panicking goroutine. Maybe this can be done by comparing
|
||||
// the frame pointer?
|
||||
frame := task.Current().DeferFrame
|
||||
frame := (*deferFrame)(task.Current().DeferFrame)
|
||||
if useParentFrame {
|
||||
// Don't recover panic from the current frame (which can't be panicking
|
||||
// already), but instead from the previous frame.
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче