From 3e830506b0f1c3f75454a998a49e8e39fdbc8964 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Mon, 14 Mar 2016 17:28:24 +0100 Subject: [PATCH] mobile/bind: stop tracking foreign objects in the Go reference tracker ToRefNum only handles Go objects, but it can be passed foreign object proxies as well. Add a check whether the object is a proxy, and if so, simply return its refnum and don't track it. Change-Id: Ib17bd11b48e472c3bec0e5fb06661b201c3dfa97 Reviewed-on: https://go-review.googlesource.com/20681 Reviewed-by: Hyang-Ah Hana Kim --- bind/gengo.go | 2 ++ bind/java/SeqTest.java | 5 +++++ bind/objc/SeqTest.m | 6 ++++++ bind/seq/ref.go | 18 ++++++++++++++++-- bind/testdata/interfaces.go.golden | 8 ++++++++ bind/testdata/issue10788.go.golden | 2 ++ bind/testdata/issue12403.go.golden | 2 ++ bind/testdata/structs.go.golden | 2 ++ bind/testdata/vars.go.golden | 2 ++ bind/testpkg/testpkg.go | 4 ++++ 10 files changed, 49 insertions(+), 2 deletions(-) diff --git a/bind/gengo.go b/bind/gengo.go index 5544350..f1317bc 100644 --- a/bind/gengo.go +++ b/bind/gengo.go @@ -275,6 +275,8 @@ func (g *goGen) genInterface(obj *types.TypeName) { } g.Printf("type proxy%s_%s _seq.Ref\n\n", g.pkgPrefix, obj.Name()) + g.Printf("func (p *proxy%s_%s) Bind_proxy_refnum__() int32 { return p.Num }\n\n", g.pkgPrefix, obj.Name()) + for _, m := range summary.callable { sig := m.Type().(*types.Signature) params := sig.Params() diff --git a/bind/java/SeqTest.java b/bind/java/SeqTest.java index 824b2ab..fa36f7d 100644 --- a/bind/java/SeqTest.java +++ b/bind/java/SeqTest.java @@ -497,4 +497,9 @@ public class SeqTest extends InstrumentationTestCase { Testpkg.WithImportedI(i); Testpkg.WithImportedS(s); } + + public void testIDup() { + Testpkg.I want = new AnI(); + assertTrue("java object passed through Go should not be wrapped", want == Testpkg.IDup(want)); + } } diff --git a/bind/objc/SeqTest.m b/bind/objc/SeqTest.m index 89b2d4f..7b196f5 100644 --- a/bind/objc/SeqTest.m +++ b/bind/objc/SeqTest.m @@ -367,4 +367,10 @@ static int numI = 0; [fields setS:s]; } +- (void)testIDup { + Number *want = [[Number alloc] init]; + Number *got = GoTestpkgIDup(want); + XCTAssertEqual(got, want, @"ObjC object passed through Go should not be wrapped"); +} + @end diff --git a/bind/seq/ref.go b/bind/seq/ref.go index 39519e9..a21d7e7 100644 --- a/bind/seq/ref.go +++ b/bind/seq/ref.go @@ -45,9 +45,23 @@ type Ref struct { Num int32 } -// ToRefNum increments the reference count for a Go object and -// return its refnum. +type proxy interface { + // Use a strange name and hope that user code does not implement it + Bind_proxy_refnum__() int32 +} + +// ToRefNum increments the reference count for an object and +// returns its refnum. func ToRefNum(obj interface{}) int32 { + // We don't track foreign objects, so if obj is a proxy + // return its refnum. + if r, ok := obj.(proxy); ok { + refnum := r.Bind_proxy_refnum__() + if refnum <= 0 { + panic(fmt.Errorf("seq: proxy contained invalid Go refnum: %d", refnum)) + } + return refnum + } refs.Lock() num := refs.refs[obj] if num != 0 { diff --git a/bind/testdata/interfaces.go.golden b/bind/testdata/interfaces.go.golden index 4c53958..6d28e8e 100644 --- a/bind/testdata/interfaces.go.golden +++ b/bind/testdata/interfaces.go.golden @@ -38,6 +38,8 @@ func proxyinterfaces_Error_Err(refnum C.int32_t) C.nstring { type proxyinterfaces_Error _seq.Ref +func (p *proxyinterfaces_Error) Bind_proxy_refnum__() int32 { return p.Num } + func (p *proxyinterfaces_Error) Err() error { res := C.cproxyinterfaces_Error_Err(C.int32_t(p.Num)) _res_str := decodeString(res) @@ -56,6 +58,8 @@ func proxyinterfaces_I_Rand(refnum C.int32_t) C.int32_t { type proxyinterfaces_I _seq.Ref +func (p *proxyinterfaces_I) Bind_proxy_refnum__() int32 { return p.Num } + func (p *proxyinterfaces_I) Rand() int32 { res := C.cproxyinterfaces_I_Rand(C.int32_t(p.Num)) _res := int32(res) @@ -90,6 +94,8 @@ func proxyinterfaces_I3_F(refnum C.int32_t) C.int32_t { type proxyinterfaces_I3 _seq.Ref +func (p *proxyinterfaces_I3) Bind_proxy_refnum__() int32 { return p.Num } + func (p *proxyinterfaces_I3) F() interfaces.I1 { res := C.cproxyinterfaces_I3_F(C.int32_t(p.Num)) var _res interfaces.I1 @@ -112,6 +118,8 @@ func proxyinterfaces_WithParam_HasParam(refnum C.int32_t, param_p0 C.char) { type proxyinterfaces_WithParam _seq.Ref +func (p *proxyinterfaces_WithParam) Bind_proxy_refnum__() int32 { return p.Num } + func (p *proxyinterfaces_WithParam) HasParam(param_p0 bool) { var _param_p0 C.char = 0 if param_p0 { diff --git a/bind/testdata/issue10788.go.golden b/bind/testdata/issue10788.go.golden index 19c86dd..92cbf12 100644 --- a/bind/testdata/issue10788.go.golden +++ b/bind/testdata/issue10788.go.golden @@ -58,6 +58,8 @@ func proxyissue10788_TestInterface_MultipleUnnamedParams(refnum C.int32_t, param type proxyissue10788_TestInterface _seq.Ref +func (p *proxyissue10788_TestInterface) Bind_proxy_refnum__() int32 { return p.Num } + func (p *proxyissue10788_TestInterface) DoSomeWork(param_s *issue10788.TestStruct) { var _param_s C.int32_t = _seq.NullRefNum if param_s != nil { diff --git a/bind/testdata/issue12403.go.golden b/bind/testdata/issue12403.go.golden index d0d3c6e..fb11817 100644 --- a/bind/testdata/issue12403.go.golden +++ b/bind/testdata/issue12403.go.golden @@ -49,6 +49,8 @@ func proxyissue12403_Parsable_ToJSON(refnum C.int32_t) (C.nstring, C.nstring) { type proxyissue12403_Parsable _seq.Ref +func (p *proxyissue12403_Parsable) Bind_proxy_refnum__() int32 { return p.Num } + func (p *proxyissue12403_Parsable) FromJSON(param_jstr string) string { _param_jstr := encodeString(param_jstr) res := C.cproxyissue12403_Parsable_FromJSON(C.int32_t(p.Num), _param_jstr) diff --git a/bind/testdata/structs.go.golden b/bind/testdata/structs.go.golden index 82c96e5..cf30a8c 100644 --- a/bind/testdata/structs.go.golden +++ b/bind/testdata/structs.go.golden @@ -104,6 +104,8 @@ func proxystructs_I_M(refnum C.int32_t) { type proxystructs_I _seq.Ref +func (p *proxystructs_I) Bind_proxy_refnum__() int32 { return p.Num } + func (p *proxystructs_I) M() { C.cproxystructs_I_M(C.int32_t(p.Num)) } diff --git a/bind/testdata/vars.go.golden b/bind/testdata/vars.go.golden index f830109..b5d9457 100644 --- a/bind/testdata/vars.go.golden +++ b/bind/testdata/vars.go.golden @@ -23,6 +23,8 @@ var _ = _seq.FromRefNum type proxyvars_I _seq.Ref +func (p *proxyvars_I) Bind_proxy_refnum__() int32 { return p.Num } + //export var_setvars_ABool func var_setvars_ABool(v C.char) { _v := v != 0 diff --git a/bind/testpkg/testpkg.go b/bind/testpkg/testpkg.go index 17f09cf..2be9a14 100644 --- a/bind/testpkg/testpkg.go +++ b/bind/testpkg/testpkg.go @@ -138,6 +138,10 @@ func NumSCollected() int { return numSCollected } +func IDup(i I) I { + return i +} + func StrDup(s string) string { return s }