golang/xenlight: begin Go to C type marshaling

Implement conversions for basic types such as strings and integer
types in toC functions.

Modify function signatures of toC implementations for builtin
types to be consistent with the signature of the generated toC
functions.

Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
Reviewed-by: George Dunlap <george.dunlap@citrix.com>
This commit is contained in:
Nick Rosbrook authored and George Dunlap committed 2020-01-16 18:18:02 +00:00
1 parent 1b4c0be707
commit 273971c940
3 files changed
+1621 -48

No files matched your search

+81
View File
@@ -234,6 +234,9 @@ def xenlight_golang_generate_helpers(path = None, types = None, comment = None):
f.write(extra)
f.write('\n')
f.write(xenlight_golang_define_to_C(ty))
f.write('\n')
go_fmt(path)
def xenlight_golang_define_from_C(ty = None):
@@ -434,6 +437,84 @@ def xenlight_golang_array_from_C(ty = None):
return s
def xenlight_golang_define_to_C(ty = None, typename = None, nested = False):
"""
Define the toC marshaling function for the type
represented by ty.
"""
func = 'func (x *{}) toC(xc *C.{}) (err error){{{}\n return nil \n }}\n'
body = ''
if ty.dispose_fn is not None:
body += 'defer func(){{\nif err != nil{{\nC.{}(xc)}}\n}}()\n\n'.format(ty.dispose_fn)
goname = xenlight_golang_fmt_name(ty.typename)
cname = ty.typename
for f in ty.fields:
if f.type.typename is not None:
if isinstance(f.type, idl.Array):
# TODO
continue
body += xenlight_golang_convert_to_C(f)
elif isinstance(f.type, idl.Struct):
for nf in f.type.fields:
body += xenlight_golang_convert_to_C(nf, outer_name=f.name)
elif isinstance(f.type, idl.KeyedUnion):
# TODO
pass
else:
raise Exception('type {} not supported'.format(f.type))
return func.format(goname, cname, body)
def xenlight_golang_convert_to_C(ty = None, outer_name = None):
"""
Returns a line of Go code that converts the Go type represented
by ty to its corresponding Go type.
If outer_name is set, the type is treated as nested within another field
named outer_name.
"""
s = ''
gotypename = xenlight_golang_fmt_name(ty.type.typename)
ctypename = ty.type.typename
goname = xenlight_golang_fmt_name(ty.name)
cname = ty.name
# In cgo, C names that conflict with Go keywords can be
# accessed by prepending an underscore to the name.
if cname in go_keywords:
cname = '_' + cname
# If outer_name is set, treat this as nested.
if outer_name is not None:
goname = '{}.{}'.format(xenlight_golang_fmt_name(outer_name), goname)
cname = '{}.{}'.format(outer_name, cname)
is_castable = (ty.type.json_parse_type == 'JSON_INTEGER' or
isinstance(ty.type, idl.Enumeration) or
gotypename in go_builtin_types)
if not is_castable:
s += 'if err := x.{}.toC(&xc.{}); err != nil {{\n'.format(goname,cname)
s += 'return err\n}\n'
elif gotypename == 'string':
# Use the cgo helper for converting C strings.
s += 'if x.{} != "" {{\n'.format(goname)
s += 'xc.{} = C.CString(x.{})}}\n'.format(cname,goname)
else:
s += 'xc.{} = C.{}(x.{})\n'.format(cname,ctypename,goname)
return s
def xenlight_golang_fmt_name(name, exported = True):
"""
Take a given type name and return an
File diff suppressed because it is too large. Load diff
+34 -48
View File
@@ -140,14 +140,12 @@ func (u *Uuid) fromC(c *C.libxl_uuid) error {
return nil
}
func (u *Uuid) toC() (C.libxl_uuid, error) {
var c C.libxl_uuid
func (u *Uuid) toC(cu *C.libxl_uuid) error {
for i, v := range u {
c.uuid[i] = C.uint8_t(v)
cu.uuid[i] = C.uint8_t(v)
}
return c, nil
return nil
}
// defboolVal represents a defbool value.
@@ -232,15 +230,13 @@ func (d *Defbool) fromC(c *C.libxl_defbool) error {
return nil
}
func (d *Defbool) toC() (C.libxl_defbool, error) {
var c C.libxl_defbool
func (d *Defbool) toC(cd *C.libxl_defbool) error {
if !d.IsDefault() {
val, _ := d.Val()
C.libxl_defbool_set(&c, C.bool(val))
C.libxl_defbool_set(cd, C.bool(val))
}
return c, nil
return nil
}
// Mac represents a libxl_mac, or simply a MAC address.
@@ -266,14 +262,12 @@ func (mac *Mac) fromC(cmac *C.libxl_mac) error {
return nil
}
func (mac Mac) toC() (C.libxl_mac, error) {
var cmac C.libxl_mac
func (mac Mac) toC(cm *C.libxl_mac) error {
for i, v := range mac {
cmac[i] = C.uint8_t(v)
(*cm)[i] = C.uint8_t(v)
}
return cmac, nil
return nil
}
// MsVmGenid represents a libxl_ms_vm_genid.
@@ -287,14 +281,12 @@ func (mvg *MsVmGenid) fromC(cmvg *C.libxl_ms_vm_genid) error {
return nil
}
func (mvg *MsVmGenid) toC() (C.libxl_ms_vm_genid, error) {
var cmvg C.libxl_ms_vm_genid
func (mvg *MsVmGenid) toC(cmvg *C.libxl_ms_vm_genid) error {
for i, v := range mvg {
cmvg.bytes[i] = C.uint8_t(v)
}
return cmvg, nil
return nil
}
// EvLink represents a libxl_ev_link.
@@ -304,8 +296,8 @@ func (mvg *MsVmGenid) toC() (C.libxl_ms_vm_genid, error) {
// through the Go package.
type EvLink struct{}
func (el *EvLink) fromC(cel *C.libxl_ev_link) error { return nil }
func (el *EvLink) toC() (cel C.libxl_ev_link, err error) { return }
func (el *EvLink) fromC(cel *C.libxl_ev_link) error { return nil }
func (el *EvLink) toC(cel *C.libxl_ev_link) (err error) { return }
// CpuidPolicyList represents a libxl_cpuid_policy_list.
//
@@ -316,20 +308,18 @@ type CpuidPolicyList string
func (cpl CpuidPolicyList) fromC(ccpl *C.libxl_cpuid_policy_list) error { return nil }
func (cpl CpuidPolicyList) toC() (C.libxl_cpuid_policy_list, error) {
var ccpl C.libxl_cpuid_policy_list
func (cpl CpuidPolicyList) toC(ccpl *C.libxl_cpuid_policy_list) error {
s := C.CString(string(cpl))
defer C.free(unsafe.Pointer(s))
ret := C.libxl_cpuid_parse_config(&ccpl, s)
ret := C.libxl_cpuid_parse_config(ccpl, s)
if ret != 0 {
C.libxl_cpuid_dispose(&ccpl)
C.libxl_cpuid_dispose(ccpl)
return ccpl, Error(-ret)
return Error(-ret)
}
return ccpl, nil
return nil
}
// Hwcap represents a libxl_hwcap.
@@ -343,14 +333,12 @@ func (hwcap *Hwcap) fromC(chwcap *C.libxl_hwcap) error {
return nil
}
func (hwcap *Hwcap) toC() (C.libxl_hwcap, error) {
var chwcap C.libxl_hwcap
func (hwcap *Hwcap) toC(chwcap *C.libxl_hwcap) error {
for i, v := range hwcap {
chwcap[i] = C.uint32_t(v)
(*chwcap)[i] = C.uint32_t(v)
}
return chwcap, nil
return nil
}
// KeyValueList represents a libxl_key_value_list.
@@ -360,8 +348,8 @@ func (hwcap *Hwcap) toC() (C.libxl_hwcap, error) {
// Go package.
type KeyValueList struct{}
func (kvl KeyValueList) fromC(ckvl *C.libxl_key_value_list) error { return nil }
func (kvl KeyValueList) toC() (ckvl C.libxl_key_value_list, err error) { return }
func (kvl KeyValueList) fromC(ckvl *C.libxl_key_value_list) error { return nil }
func (kvl KeyValueList) toC(ckvl *C.libxl_key_value_list) (err error) { return }
// StringList represents a libxl_string_list.
type StringList []string
@@ -379,17 +367,17 @@ func (sl *StringList) fromC(csl *C.libxl_string_list) error {
return nil
}
func (sl StringList) toC() (C.libxl_string_list, error) {
func (sl StringList) toC(csl *C.libxl_string_list) error {
var char *C.char
size := len(sl)
csl := (C.libxl_string_list)(C.malloc(C.ulong(size) * C.ulong(unsafe.Sizeof(char))))
*csl = (C.libxl_string_list)(C.malloc(C.ulong(size) * C.ulong(unsafe.Sizeof(char))))
clist := (*[1 << 30]*C.char)(unsafe.Pointer(csl))[:size:size]
for i, v := range sl {
clist[i] = C.CString(v)
}
return csl, nil
return nil
}
// Bitmap represents a libxl_bitmap.
@@ -421,9 +409,7 @@ func (bm *Bitmap) fromC(cbm *C.libxl_bitmap) error {
return nil
}
func (bm *Bitmap) toC() (C.libxl_bitmap, error) {
var cbm C.libxl_bitmap
func (bm *Bitmap) toC(cbm *C.libxl_bitmap) error {
size := len(bm.bitmap)
cbm.size = C.uint32_t(size)
cbm._map = (*C.uint8_t)(C.malloc(C.ulong(cbm.size) * C.sizeof_uint8_t))
@@ -431,7 +417,7 @@ func (bm *Bitmap) toC() (C.libxl_bitmap, error) {
copy(cs, bm.bitmap)
return cbm, nil
return nil
}
func (sr ShutdownReason) String() (str string) {
@@ -534,8 +520,8 @@ func (Ctx *Context) CpupoolCreate(Name string, Scheduler Scheduler, Cpumap Bitma
var uuid C.libxl_uuid
C.libxl_uuid_generate(&uuid)
cbm, err := Cpumap.toC()
if err != nil {
var cbm C.libxl_bitmap
if err = Cpumap.toC(&cbm); err != nil {
return
}
defer C.libxl_bitmap_dispose(&cbm)
@@ -577,8 +563,8 @@ func (Ctx *Context) CpupoolCpuadd(Poolid uint32, Cpu int) (err error) {
// int libxl_cpupool_cpuadd_cpumap(libxl_ctx *ctx, uint32_t poolid,
// const libxl_bitmap *cpumap);
func (Ctx *Context) CpupoolCpuaddCpumap(Poolid uint32, Cpumap Bitmap) (err error) {
cbm, err := Cpumap.toC()
if err != nil {
var cbm C.libxl_bitmap
if err = Cpumap.toC(&cbm); err != nil {
return
}
defer C.libxl_bitmap_dispose(&cbm)
@@ -606,8 +592,8 @@ func (Ctx *Context) CpupoolCpuremove(Poolid uint32, Cpu int) (err error) {
// int libxl_cpupool_cpuremove_cpumap(libxl_ctx *ctx, uint32_t poolid,
// const libxl_bitmap *cpumap);
func (Ctx *Context) CpupoolCpuremoveCpumap(Poolid uint32, Cpumap Bitmap) (err error) {
cbm, err := Cpumap.toC()
if err != nil {
var cbm C.libxl_bitmap
if err = Cpumap.toC(&cbm); err != nil {
return
}
defer C.libxl_bitmap_dispose(&cbm)
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.