Complete working GC mode.
This commit is contained in:
parent
c8209dd260
commit
4aa1211d73
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -151,7 +151,7 @@ func memtest5() {
|
||||||
time.Sleep(time.Second/50)
|
time.Sleep(time.Second/50)
|
||||||
runtime.GC()
|
runtime.GC()
|
||||||
i++
|
i++
|
||||||
fmt.Printf("loop completed\n")
|
//fmt.Printf("loop completed\n")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -314,9 +314,7 @@ type %s interface {
|
||||||
type %s struct { %s }
|
type %s struct { %s }
|
||||||
func (o *%s) Ptr() unsafe.Pointer { if o == nil { return nil }; return o.ptr }
|
func (o *%s) Ptr() unsafe.Pointer { if o == nil { return nil }; return o.ptr }
|
||||||
func (o *Id) %s() *%s {
|
func (o *Id) %s() *%s {
|
||||||
ret := &%s{}
|
return (*%s)(unsafe.Pointer(o))
|
||||||
ret.ptr = o.ptr
|
|
||||||
return ret
|
|
||||||
}
|
}
|
||||||
`, gt, super, gt, gt, gt, gt)
|
`, gt, super, gt, gt, gt, gt)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func dbg(f string, xs ...interface{}) {
|
func dbg(f string, xs ...interface{}) {
|
||||||
if Debug {
|
if Debug && false {
|
||||||
fmt.Printf(f, xs...)
|
fmt.Printf(f, xs...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
81
wrap/main.go
81
wrap/main.go
|
@ -153,25 +153,25 @@ type Method struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Method) ShouldFinalize() bool {
|
func (m *Method) ShouldFinalize() bool {
|
||||||
return shouldFinalize(m.Type.GoType(), m.Name)
|
grtype := m.Type.GoType()
|
||||||
|
return Gogc && grtype != "NSAutoreleasePool" &&
|
||||||
|
(types.PtrShouldWrap(grtype) || grtype == "*Id") &&
|
||||||
|
(!m.ClassMethod || IsRetained(m.Name))
|
||||||
}
|
}
|
||||||
|
|
||||||
func shouldFinalize (grtype, name string) bool {
|
// IsRetained returns true if a given instance method returns a retained object.
|
||||||
return Gogc && grtype != "*NSAutoreleasePool" &&
|
func IsRetained(name string) bool {
|
||||||
(types.PtrShouldWrap(grtype) || grtype == "*Id") &&
|
return (
|
||||||
(len(name) < 6 || name != "retain")
|
(len(name) >= 3 && name[:3] == "new") ||
|
||||||
|
(len(name) >= 4 && name[:4] == "init") ||
|
||||||
|
(len(name) >= 4 && name[:4] == "copy") ||
|
||||||
|
(len(name) >= 5 && name[:5] == "alloc") ||
|
||||||
|
(len(name) >= 11 && name[:11] == "mutableCopy"))
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsRetained returns true if the name matches a retained property for the
|
// IsRetainedProperty returns true if the name matches a retained property for
|
||||||
// given interface.
|
// the given interface.
|
||||||
func (i *Interface) IsRetained(name string) bool {
|
func (i *Interface) IsRetainedProperty(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
|
||||||
|
@ -976,6 +976,7 @@ func (w *Wrapper) _processMethod(m *Method, fun bool) {
|
||||||
gname = strings.Title(gname)
|
gname = strings.Title(gname)
|
||||||
gname = strings.ReplaceAll(gname, " ", "")
|
gname = strings.ReplaceAll(gname, " ", "")
|
||||||
receiver := ""
|
receiver := ""
|
||||||
|
constructor := false // this is an autoreleased object constructor
|
||||||
var cname string
|
var cname string
|
||||||
if fun {
|
if fun {
|
||||||
cname = m.Name
|
cname = m.Name
|
||||||
|
@ -985,6 +986,16 @@ func (w *Wrapper) _processMethod(m *Method, fun bool) {
|
||||||
if Debug {
|
if Debug {
|
||||||
fmt.Printf("Method %s (GoClass %s)\n", cname, m.GoClass)
|
fmt.Printf("Method %s (GoClass %s)\n", cname, m.GoClass)
|
||||||
}
|
}
|
||||||
|
grtype := m.Type.GoType()
|
||||||
|
if grtype == "Void" {
|
||||||
|
grtype = ""
|
||||||
|
}
|
||||||
|
if types.PtrIsGoInterface(grtype) {
|
||||||
|
grtype = "*Id"
|
||||||
|
}
|
||||||
|
if grtype == "BOOL" { // convert objective-c bools to Go bools
|
||||||
|
grtype = "bool"
|
||||||
|
}
|
||||||
switch {
|
switch {
|
||||||
case !m.ClassMethod:
|
case !m.ClassMethod:
|
||||||
if types.IsGoInterface(m.GoClass) {
|
if types.IsGoInterface(m.GoClass) {
|
||||||
|
@ -994,15 +1005,19 @@ func (w *Wrapper) _processMethod(m *Method, fun bool) {
|
||||||
}
|
}
|
||||||
//Disambiguate instance methods with same name as a class method
|
//Disambiguate instance methods with same name as a class method
|
||||||
cname = "inst_" + cname
|
cname = "inst_" + cname
|
||||||
default:
|
case m.ClassMethod:
|
||||||
//Shorten class method names
|
//Shorten class method names
|
||||||
lens1 := len(m.Class)
|
lens1 := len(m.Class)
|
||||||
i := 0
|
i := 0
|
||||||
if len(gname) < len(m.Class) {
|
if len(gname) < lens1 {
|
||||||
i = lens1 - len(gname)
|
i = lens1 - len(gname)
|
||||||
}
|
}
|
||||||
for ; i < lens1; i++ {
|
for ; i < lens1; i++ {
|
||||||
if m.Class[i:] == gname[:lens1-i] {
|
if m.Class[i:] == gname[:lens1-i] {
|
||||||
|
if Gogc &&
|
||||||
|
(types.PtrShouldWrap(grtype) || grtype == "*Id") {
|
||||||
|
constructor = true
|
||||||
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1029,16 +1044,6 @@ func (w *Wrapper) _processMethod(m *Method, fun bool) {
|
||||||
cmtype = m.Type.CTypeAttrib()
|
cmtype = m.Type.CTypeAttrib()
|
||||||
}
|
}
|
||||||
ns, snames, tps, gplist := w.gpntp(m)
|
ns, snames, tps, gplist := w.gpntp(m)
|
||||||
grtype := m.Type.GoType()
|
|
||||||
if grtype == "Void" {
|
|
||||||
grtype = ""
|
|
||||||
}
|
|
||||||
if types.PtrIsGoInterface(grtype) {
|
|
||||||
grtype = "*Id"
|
|
||||||
}
|
|
||||||
if grtype == "BOOL" { // convert objective-c bools to Go bools
|
|
||||||
grtype = "bool"
|
|
||||||
}
|
|
||||||
if gname == grtype { // avoid name conflicts between methods and types
|
if gname == grtype { // avoid name conflicts between methods and types
|
||||||
gname = "Get" + gname
|
gname = "Get" + gname
|
||||||
}
|
}
|
||||||
|
@ -1088,7 +1093,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(m.Name, cname, ns, snames, m.Type, tps, fun, m.ShouldFinalize(), m.ClassMethod) + "\n}\n")
|
types.GoToC(m.Name, cname, ns, snames, m.Type, tps, fun, constructor || m.ShouldFinalize(), m.ClassMethod) + "\n}\n")
|
||||||
|
|
||||||
cret := ""
|
cret := ""
|
||||||
if !m.isVoid() {
|
if !m.isVoid() {
|
||||||
|
@ -1131,15 +1136,14 @@ func %s%s(%s) %s {
|
||||||
if types.PtrShouldWrap(m.Type.GoType()) {
|
if types.PtrShouldWrap(m.Type.GoType()) {
|
||||||
switch {
|
switch {
|
||||||
case m.ClassMethod:
|
case m.ClassMethod:
|
||||||
if grtype != "*NSAutoreleasePool" {
|
if grtype != "*NSAutoreleasePool" && constructor {
|
||||||
// retain objects returned by class methods
|
// retain objects returned by class constructor methods
|
||||||
rtn = `
|
rtn = `
|
||||||
[ret retain];`
|
[ret retain];`
|
||||||
}
|
}
|
||||||
|
|
||||||
// some methods always return retained objects,
|
// do not retain new, alloc, init and copy methods
|
||||||
// including "getters" for retained properties.
|
case IsRetained(m.Name):
|
||||||
case inter.IsRetained(m.Name):
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// by default, for instance methods, retain
|
// by default, for instance methods, retain
|
||||||
|
@ -1148,13 +1152,16 @@ func %s%s(%s) %s {
|
||||||
if (o != ret) { [ret retain]; }`
|
if (o != ret) { [ret retain]; }`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var ar1, ar2 string
|
||||||
|
if constructor || true {
|
||||||
|
ar1 = "@autoreleasepool {\n\t\t"
|
||||||
|
ar2 = "\n }"
|
||||||
|
}
|
||||||
w.cCode.WriteString(fmt.Sprintf(
|
w.cCode.WriteString(fmt.Sprintf(
|
||||||
` %s ret;
|
` %s ret;
|
||||||
@autoreleasepool {
|
%sret = [%s %s];%s%s
|
||||||
ret = [%s %s];%s
|
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
}`, m.Type.CTypeAttrib(), cobj, w.objcparamlist(m),rtn))
|
}`, m.Type.CTypeAttrib(), ar1, cobj, w.objcparamlist(m), rtn, ar2))
|
||||||
} else {
|
} else {
|
||||||
w.cCode.WriteString(fmt.Sprintf(` %s[%s %s];
|
w.cCode.WriteString(fmt.Sprintf(` %s[%s %s];
|
||||||
}`, cret, cobj, w.objcparamlist(m)))
|
}`, cret, cobj, w.objcparamlist(m)))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user