Interim commit.

This commit is contained in:
Greg 2019-06-18 17:29:52 -04:00
parent e5c8e114bf
commit c8209dd260
4 changed files with 43 additions and 24 deletions

View File

@ -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 // and if so release the old one. Be careful to check the Objective-C pointers
// here as the Go pointers will differ. // here as the Go pointers will differ.
if peripheral != nil && p.Ptr() != peripheral.Ptr() { // if peripheral != nil && p.Ptr() != peripheral.Ptr() {
peripheral.Release() // peripheral.Release()
} // }
peripheral = p peripheral = p

View File

@ -140,12 +140,18 @@ func memtest5() {
// finalizer. // finalizer.
sub := str.SubstringFromIndex(5) sub := str.SubstringFromIndex(5)
_ = sub sub2 := sub.Copy().NSString()
sub3 := sub2.MutableCopy().NSString()
u := sub.UTF8String() u := sub.UTF8String()
u2 := sub2.UTF8String()
u3 := sub3.UTF8String()
_ = u _ = u
_ = u2
_ = u3
time.Sleep(time.Second/50) time.Sleep(time.Second/50)
runtime.GC() runtime.GC()
i++ i++
fmt.Printf("loop completed\n")
} }
} }

View File

@ -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 // 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 { if rtype == nil {
//fmt.Println("nil sent to GoToC") //fmt.Println("nil sent to GoToC")
return "" 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)) }`, 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 rt != "void" {
if fin { cmp := ""
cmp := "" if sw {
if !cm { if !cm && sname != "copy" && sname != "mutableCopy" {
cmp = fmt.Sprintf(`if ret.ptr == o.ptr { return (%s)(unsafe.Pointer(o)) } cmp = fmt.Sprintf(`
`,rtgt) 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 := "" dbg := ""
dbg2 := "" dbg2 := ""
if Debug { if Debug {
@ -509,10 +513,9 @@ func GoToC(name string, pnames, snames []string, rtype *Type, ptypes []*Type, fu
`, rtgt) `, rtgt)
} }
ret.WriteString(fmt.Sprintf(` ret.WriteString(fmt.Sprintf(`
if ret.ptr == nil { return ret } %sruntime.SetFinalizer(ret, func(o %s) {
%s%sruntime.SetFinalizer(ret, func(o %s) {
%so.Release() %so.Release()
})`, cmp, dbg, rtgt, dbg2)) })`, dbg, rtgt, dbg2))
} }
ret.WriteString(` ret.WriteString(`
return ret`) return ret`)

View File

@ -158,13 +158,20 @@ func (m *Method) ShouldFinalize() bool {
func shouldFinalize (grtype, name string) bool { func shouldFinalize (grtype, name string) bool {
return Gogc && grtype != "*NSAutoreleasePool" && return Gogc && grtype != "*NSAutoreleasePool" &&
(types.PtrShouldWrap(grtype) || grtype == "*Id") && (types.PtrShouldWrap(grtype) || grtype == "*Id") &&
(len(name) < 6 || name != "retain") (len(name) < 6 || name != "retain")
} }
// IsRetained returns true if the name matches a retained property for the // IsRetained returns true if the name matches a retained property for the
// given interface. // given interface.
func (i *Interface) IsRetained(name string) bool { 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, ok := i.Properties[name]; ok {
if p.retained { if p.retained {
return true return true
@ -1081,7 +1088,7 @@ func %s%s(%s) %s {
`, snames[i], n, n, snames[i], n)) `, snames[i], n, n, snames[i], n))
} }
w.goCode.WriteString(` ` + 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 := "" cret := ""
if !m.isVoid() { if !m.isVoid() {
@ -1130,15 +1137,13 @@ func %s%s(%s) %s {
[ret retain];` [ret retain];`
} }
case len(m.Name) >= 4 && m.Name[:4] == "init": // some methods always return retained objects,
// init always returns a retained object // including "getters" for retained properties.
case inter.IsRetained(m.Name): case inter.IsRetained(m.Name):
// some methods relate to retained properties
// do not retain these again
default: default:
// by default, retain if returning a new object // by default, for instance methods, retain
// if returning a new object
rtn = ` rtn = `
if (o != ret) { [ret retain]; }` if (o != ret) { [ret retain]; }`
} }
@ -1167,7 +1172,8 @@ func %s%s(%s) %s {
if Debug { if Debug {
dbg = fmt.Sprintf(`fmt.Printf("Setting GC finalizer (%s): %%p -> %%p\n", o, o.ptr) dbg = fmt.Sprintf(`fmt.Printf("Setting GC finalizer (%s): %%p -> %%p\n", o, o.ptr)
`,cls) `,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(` w.goCode.WriteString(fmt.Sprintf(`
func (o *%s) GC() { func (o *%s) GC() {
@ -1718,7 +1724,7 @@ void*
dbg = fmt.Sprintf(`fmt.Printf("Setting finalizer (%s): %%p -> %%p\n", ret, ret.ptr) dbg = fmt.Sprintf(`fmt.Printf("Setting finalizer (%s): %%p -> %%p\n", ret, ret.ptr)
`, gname) `, gname)
dbg2 = fmt.Sprintf(`fmt.Printf("Finalizer (%s): release %%p -> %%p\n", o, o.ptr) dbg2 = fmt.Sprintf(`fmt.Printf("Finalizer (%s): release %%p -> %%p\n", o, o.ptr)
`, gname) `, gname)
} }
if Gogc { if Gogc {
w.goImports["runtime"] = true w.goImports["runtime"] = true
@ -1738,6 +1744,10 @@ func %sAlloc() *%s {
} }
`, gname, gname, gname, dname, finalizer)) `, gname, gname, gname, dname, finalizer))
if Gogc { if Gogc {
if Debug {
dbg = fmt.Sprintf(`fmt.Printf("Setting finalizer (%s): %%p -> %%p\n", o, o.ptr)
`, gname)
}
gocode.WriteString(fmt.Sprintf(` gocode.WriteString(fmt.Sprintf(`
func (o *%s) GC() { func (o *%s) GC() {
if o.ptr == nil { return } if o.ptr == nil { return }
@ -1912,7 +1922,7 @@ func (o *%s) Super%s(%s) %s {
} }
`, vn, w.Vaargs, vn, vn)) `, 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()) w.cCode.WriteString(cprotos.String())