From patchwork Fri Oct 3 15:51:40 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Lance Taylor X-Patchwork-Id: 396285 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 87CDD140174 for ; Sat, 4 Oct 2014 01:51:52 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type; q=dns; s= default; b=NfwICT+jQ5MJzdzsMjVhXXfRjf5iUe+iG+2hmnQ16yju04kT8jz0p 08jk/oCBwpjv739BCwbnopBmCX5fIKE1BFZoIbe9PBxByTJR6hIqX1qYPpF/G9Vt Y/oqhoNmau98zLmoWUxOGyUunUxaUZVcxcYLQGVfu9FipCb0v63Xto= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type; s= default; bh=N72Ih041vBMqjVY51nES323kOHs=; b=nZf5t8J7n1GflElrwhaO EvJYjlCGpj9JnDNwNNTLIGxPqQ4/ekTwMnzRpoJ06Z6fK4uYnj8NznRMvsUIYvSL LdWAJKr1Ug+2DMS18Drii1CYcmrRA+AIyt2BLeQkDPLkLixI1UsyDvprgS1XV/vG shwfMjeWjEadmTU0QXWmnP4= Received: (qmail 6108 invoked by alias); 3 Oct 2014 15:51:46 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 6096 invoked by uid 89); 3 Oct 2014 15:51:45 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW, SPF_PASS, T_RP_MATCHES_RCVD, T_TVD_MIME_NO_HEADERS autolearn=ham version=3.3.2 X-HELO: mail-pd0-f176.google.com Received: from mail-pd0-f176.google.com (HELO mail-pd0-f176.google.com) (209.85.192.176) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Fri, 03 Oct 2014 15:51:44 +0000 Received: by mail-pd0-f176.google.com with SMTP id fp1so2705967pdb.7 for ; Fri, 03 Oct 2014 08:51:42 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id:user-agent :mime-version:content-type; bh=4bom7/qP0C7vcC3yOYhXLSs4dd3RYYqXqV/62K8aYG4=; b=fl7jlh8wSM9rQ1QGsxxLAvCe2Vv6esdOBg3R3yeeEfPPHrL8Lxn5T/+WfGAbajOrVR PyUOtNh5zqTMwuYtzdF69w/30ZvengsgxCQtEw+67q34vo50q/gp0Vr/GSnzcJx9Xkci KdXHVxz0/SGJrfoxbtMMyPiHLotM6C/RkbQJeIhp+m7n1BQaWI1G62LCHb9PhGu5H3xF IeFmVI2xhXY7+7V6HqpTElVWivqob8RtlpAw0OjHlu92BcS9MaUXvT+c+9WMrCfXGPtA 4CQ0tcQQFGtIYQ0/PYVO3yFb2rlwEcWZM3Q/66e73yWXbOjRzeWcEl+AgMHLVgYUJAN/ HsTQ== X-Gm-Message-State: ALoCoQmJ4ltNnVGrw6p5OVGp9eWOuKOOYJG5MkYizR2ULL2FQHDowXx8I+TEGP9fLZTA3S7rIYMU X-Received: by 10.70.129.33 with SMTP id nt1mr1686352pdb.166.1412351502066; Fri, 03 Oct 2014 08:51:42 -0700 (PDT) Received: from iant-glaptop.roam.corp.google.com.google.com ([2620:0:1000:157d:c1e1:8ec0:ad7a:27e6]) by mx.google.com with ESMTPSA id i13sm4428490pdm.93.2014.10.03.08.51.40 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Fri, 03 Oct 2014 08:51:41 -0700 (PDT) From: Ian Lance Taylor To: gcc-patches@gcc.gnu.org, gofrontend@googlegroups.com Subject: libgo patch committed: Fix reflection of variadic methods Date: Fri, 03 Oct 2014 08:51:40 -0700 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3 (gnu/linux) MIME-Version: 1.0 X-IsSubscribed: yes This patch from Michael Hudson-Doyle fixes PR 61877 which is about using reflection to get a variadic method value. Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu. Committed to mainline. Ian diff -r 9a88882ca32c libgo/go/reflect/all_test.go --- a/libgo/go/reflect/all_test.go Fri Oct 03 08:13:20 2014 -0700 +++ b/libgo/go/reflect/all_test.go Fri Oct 03 08:50:04 2014 -0700 @@ -1543,7 +1543,17 @@ fv := MakeFunc(TypeOf(fn), func(in []Value) []Value { return in[1:2] }) ValueOf(&fn).Elem().Set(fv) - r := fv.Call([]Value{ValueOf(1), ValueOf(2), ValueOf(3)})[0].Interface().([]int) + r := fn(1, 2, 3) + if r[0] != 2 || r[1] != 3 { + t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1]) + } + + r = fn(1, []int{2, 3}...) + if r[0] != 2 || r[1] != 3 { + t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1]) + } + + r = fv.Call([]Value{ValueOf(1), ValueOf(2), ValueOf(3)})[0].Interface().([]int) if r[0] != 2 || r[1] != 3 { t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1]) } @@ -1552,6 +1562,17 @@ if r[0] != 2 || r[1] != 3 { t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1]) } + + f := fv.Interface().(func(int, ...int) []int) + + r = f(1, 2, 3) + if r[0] != 2 || r[1] != 3 { + t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1]) + } + r = f(1, []int{2, 3}...) + if r[0] != 2 || r[1] != 3 { + t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1]) + } } type Point struct { @@ -1569,6 +1590,24 @@ return p.x*p.x*scale + p.y*p.y*scale } +// This will be index 2. +func (p Point) GCMethod(k int) int { + runtime.GC() + return k + p.x +} + +// This will be index 3. +func (p Point) TotalDist(points ...Point) int { + tot := 0 + for _, q := range points { + dx := q.x - p.x + dy := q.y - p.y + tot += dx*dx + dy*dy // Should call Sqrt, but it's just a test. + + } + return tot +} + func TestMethod(t *testing.T) { // Non-curried method of type. p := Point{3, 4} @@ -1751,6 +1790,37 @@ } } +func TestVariadicMethodValue(t *testing.T) { + p := Point{3, 4} + points := []Point{{20, 21}, {22, 23}, {24, 25}} + want := int64(p.TotalDist(points[0], points[1], points[2])) + + // Curried method of value. + tfunc := TypeOf((func(...Point) int)(nil)) + v := ValueOf(p).Method(3) + if tt := v.Type(); tt != tfunc { + t.Errorf("Variadic Method Type is %s; want %s", tt, tfunc) + } + i := ValueOf(v.Interface()).Call([]Value{ValueOf(points[0]), ValueOf(points[1]), ValueOf(points[2])})[0].Int() + if i != want { + t.Errorf("Variadic Method returned %d; want %d", i, want) + } + i = ValueOf(v.Interface()).CallSlice([]Value{ValueOf(points)})[0].Int() + if i != want { + t.Errorf("Variadic Method CallSlice returned %d; want %d", i, want) + } + + f := v.Interface().(func(...Point) int) + i = int64(f(points[0], points[1], points[2])) + if i != want { + t.Errorf("Variadic Method Interface returned %d; want %d", i, want) + } + i = int64(f(points...)) + if i != want { + t.Errorf("Variadic Method Interface Slice returned %d; want %d", i, want) + } +} + // Reflect version of $GOROOT/test/method5.go // Concrete types implementing M method. @@ -3718,11 +3788,6 @@ f.Call([]Value{}) } -func (p Point) GCMethod(k int) int { - runtime.GC() - return k + p.x -} - func TestReflectMethodTraceback(t *testing.T) { p := Point{3, 4} m := ValueOf(p).MethodByName("GCMethod") diff -r 9a88882ca32c libgo/go/reflect/makefunc.go --- a/libgo/go/reflect/makefunc.go Fri Oct 03 08:13:20 2014 -0700 +++ b/libgo/go/reflect/makefunc.go Fri Oct 03 08:50:04 2014 -0700 @@ -117,29 +117,21 @@ ftyp := (*funcType)(unsafe.Pointer(t)) method := int(v.flag) >> flagMethodShift - var code uintptr - var ffi *ffiData + fv := &makeFuncImpl{ + typ: ftyp, + method: method, + rcvr: rcvr, + } + switch runtime.GOARCH { case "amd64", "386": // Indirect Go func value (dummy) to obtain actual // code address. (A Go func value is a pointer to a C // function pointer. http://golang.org/s/go11func.) dummy := makeFuncStub - code = **(**uintptr)(unsafe.Pointer(&dummy)) + fv.code = **(**uintptr)(unsafe.Pointer(&dummy)) default: - code, ffi = makeFuncFFI(ftyp, - func(in []Value) []Value { - m := rcvr.Method(method) - return m.Call(in) - }) - } - - fv := &makeFuncImpl{ - code: code, - typ: ftyp, - method: method, - rcvr: rcvr, - ffi: ffi, + fv.code, fv.ffi = makeFuncFFI(ftyp, fv.call) } return Value{ft, unsafe.Pointer(&fv), v.flag&flagRO | flag(Func)<