Skip to content

Commit 607d824

Browse files
aykevldeadprogram
authored andcommitted
interp: keep reverted package initializers in order
Previously, a package initializer that could not be reverted correctly would be called at runtime. But the initializer would be called in the wrong order: after later packages are initialized. This commit fixes this oversight and adds a test to verify the new behavior.
1 parent 8cc7c6d commit 607d824

File tree

4 files changed

+40
-1
lines changed

4 files changed

+40
-1
lines changed

interp/interp.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,17 +110,19 @@ func Run(mod llvm.Module, debug bool) error {
110110
fmt.Fprintln(os.Stderr, "call:", fn.Name())
111111
}
112112
_, mem, callErr := r.run(r.getFunction(fn), nil, nil, " ")
113+
call.EraseFromParentAsInstruction()
113114
if callErr != nil {
114115
if isRecoverableError(callErr.Err) {
115116
if r.debug {
116117
fmt.Fprintln(os.Stderr, "not interpreting", r.pkgName, "because of error:", callErr.Error())
117118
}
118119
mem.revert()
120+
i8undef := llvm.Undef(r.i8ptrType)
121+
r.builder.CreateCall(fn, []llvm.Value{i8undef, i8undef}, "")
119122
continue
120123
}
121124
return callErr
122125
}
123-
call.EraseFromParentAsInstruction()
124126
for index, obj := range mem.objects {
125127
r.objects[index] = obj
126128
}

interp/interp_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ func TestInterp(t *testing.T) {
1717
"slice-copy",
1818
"consteval",
1919
"interface",
20+
"revert",
2021
} {
2122
name := name // make tc local to this closure
2223
t.Run(name, func(t *testing.T) {

interp/testdata/revert.ll

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2+
target triple = "x86_64--linux"
3+
4+
declare void @externalCall(i64)
5+
6+
define void @runtime.initAll() unnamed_addr {
7+
entry:
8+
call void @foo.init(i8* undef, i8* undef)
9+
call void @main.init(i8* undef, i8* undef)
10+
ret void
11+
}
12+
13+
define internal void @foo.init(i8* %context, i8* %parentHandle) unnamed_addr {
14+
unreachable ; this triggers a revert of @foo.init.
15+
}
16+
17+
define internal void @main.init(i8* %context, i8* %parentHandle) unnamed_addr {
18+
entry:
19+
call void @externalCall(i64 3)
20+
ret void
21+
}

interp/testdata/revert.out.ll

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2+
target triple = "x86_64--linux"
3+
4+
declare void @externalCall(i64) local_unnamed_addr
5+
6+
define void @runtime.initAll() unnamed_addr {
7+
entry:
8+
call fastcc void @foo.init(i8* undef, i8* undef)
9+
call void @externalCall(i64 3)
10+
ret void
11+
}
12+
13+
define internal fastcc void @foo.init(i8* %context, i8* %parentHandle) unnamed_addr {
14+
unreachable
15+
}

0 commit comments

Comments
 (0)