From 0a99eb48c3978d842d1b9623a8ac26ea2b9eb7d8 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Mon, 23 Mar 2020 13:40:03 +0100 Subject: [PATCH] fix: do not pass twice the receiver in deferred method calls --- _test/cli2.go | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++ interp/run.go | 4 ++++ 2 files changed, 63 insertions(+) create mode 100644 _test/cli2.go diff --git a/_test/cli2.go b/_test/cli2.go new file mode 100644 index 00000000..a9e8e53b --- /dev/null +++ b/_test/cli2.go @@ -0,0 +1,59 @@ +package main + +import ( + "fmt" + "io/ioutil" + "log" + "net" + "net/http" +) + +type T struct { + ln net.Listener +} + +func (t *T) Close() { + t.ln.Close() +} + +func client(uri string) { + resp, err := http.Get(uri) + if err != nil { + log.Fatal(err) + } + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + log.Fatal(err) + } + fmt.Println(string(body)) +} + +func server(ln net.Listener, ready chan bool) { + http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) { + var r1 *http.Request = r + fmt.Fprintln(w, "Welcome to my website!", r1.RequestURI) + }) + + go http.Serve(ln, nil) + ready <- true +} + +func main() { + ln, err := net.Listen("tcp", "localhost:0") + t := &T{ln} + if err != nil { + log.Fatal(err) + } + defer t.Close() + // defer ln.Close() + + ready := make(chan bool) + go server(ln, ready) + <-ready + + client(fmt.Sprintf("http://%s/hello", ln.Addr().String())) + http.DefaultServeMux = &http.ServeMux{} +} + +// Output: +// Welcome to my website! /hello diff --git a/interp/run.go b/interp/run.go index cd37598a..120a62c6 100644 --- a/interp/run.go +++ b/interp/run.go @@ -669,6 +669,10 @@ func call(n *node) { if n.anc.kind == deferStmt { // Store function call in frame for deferred execution. value = genFunctionWrapper(n.child[0]) + if method { + // The receiver is already passed in the function wrapper, skip it. + values = values[1:] + } n.exec = func(f *frame) bltn { val := make([]reflect.Value, len(values)+1) val[0] = value(f)