Skip to content

Commit

Permalink
Separate Go and C struct pointer, fixes #17
Browse files Browse the repository at this point in the history
  • Loading branch information
diamondburned committed Jul 15, 2021
1 parent 856899c commit 14b6eb3
Show file tree
Hide file tree
Showing 285 changed files with 7,278 additions and 6,632 deletions.
13 changes: 4 additions & 9 deletions gir/girgen/generators/record.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,14 @@ var recordIgnoreSuffixes = []string{
var recordTmpl = gotmpl.NewGoTemplate(`
{{ GoDoc . 0 }}
type {{ .GoName }} struct {
native C.{{ .CType }}
nocopy gextras.NoCopy
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 }})(unsafe.Pointer(b)), nil
return &{{ .GoName }}{native: (*C.{{.CType}})(unsafe.Pointer(b))}, nil
}
{{ end }}
Expand All @@ -54,11 +55,6 @@ var recordTmpl = gotmpl.NewGoTemplate(`
{{ $recv := (FirstLetter $.GoName) }}
// Native returns the underlying C source pointer.
func ({{ $recv }} *{{ .GoName }}) Native() unsafe.Pointer {
return unsafe.Pointer(&{{ FirstLetter .GoName }}.native)
}
{{ range .Getters }}
{{ GoDoc . 0 }}
func ({{ $recv }} *{{ $.GoName }}) {{ .Name }}() {{ .Type }} {{ .Block }}
Expand Down Expand Up @@ -136,8 +132,7 @@ func GenerateRecord(gen FileGeneratorWriter, record *gir.Record) bool {
}

writer := FileWriterFromType(gen, record)
// Need unsafe for the wrapper.
writer.Header().Import("unsafe")
writer.Header().ImportCore("gextras")

if record.GLibGetType != "" && !types.FilterCType(gen, record.GLibGetType) {
writer.Header().AddMarshaler(record.GLibGetType, recordGen.GoName)
Expand Down
41 changes: 14 additions & 27 deletions gir/girgen/types/typeconv/c-go.go
Original file line number Diff line number Diff line change
Expand Up @@ -391,17 +391,17 @@ func (conv *Converter) cgoConverter(value *ValueConverted) bool {
unref = "cairo_pattern_destroy"
value.p.Descend()
// Hack to fit the Pattern type.
value.p.Linef("_p := &struct{p unsafe.Pointer}{unsafe.Pointer(%s)}", value.InNamePtr(1))
value.p.Linef("%s = (*cairo.Pattern)(unsafe.Pointer(_p))", value.Out.Set)
value.p.Linef("_pp:= &struct{p unsafe.Pointer}{unsafe.Pointer(%s)}", value.InNamePtr(1))
value.p.Linef("%s = (*cairo.Pattern)(unsafe.Pointer(_pp))", value.Out.Set)
value.p.Ascend()

case "cairo.Region":
ref = "cairo_region_reference"
unref = "cairo_region_destroy"
value.p.Descend()
// Hack to fit the Region type.
value.p.Linef("_p := &struct{p unsafe.Pointer}{unsafe.Pointer(%s)}", value.InNamePtr(1))
value.p.Linef("%s = (*cairo.Region)(unsafe.Pointer(_p))", value.Out.Set)
value.p.Linef("_pp:= &struct{p unsafe.Pointer}{unsafe.Pointer(%s)}", value.InNamePtr(1))
value.p.Linef("%s = (*cairo.Region)(unsafe.Pointer(_pp))", value.Out.Set)
value.p.Ascend()
}

Expand Down Expand Up @@ -434,32 +434,19 @@ func (conv *Converter) cgoConverter(value *ValueConverted) bool {

switch v := value.Resolved.Extern.Type.(type) {
case *gir.Enum, *gir.Bitfield:
value.p.LineTmpl(value, "<.Out.Set> = <.OutCast 0>(<.InNamePtr 0>)")
value.vtmpl("<.Out.Set> = <.OutCast 0>(<.InNamePtr 0>)")
return true

case *gir.Class, *gir.Interface:
return value.cgoSetObject(conv)

case *gir.Record:
// We can slightly cheat here. Since Go structs are declared by wrapping
// the C type, we can directly cast to the C type if this is an output
// parameter. This saves us a copy.
if value.Resolved.Ptr < 2 && value.outputAllocs() {
value.header.Import("unsafe")

value.outDecl.Reset()
value.inDecl.Reset()

// Write the Go type directly.
value.inDecl.Linef("var %s %s", value.OutName, value.Out.Type)
value.In.Call = fmt.Sprintf("(*%s)(unsafe.Pointer(&%s))", value.In.Type, value.OutName)

return true
}

value.header.Import("unsafe")
value.header.ImportCore("gextras")

// Require 1 pointer to avoid weird copies.
value.p.LineTmpl(value, "<.Out.Set> = <.OutCast 1>(unsafe.Pointer(<.InNamePtr 1>))")
value.vtmpl(
"<.Out.Set> = <.OutCast 1>(gextras.NewStructNative(unsafe.Pointer(<.InNamePtr 1>)))")
if value.fail {
return false
}
Expand All @@ -482,17 +469,17 @@ 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.p.LineTmpl(value,
value.vtmpl(
"runtime.SetFinalizer(<.OutInPtr 1><.OutName>, func(v <.OutPtr 1><.Out.Type>) {")

if free != nil {
value.p.Linef(
"C.%s((%s%s)(unsafe.Pointer(v)))",
"C.%s((%s%s)(gextras.StructNative(unsafe.Pointer(v))))",
free.CIdentifier, value.OutPtr(1), value.In.Type)
} else {
value.p.Linef("C.free(unsafe.Pointer(v))")
value.p.Linef(
"C.free(gextras.StructNative(unsafe.Pointer(v)))",
)
}

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

Expand Down
5 changes: 4 additions & 1 deletion gir/girgen/types/typeconv/go-c.go
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,10 @@ func (conv *Converter) gocConverter(value *ValueConverted) bool {

case *gir.Record:
value.header.Import("unsafe")
value.p.LineTmpl(value, "<.Out.Set> = <.OutCast 1>(unsafe.Pointer(<.InNamePtr 1>))")
value.header.ImportCore("gextras")
value.vtmpl(
"<.Out.Set> = <.OutCast 1>(gextras.StructNative(unsafe.Pointer(<.InNamePtr 1>)))",
)

// This code might trigger a double-free.
// // If ShouldFree is true, then ideally, we'll be freeing the C copy of
Expand Down
4 changes: 4 additions & 0 deletions gir/girgen/types/typeconv/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,10 @@ func (value *ValueConverted) flush() {
value.Conversion = value.p.String()
}

func (value *ValueConverted) vtmpl(tmpl string) {
value.p.LineTmpl(value, tmpl)
}

func (value *ValueConverted) Logln(lvl logger.Level, v ...interface{}) {
value.log(lvl, logger.Prefix(v, value.logPrefix())...)
}
Expand Down
10 changes: 3 additions & 7 deletions pkg/atk/atkcomponent.go

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

16 changes: 4 additions & 12 deletions pkg/atk/atkobject.go

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

29 changes: 13 additions & 16 deletions pkg/atk/atkrange.go

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

4 changes: 2 additions & 2 deletions pkg/atk/atkstreamablecontent.go

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

40 changes: 18 additions & 22 deletions pkg/atk/atktext.go

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

Loading

0 comments on commit 14b6eb3

Please sign in to comment.