Skip to content

Commit

Permalink
Implement intern struct, closes #26
Browse files Browse the repository at this point in the history
  • Loading branch information
diamondburned committed Aug 14, 2021
1 parent 5e69594 commit aa7ccd9
Show file tree
Hide file tree
Showing 224 changed files with 4,585 additions and 2,044 deletions.
11 changes: 8 additions & 3 deletions gir/girgen/generators/record.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,22 @@ var recordIgnoreSuffixes = []string{
}

var recordTmpl = gotmpl.NewGoTemplate(`
{{ $impl := UnexportPascal .GoName }}
{{ GoDoc . 0 }}
type {{ .GoName }} struct {
nocopy gextras.NoCopy
*{{ $impl }}
}
// {{ $impl }} is the struct that's finalized.
type {{ $impl }} struct {
native *C.{{.CType}}
}
{{ if .GLibGetType }}
func marshal{{ .GoName }}(p uintptr) (interface{}, error) {
b := C.g_value_get_boxed((*C.GValue)(unsafe.Pointer(p)))
return &{{ .GoName }}{native: (*C.{{.CType}})(unsafe.Pointer(b))}, nil
return &{{ .GoName }}{&{{ $impl }}{(*C.{{.CType}})(unsafe.Pointer(b))}}, nil
}
{{ end }}
Expand Down Expand Up @@ -142,7 +148,6 @@ func GenerateRecord(gen FileGeneratorWriter, record *gir.Record) bool {
}

writer := FileWriterFromType(gen, record)
writer.Header().ImportCore("gextras")

if record.GLibGetType != "" && !types.FilterCType(gen, record.GLibGetType) {
writer.Header().AddMarshaler(record.GLibGetType, recordGen.GoName)
Expand Down
23 changes: 15 additions & 8 deletions gir/girgen/types/typeconv/c-go.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ func (conv *Converter) cgoArrayConverter(value *ValueConverted) bool {
value.p.Linef("p := C.g_array_steal(&%s, (*C.gsize)(&len))", value.InName)
value.p.Linef("src := unsafe.Slice((*%s)(p), len)", inner.In.Type)
value.p.Linef("%s = make(%s, len)", value.Out.Set, value.Out.Type)
value.p.Linef("for i := 0; i < len; i++ {", value.InName)
value.p.Linef("for i := 0; i < len; i++ {")
value.p.Linef(inner.Conversion)
value.p.Linef("}")

Expand Down Expand Up @@ -301,6 +301,7 @@ func (conv *Converter) cgoConvertNested(value *ValueConverted) bool {
return false
}

/*
// cFree calls the free function of the given value on the given string
// variable. v should be of type unsafe.Pointer. If value is nil, then a generic
// C.free is returned.
Expand Down Expand Up @@ -355,6 +356,7 @@ func (conv *Converter) cFree(value *ValueConverted, v string) string {
return fmt.Sprintf("C.free(%s)", v)
}
*/

func (conv *Converter) cgoConverter(value *ValueConverted) bool {
// TODO: make the freeing use cFree().
Expand Down Expand Up @@ -552,8 +554,9 @@ func (conv *Converter) cgoConverter(value *ValueConverted) bool {
value.header.ImportCore("gextras")

// Require 1 pointer to avoid weird copies.
value.vtmpl(
"<.Out.Set> = <.OutCast 1>(gextras.NewStructNative(unsafe.Pointer(<.InNamePtr 1>)))")
value.vtmpl(`
<.Out.Set> = <.OutCast 1>(gextras.NewStructNative(unsafe.Pointer(<.InNamePtr 1>)))
`)
if value.fail {
value.Logln(logger.Debug, "record set fail")
return false
Expand All @@ -577,22 +580,26 @@ func (conv *Converter) cgoConverter(value *ValueConverted) bool {
// We can take ownership if the type can be reference-counted anyway.
if value.ShouldFree() || unref {
value.header.Import("runtime")
value.vtmpl(
"runtime.SetFinalizer(<.OutInPtr 1><.OutName>, func(v <.OutPtr 1><.Out.Type>) {")
value.vtmpl(`
runtime.SetFinalizer(
gextras.StructIntern(unsafe.Pointer(<.OutInPtr 1><.OutName>)),
func(intern *struct{ C unsafe.Pointer }) {
`)
if value.fail {
value.Logln(logger.Debug, "SetFinalizer set fail")
}

if free != nil {
value.p.Linef(
"C.%s((%s)(gextras.StructNative(unsafe.Pointer(v))))",
"C.%s((%s)(intern.C))",
free.CIdentifier, types.AnyTypeCGo(free.Parameters.InstanceParameter.AnyType),
)
} else {
value.p.Linef("C.free(gextras.StructNative(unsafe.Pointer(v)))")
value.p.Linef("C.free(intern.C)")
}

value.p.Linef("})")
value.p.Linef("},")
value.p.Linef(")")
}

return true
Expand Down
4 changes: 3 additions & 1 deletion gir/girgen/types/typeconv/go-c.go
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,9 @@ func (conv *Converter) gocConverter(value *ValueConverted) bool {
// then we detach the finalizer so Go can't.
if !value.ShouldFree() && types.RecordHasRef(v) == nil {
value.header.Import("runtime")
value.p.Linef("runtime.SetFinalizer(%s, nil)", value.InName)
value.vtmpl(
"runtime.SetFinalizer(gextras.StructIntern(unsafe.Pointer(<.InNamePtr 1>)), nil)",
)
}
return true

Expand Down
9 changes: 6 additions & 3 deletions pkg/atk/atkcomponent.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 10 additions & 3 deletions pkg/atk/atkobject.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 18 additions & 8 deletions pkg/atk/atkrange.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 6 additions & 3 deletions pkg/atk/atkstreamablecontent.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 17 additions & 6 deletions pkg/atk/atktext.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 11 additions & 4 deletions pkg/atk/atkutil.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 6 additions & 3 deletions pkg/atk/atkvalue.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 11 additions & 17 deletions pkg/core/gextras/gextras.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@ import (
"unsafe"
)

type record struct {
_ NoCopy
p unsafe.Pointer
}
type record struct{ intern *internRecord }

type internRecord struct{ c unsafe.Pointer }

// StructNative returns the underlying C pointer of the given Go record struct
// pointer. It can be used like so:
Expand All @@ -22,7 +21,12 @@ type record struct {
// c := (*namespace_record)(StructPtr(unsafe.Pointer(rec)))
//
func StructNative(ptr unsafe.Pointer) unsafe.Pointer {
return (*record)(ptr).p
return (*record)(ptr).intern.c
}

// StructIntern returns the given struct's internal struct pointer.
func StructIntern(ptr unsafe.Pointer) *struct{ C unsafe.Pointer } {
return (*struct{ C unsafe.Pointer })(unsafe.Pointer((*record)(ptr).intern))
}

// SetStructNative sets the native value inside the Go struct value that the
Expand All @@ -32,26 +36,16 @@ func StructNative(ptr unsafe.Pointer) unsafe.Pointer {
// SetStructNative(&rec, cvalue) // T(cvalue) = *namespace_record
//
func SetStructNative(dst, native unsafe.Pointer) {
(*record)(dst).p = native
(*record)(dst).intern.c = native
}

// NewStructNative creates a new Go struct from the given native pointer. The
// finalizer is NOT set.
func NewStructNative(native unsafe.Pointer) unsafe.Pointer {
var r record
(*record)(&r).p = native
r := record{intern: &internRecord{native}}
return unsafe.Pointer(&r)
}

// NoCopy is a zero-sized type that triggers a warning in go vet when a struct
// containing this type is copied.
//
// See https://github.com/golang/go/issues/8005#issuecomment-190753527.
type NoCopy struct{}

func (*NoCopy) Lock() {}
func (*NoCopy) Unlock() {}

// HashTableSize returns the size of the *GHashTable.
func HashTableSize(ptr unsafe.Pointer) int {
return int(C.g_hash_table_size((*C.GHashTable)(ptr)))
Expand Down
Loading

0 comments on commit aa7ccd9

Please sign in to comment.