From c261c465a92a350d05c4232cc2005b4b486d53f2 Mon Sep 17 00:00:00 2001 From: "Hyang-Ah (Hana) Kim" Date: Mon, 27 Jul 2015 12:48:33 -0400 Subject: [PATCH] bind: seq.Transact requires interface descriptor. seq.Transact is called when Go calls a method of a foreign object that implements a Go interface. Currently, we assume that the foreign object has an instance method that can conduct the message routing, so the object id and the method code is sufficient for transact. Passing the interface descriptor (e.g. go.testpkg.I) however allows the bind internal to use non-instance methods to implement the routing. Change-Id: I1f61a04f919fbd09117ea332d678cd50e4861e46 Reviewed-on: https://go-review.googlesource.com/12685 Reviewed-by: David Crawshaw --- bind/gengo.go | 8 +++++--- bind/java/seq_android.go | 4 ++-- bind/seq/seq.go | 2 +- bind/testdata/interfaces.go.golden | 4 ++-- bind/testdata/issue10788.go.golden | 4 ++-- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/bind/gengo.go b/bind/gengo.go index 13e2507..56a62ec 100644 --- a/bind/gengo.go +++ b/bind/gengo.go @@ -238,10 +238,12 @@ func (g *goGen) genStruct(obj *types.TypeName, T *types.Struct) { func (g *goGen) genInterface(obj *types.TypeName) { iface := obj.Type().(*types.Named).Underlying().(*types.Interface) + ifaceDesc := fmt.Sprintf("go.%s.%s", g.pkg.Name(), obj.Name()) + // Descriptor and code for interface methods. g.Printf("const (\n") g.Indent() - g.Printf("proxy%s_Descriptor = \"go.%s.%s\"\n", obj.Name(), g.pkg.Name(), obj.Name()) + g.Printf("proxy%s_Descriptor = %q\n", obj.Name(), ifaceDesc) for i := 0; i < iface.NumMethods(); i++ { g.Printf("proxy%s_%s_Code = 0x%x0a\n", obj.Name(), iface.Method(i).Name(), i+1) } @@ -308,9 +310,9 @@ func (g *goGen) genInterface(obj *types.TypeName) { } if res.Len() == 0 { - g.Printf("seq.Transact((*seq.Ref)(p), proxy%s_%s_Code, in)\n", obj.Name(), m.Name()) + g.Printf("seq.Transact((*seq.Ref)(p), %q, proxy%s_%s_Code, in)\n", ifaceDesc, obj.Name(), m.Name()) } else { - g.Printf("out := seq.Transact((*seq.Ref)(p), proxy%s_%s_Code, in)\n", obj.Name(), m.Name()) + g.Printf("out := seq.Transact((*seq.Ref)(p), %q, proxy%s_%s_Code, in)\n", ifaceDesc, obj.Name(), m.Name()) var rvs []string for i := 0; i < res.Len(); i++ { rv := fmt.Sprintf("res_%d", i) diff --git a/bind/java/seq_android.go b/bind/java/seq_android.go index 01a915f..a3c4a8c 100644 --- a/bind/java/seq_android.go +++ b/bind/java/seq_android.go @@ -133,7 +133,7 @@ func RecvRes(handle C.int32_t, out *C.uint8_t, outlen C.size_t) { // transact calls a method on a Java object instance. // It blocks until the call is complete. -func transact(ref *seq.Ref, code int, in *seq.Buffer) *seq.Buffer { +func transact(ref *seq.Ref, _ string, code int, in *seq.Buffer) *seq.Buffer { recv.Lock() if recv.next == 1<<31-1 { panic("recv handle overflow") @@ -173,7 +173,7 @@ func init() { if ref.Num < 0 { panic(fmt.Sprintf("not a Java ref: %d", ref.Num)) } - transact(ref, -1, new(seq.Buffer)) + transact(ref, "", -1, new(seq.Buffer)) } seq.Transact = transact diff --git a/bind/seq/seq.go b/bind/seq/seq.go index ca078f5..21f3093 100644 --- a/bind/seq/seq.go +++ b/bind/seq/seq.go @@ -24,7 +24,7 @@ import ( // Transact calls a method on a foreign object instance. // It blocks until the call is complete. -var Transact func(ref *Ref, code int, in *Buffer) (out *Buffer) +var Transact func(ref *Ref, desc string, code int, in *Buffer) (out *Buffer) // FinalizeRef is the finalizer used on foreign objects. var FinalizeRef func(ref *Ref) diff --git a/bind/testdata/interfaces.go.golden b/bind/testdata/interfaces.go.golden index 340de12..35bf2af 100644 --- a/bind/testdata/interfaces.go.golden +++ b/bind/testdata/interfaces.go.golden @@ -41,7 +41,7 @@ type proxyI seq.Ref func (p *proxyI) Rand() int32 { in := new(seq.Buffer) - out := seq.Transact((*seq.Ref)(p), proxyI_Rand_Code, in) + out := seq.Transact((*seq.Ref)(p), "go.interfaces.I", proxyI_Rand_Code, in) res_0 := out.ReadInt32() return res_0 } @@ -72,7 +72,7 @@ type proxyWithParam seq.Ref func (p *proxyWithParam) HasParam(p0 bool) { in := new(seq.Buffer) in.WriteBool(p0) - seq.Transact((*seq.Ref)(p), proxyWithParam_HasParam_Code, in) + seq.Transact((*seq.Ref)(p), "go.interfaces.WithParam", proxyWithParam_HasParam_Code, in) } func init() { diff --git a/bind/testdata/issue10788.go.golden b/bind/testdata/issue10788.go.golden index 9b96e23..ee9d8ce 100644 --- a/bind/testdata/issue10788.go.golden +++ b/bind/testdata/issue10788.go.golden @@ -43,7 +43,7 @@ type proxyTestInterface seq.Ref func (p *proxyTestInterface) DoSomeWork(s *issue10788.TestStruct) { in := new(seq.Buffer) in.WriteGoRef(s) - seq.Transact((*seq.Ref)(p), proxyTestInterface_DoSomeWork_Code, in) + seq.Transact((*seq.Ref)(p), "go.issue10788.TestInterface", proxyTestInterface_DoSomeWork_Code, in) } func (p *proxyTestInterface) MultipleUnnamedParams(p0 int, p1 string, p2 int64) { @@ -51,7 +51,7 @@ func (p *proxyTestInterface) MultipleUnnamedParams(p0 int, p1 string, p2 int64) in.WriteInt(p0) in.WriteString(p1) in.WriteInt64(p2) - seq.Transact((*seq.Ref)(p), proxyTestInterface_MultipleUnnamedParams_Code, in) + seq.Transact((*seq.Ref)(p), "go.issue10788.TestInterface", proxyTestInterface_MultipleUnnamedParams_Code, in) } const (