From c8209dd260f395c8240296cd588e77cce7e3f639 Mon Sep 17 00:00:00 2001 From: Greg Date: Tue, 18 Jun 2019 17:29:52 -0400 Subject: [PATCH] Interim commit. --- examples/bluetooth/main.go | 6 +++--- examples/gc/main.go | 8 +++++++- types/convert.go | 21 ++++++++++++--------- wrap/main.go | 32 +++++++++++++++++++++----------- 4 files changed, 43 insertions(+), 24 deletions(-) diff --git a/examples/bluetooth/main.go b/examples/bluetooth/main.go index 373d3db..2f7ea51 100644 --- a/examples/bluetooth/main.go +++ b/examples/bluetooth/main.go @@ -38,9 +38,9 @@ func discoverPeripheral(c *ns.CBCentralManager, p *ns.CBPeripheral, d *ns.NSDict // and if so release the old one. Be careful to check the Objective-C pointers // here as the Go pointers will differ. - if peripheral != nil && p.Ptr() != peripheral.Ptr() { - peripheral.Release() - } +// if peripheral != nil && p.Ptr() != peripheral.Ptr() { +// peripheral.Release() +// } peripheral = p diff --git a/examples/gc/main.go b/examples/gc/main.go index 3754e14..4f60d89 100644 --- a/examples/gc/main.go +++ b/examples/gc/main.go @@ -140,12 +140,18 @@ func memtest5() { // finalizer. sub := str.SubstringFromIndex(5) - _ = sub + sub2 := sub.Copy().NSString() + sub3 := sub2.MutableCopy().NSString() u := sub.UTF8String() + u2 := sub2.UTF8String() + u3 := sub3.UTF8String() _ = u + _ = u2 + _ = u3 time.Sleep(time.Second/50) runtime.GC() i++ + fmt.Printf("loop completed\n") } } diff --git a/types/convert.go b/types/convert.go index df10cb9..384afd8 100644 --- a/types/convert.go +++ b/types/convert.go @@ -384,7 +384,7 @@ func (t *Type) CToGo(cval string) string { } // Call a C function from Go with a given return type and parameter types -func GoToC(name string, pnames, snames []string, rtype *Type, ptypes []*Type, fun, fin bool, cm bool) string { +func GoToC(sname, name string, pnames, snames []string, rtype *Type, ptypes []*Type, fun, fin bool, cm bool) string { if rtype == nil { //fmt.Println("nil sent to GoToC") return "" @@ -494,12 +494,16 @@ func GoToC(name string, pnames, snames []string, rtype *Type, ptypes []*Type, fu }`, pnames[i], pnames[i], pnames[i], pnames[i], sname, pnames[i], pnames[i], pnames[i], pnames[i], ptgt, pnames[i], sname)) } if rt != "void" { - if fin { - cmp := "" - if !cm { - cmp = fmt.Sprintf(`if ret.ptr == o.ptr { return (%s)(unsafe.Pointer(o)) } - `,rtgt) + cmp := "" + if sw { + if !cm && sname != "copy" && sname != "mutableCopy" { + cmp = fmt.Sprintf(` + if ret.ptr == o.ptr { return (%s)(unsafe.Pointer(o)) }`,rtgt) } + ret.WriteString(fmt.Sprintf(` + if ret.ptr == nil { return ret }%s`,cmp)) + } + if fin { dbg := "" dbg2 := "" if Debug { @@ -509,10 +513,9 @@ func GoToC(name string, pnames, snames []string, rtype *Type, ptypes []*Type, fu `, rtgt) } ret.WriteString(fmt.Sprintf(` - if ret.ptr == nil { return ret } - %s%sruntime.SetFinalizer(ret, func(o %s) { + %sruntime.SetFinalizer(ret, func(o %s) { %so.Release() - })`, cmp, dbg, rtgt, dbg2)) + })`, dbg, rtgt, dbg2)) } ret.WriteString(` return ret`) diff --git a/wrap/main.go b/wrap/main.go index 975148a..b24c99b 100644 --- a/wrap/main.go +++ b/wrap/main.go @@ -158,13 +158,20 @@ func (m *Method) ShouldFinalize() bool { func shouldFinalize (grtype, name string) bool { return Gogc && grtype != "*NSAutoreleasePool" && - (types.PtrShouldWrap(grtype) || grtype == "*Id") && + (types.PtrShouldWrap(grtype) || grtype == "*Id") && (len(name) < 6 || name != "retain") } // IsRetained returns true if the name matches a retained property for the // given interface. func (i *Interface) IsRetained(name string) bool { + // init, copy and MutableCopy always return a retained object + if len(name) >= 4 && (name[:4] == "init" || + name[:4] == "copy") || + len(name) >= 11 && name[:11] == "mutableCopy" { + return true + } + if p, ok := i.Properties[name]; ok { if p.retained { return true @@ -1081,7 +1088,7 @@ func %s%s(%s) %s { `, snames[i], n, n, snames[i], n)) } w.goCode.WriteString(` ` + - types.GoToC(cname, ns, snames, m.Type, tps, fun, m.ShouldFinalize() && (m.ClassMethod || !inter.IsRetained(m.Name)), m.ClassMethod) + "\n}\n") + types.GoToC(m.Name, cname, ns, snames, m.Type, tps, fun, m.ShouldFinalize(), m.ClassMethod) + "\n}\n") cret := "" if !m.isVoid() { @@ -1130,15 +1137,13 @@ func %s%s(%s) %s { [ret retain];` } - case len(m.Name) >= 4 && m.Name[:4] == "init": - // init always returns a retained object - + // some methods always return retained objects, + // including "getters" for retained properties. case inter.IsRetained(m.Name): - // some methods relate to retained properties - // do not retain these again default: - // by default, retain if returning a new object + // by default, for instance methods, retain + // if returning a new object rtn = ` if (o != ret) { [ret retain]; }` } @@ -1167,7 +1172,8 @@ func %s%s(%s) %s { if Debug { dbg = fmt.Sprintf(`fmt.Printf("Setting GC finalizer (%s): %%p -> %%p\n", o, o.ptr) `,cls) - dbg2 = fmt.Sprintf(`fmt.Printf("GC finalizer (%s): release %%p -> %%p\n", o, o.ptr)`, cls) + dbg2 = fmt.Sprintf(`fmt.Printf("GC finalizer (%s): release %%p -> %%p\n", o, o.ptr) + `, cls) } w.goCode.WriteString(fmt.Sprintf(` func (o *%s) GC() { @@ -1718,7 +1724,7 @@ void* dbg = fmt.Sprintf(`fmt.Printf("Setting finalizer (%s): %%p -> %%p\n", ret, ret.ptr) `, gname) dbg2 = fmt.Sprintf(`fmt.Printf("Finalizer (%s): release %%p -> %%p\n", o, o.ptr) - `, gname) + `, gname) } if Gogc { w.goImports["runtime"] = true @@ -1738,6 +1744,10 @@ func %sAlloc() *%s { } `, gname, gname, gname, dname, finalizer)) if Gogc { + if Debug { + dbg = fmt.Sprintf(`fmt.Printf("Setting finalizer (%s): %%p -> %%p\n", o, o.ptr) + `, gname) + } gocode.WriteString(fmt.Sprintf(` func (o *%s) GC() { if o.ptr == nil { return } @@ -1912,7 +1922,7 @@ func (o *%s) Super%s(%s) %s { } `, vn, w.Vaargs, vn, vn)) } - gocode.WriteString("\t" + types.GoToC(dname+"_super_"+m.Name, ns, snames, m.Type, tps, false, m.ShouldFinalize(), m.ClassMethod) + "\n}\n") + gocode.WriteString("\t" + types.GoToC(m.Name, dname+"_super_"+m.Name, ns, snames, m.Type, tps, false, m.ShouldFinalize(), m.ClassMethod) + "\n}\n") } } w.cCode.WriteString(cprotos.String())