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.
Этот коммит содержится в:
родитель
8cc7c6d572
коммит
607d824211
4 изменённых файлов: 40 добавлений и 1 удалений
|
@ -110,17 +110,19 @@ func Run(mod llvm.Module, debug bool) error {
|
|||
fmt.Fprintln(os.Stderr, "call:", fn.Name())
|
||||
}
|
||||
_, mem, callErr := r.run(r.getFunction(fn), nil, nil, " ")
|
||||
call.EraseFromParentAsInstruction()
|
||||
if callErr != nil {
|
||||
if isRecoverableError(callErr.Err) {
|
||||
if r.debug {
|
||||
fmt.Fprintln(os.Stderr, "not interpreting", r.pkgName, "because of error:", callErr.Error())
|
||||
}
|
||||
mem.revert()
|
||||
i8undef := llvm.Undef(r.i8ptrType)
|
||||
r.builder.CreateCall(fn, []llvm.Value{i8undef, i8undef}, "")
|
||||
continue
|
||||
}
|
||||
return callErr
|
||||
}
|
||||
call.EraseFromParentAsInstruction()
|
||||
for index, obj := range mem.objects {
|
||||
r.objects[index] = obj
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ func TestInterp(t *testing.T) {
|
|||
"slice-copy",
|
||||
"consteval",
|
||||
"interface",
|
||||
"revert",
|
||||
} {
|
||||
name := name // make tc local to this closure
|
||||
t.Run(name, func(t *testing.T) {
|
||||
|
|
21
interp/testdata/revert.ll
предоставленный
Обычный файл
21
interp/testdata/revert.ll
предоставленный
Обычный файл
|
@ -0,0 +1,21 @@
|
|||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64--linux"
|
||||
|
||||
declare void @externalCall(i64)
|
||||
|
||||
define void @runtime.initAll() unnamed_addr {
|
||||
entry:
|
||||
call void @foo.init(i8* undef, i8* undef)
|
||||
call void @main.init(i8* undef, i8* undef)
|
||||
ret void
|
||||
}
|
||||
|
||||
define internal void @foo.init(i8* %context, i8* %parentHandle) unnamed_addr {
|
||||
unreachable ; this triggers a revert of @foo.init.
|
||||
}
|
||||
|
||||
define internal void @main.init(i8* %context, i8* %parentHandle) unnamed_addr {
|
||||
entry:
|
||||
call void @externalCall(i64 3)
|
||||
ret void
|
||||
}
|
15
interp/testdata/revert.out.ll
предоставленный
Обычный файл
15
interp/testdata/revert.out.ll
предоставленный
Обычный файл
|
@ -0,0 +1,15 @@
|
|||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64--linux"
|
||||
|
||||
declare void @externalCall(i64) local_unnamed_addr
|
||||
|
||||
define void @runtime.initAll() unnamed_addr {
|
||||
entry:
|
||||
call fastcc void @foo.init(i8* undef, i8* undef)
|
||||
call void @externalCall(i64 3)
|
||||
ret void
|
||||
}
|
||||
|
||||
define internal fastcc void @foo.init(i8* %context, i8* %parentHandle) unnamed_addr {
|
||||
unreachable
|
||||
}
|
Загрузка…
Создание таблицы
Сослаться в новой задаче