The following program sample.go triggers an unexpected result
package main
import (
"reflect"
"github.com/traefik/yaegi/interp"
)
type TestInterface interface {
AFunc()
}
type Test struct{}
func (t *Test) AFunc() {}
func main() {
exe := interp.New(interp.Options{})
exe.Use(interp.Exports{
"exe/exe": map[string]reflect.Value{
"TestInterface": reflect.ValueOf((*TestInterface)(nil)),
"Test": reflect.ValueOf((*Test)(nil)),
},
})
exe.Eval(`
package main
import "exe"
type Test struct {}
func (t Test) AFunc() {}
func main() {
println("main!")
t()
}
func t() {
println("t")
var a exe.TestInterface
a.AFunc() // This is the problematic line, but it's not pointed to
var b exe.TestInterface = &exe.Test{}
b.AFunc()
println("a")
}
`)
}
Expected result
main!
t
19:3: panic: main.t(...)
11:3: panic: main.main(...)
Got
main!
t
17:3: panic: main.t(...)
11:3: panic: main.main(...)
Yaegi Version
fcb76d1
Additional Notes
This is a bug that appears when getting a runtime error (for example, a nil-pointer exception) and Yaegi outputs a stack trace as to the bug's location.
Instead of it being the line of the offending statement, it's the beginning of the function that contains the offending statement. I believe this has to do with the runCfg() function in interp/run.go here:
https://github.com/traefik/yaegi/blob/master/interp/run.go#L205
Firstly, I believe the first line, var exec bltn, is never assigned to throughout the function, which makes getting its ownership incorrect. In addition, originalExecNode() is not working properly either, as I think the line that determines original execution (?), here:
https://github.com/traefik/yaegi/blob/master/interp/run.go#L159
seems to test if the built-in function being executed (bltn) is the same type as the offending function, rather than if it's the same function exactly...? Like, it's comparing pointers for the function values themselves, which point to one of a series of functions, so, another line with the same kind of function in the source would trigger this "get original node" code, I think.
I started working on resolving this, but I need some help figuring out exactly what to do, since I'm not super familiar with
AST tree traversal and interpreters.
EDIT: Updated the example with a better one.
The following program
sample.gotriggers an unexpected resultExpected result
Got
Yaegi Version
fcb76d1
Additional Notes
This is a bug that appears when getting a runtime error (for example, a nil-pointer exception) and Yaegi outputs a stack trace as to the bug's location.
Instead of it being the line of the offending statement, it's the beginning of the function that contains the offending statement. I believe this has to do with the
runCfg()function ininterp/run.gohere:https://github.com/traefik/yaegi/blob/master/interp/run.go#L205
Firstly, I believe the first line,
var exec bltn, is never assigned to throughout the function, which makes getting its ownership incorrect. In addition,originalExecNode()is not working properly either, as I think the line that determines original execution (?), here:https://github.com/traefik/yaegi/blob/master/interp/run.go#L159
seems to test if the built-in function being executed (
bltn) is the same type as the offending function, rather than if it's the same function exactly...? Like, it's comparing pointers for the function values themselves, which point to one of a series of functions, so, another line with the same kind of function in the source would trigger this "get original node" code, I think.I started working on resolving this, but I need some help figuring out exactly what to do, since I'm not super familiar with
AST tree traversal and interpreters.
EDIT: Updated the example with a better one.