[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v9 7/8] libxl IDL: generate deep copy functions
Introduces copy_fn for a type. For most builtin types we can use direct assignment. For those builtin types which cannot use direct assignment we use the copy functions in previous patch. Signed-off-by: Wei Liu <wei.liu2@xxxxxxxxxx> Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx> --- change since last version: add copy_fn for libxl_ms_vm_genid type --- tools/libxl/gentypes.py | 67 ++++++++++++++++++++++++++++++++++ tools/libxl/idl.py | 13 ++++++- tools/libxl/idl.txt | 12 ++++++ tools/libxl/libxl_types.idl | 30 +++++++++------ tools/libxl/libxl_types_internal.idl | 2 +- 5 files changed, 110 insertions(+), 14 deletions(-) diff --git a/tools/libxl/gentypes.py b/tools/libxl/gentypes.py index 6cdeaa8..4b0c996 100644 --- a/tools/libxl/gentypes.py +++ b/tools/libxl/gentypes.py @@ -100,6 +100,61 @@ def libxl_C_type_dispose(ty, v, indent = " ", parent = None): s = indent + s return s.replace("\n", "\n%s" % indent).rstrip(indent) +def libxl_C_type_copy(ty, v, w, indent = " ", vparent = None, wparent = None): + s = "" + + if vparent is None: + s += "GC_INIT(ctx);\n"; + + if isinstance(ty, idl.KeyedUnion): + if vparent is None or wparent is None: + raise Exception("KeyedUnion type must have a parent") + s += "%s = %s;\n" % ((vparent + ty.keyvar.name), (wparent + ty.keyvar.name)) + s += "switch (%s) {\n" % (wparent + ty.keyvar.name) + for f in ty.fields: + (vnparent,vfexpr) = ty.member(v, f, vparent is None) + (wnparent,wfexpr) = ty.member(w, f, wparent is None) + s += "case %s:\n" % f.enumname + if f.type is not None: + s += libxl_C_type_copy(f.type, vfexpr, wfexpr, indent + " ", + vnparent, wnparent) + s += " break;\n" + s += "}\n" + elif isinstance(ty, idl.Array): + if vparent is None or wparent is None: + raise Exception("Array type must have a parent") + s += "%s = libxl__calloc(NOGC, %s, sizeof(*%s));\n" % (ty.pass_arg(v, vparent is None), + (wparent + ty.lenvar.name), + ty.pass_arg(w, wparent is None)) + s += "%s = %s;\n" % ((vparent + ty.lenvar.name), (wparent + ty.lenvar.name)) + s += "{\n" + s += " int i;\n" + s += " for (i=0; i<%s; i++)\n" % (wparent + ty.lenvar.name) + s += libxl_C_type_copy(ty.elem_type, v+"[i]", w+"[i]", + indent + " ", vparent, wparent) + s += "}\n" + elif isinstance(ty, idl.Struct) and ((vparent is None and wparent is None) or ty.copy_fn is None): + for f in [f for f in ty.fields if not f.const and not f.type.private]: + (vnparent,vfexpr) = ty.member(v, f, vparent is None) + (wnparent,wfexpr) = ty.member(w, f, wparent is None) + s += libxl_C_type_copy(f.type, vfexpr, wfexpr, "", vnparent, wnparent) + else: + if ty.copy_fn is not None: + s += "%s(ctx, %s, %s);\n" % (ty.copy_fn, + ty.pass_arg(v, vparent is None, passby=idl.PASS_BY_REFERENCE), + ty.pass_arg(w, wparent is None, passby=idl.PASS_BY_REFERENCE)) + + else: + s += "%s = %s;\n" % (ty.pass_arg(v, vparent is None, passby=idl.PASS_BY_VALUE), + ty.pass_arg(w, wparent is None, passby=idl.PASS_BY_VALUE)) + + if vparent is None: + s += "GC_FREE;\n" + + if s != "": + s = indent + s + return s.replace("\n", "\n%s" % indent).rstrip(indent) + def libxl_init_members(ty, nesting = 0): """Returns a list of members of ty which require a separate init""" @@ -489,6 +544,9 @@ if __name__ == '__main__': f.write(libxl_C_type_define(ty) + ";\n") if ty.dispose_fn is not None: f.write("%svoid %s(%s);\n" % (ty.hidden(), ty.dispose_fn, ty.make_arg("p"))) + if ty.copy_fn is not None: + f.write("%svoid %s(libxl_ctx *ctx, %s, %s);\n" % (ty.hidden(), ty.copy_fn, + ty.make_arg("dst"), ty.make_arg("src"))) if ty.init_fn is not None: f.write("%svoid %s(%s);\n" % (ty.hidden(), ty.init_fn, ty.make_arg("p"))) for field in libxl_init_members(ty): @@ -590,6 +648,15 @@ if __name__ == '__main__': f.write(" memset(p, LIBXL_DTOR_POISON, sizeof(*p));\n") f.write("}\n") f.write("\n") + + for ty in [t for t in types if t.copy_fn and t.autogenerate_copy_fn]: + f.write("void %s(libxl_ctx *ctx, %s, %s)\n" % (ty.copy_fn, + ty.make_arg("dst", passby=idl.PASS_BY_REFERENCE), + ty.make_arg("src", passby=idl.PASS_BY_REFERENCE))) + f.write("{\n") + f.write(libxl_C_type_copy(ty, "dst", "src")) + f.write("}\n") + f.write("\n") for ty in [t for t in types if t.init_fn is not None and t.autogenerate_init_fn]: f.write(libxl_C_type_init(ty)) diff --git a/tools/libxl/idl.py b/tools/libxl/idl.py index 63557db..437049e 100644 --- a/tools/libxl/idl.py +++ b/tools/libxl/idl.py @@ -60,6 +60,13 @@ class Type(object): self.autogenerate_dispose_fn = kwargs.setdefault('autogenerate_dispose_fn', True) + if self.typename is not None: + self.copy_fn = kwargs.setdefault('copy_fn', self.typename + "_copy") + else: + self.copy_fn = kwargs.setdefault('copy_fn', None) + + self.autogenerate_copy_fn = kwargs.setdefault('autogenerate_copy_fn', True) + self.init_fn = kwargs.setdefault('init_fn', None) self.init_val = kwargs.setdefault('init_val', None) self.autogenerate_init_fn = kwargs.setdefault('autogenerate_init_fn', False) @@ -128,6 +135,7 @@ class Number(Builtin): def __init__(self, ctype, **kwargs): kwargs.setdefault('namespace', None) kwargs.setdefault('dispose_fn', None) + kwargs.setdefault('copy_fn', None) kwargs.setdefault('signed', False) kwargs.setdefault('json_gen_fn', "yajl_gen_integer") kwargs.setdefault('json_parse_type', "JSON_INTEGER") @@ -141,6 +149,7 @@ class UInt(Number): kwargs.setdefault('namespace', None) kwargs.setdefault('dispose_fn', None) kwargs.setdefault('json_parse_fn', "libxl__uint%d_parse_json" % w) + kwargs.setdefault('copy_fn', None) Number.__init__(self, "uint%d_t" % w, **kwargs) self.width = w @@ -157,6 +166,7 @@ class EnumerationValue(object): class Enumeration(Type): def __init__(self, typename, values, **kwargs): kwargs.setdefault('dispose_fn', None) + kwargs.setdefault('copy_fn', None) kwargs.setdefault('json_parse_type', "JSON_STRING") Type.__init__(self, typename, **kwargs) @@ -273,6 +283,7 @@ class KeyedUnion(Aggregate): void = Builtin("void *", namespace = None) bool = Builtin("bool", namespace = None, + copy_fn=None, json_gen_fn = "yajl_gen_bool", json_parse_type = "JSON_BOOL", json_parse_fn = "libxl__bool_parse_json", @@ -287,7 +298,7 @@ uint16 = UInt(16) uint32 = UInt(32) uint64 = UInt(64, json_gen_fn = "libxl__uint64_gen_json") -string = Builtin("char *", namespace = None, dispose_fn = "free", +string = Builtin("char *", namespace = None, copy_fn = "libxl_string_copy", dispose_fn = "free", json_gen_fn = "libxl__string_gen_json", json_parse_type = "JSON_STRING | JSON_NULL", json_parse_fn = "libxl__string_parse_json", diff --git a/tools/libxl/idl.txt b/tools/libxl/idl.txt index 87c4952..7440fb3 100644 --- a/tools/libxl/idl.txt +++ b/tools/libxl/idl.txt @@ -44,6 +44,18 @@ Type.autogenerate_dispose_fn: (default: True) Indicates if the above named Type.dispose_fn should be autogenerated. +Type.copy_fn: (default: typename + "_copy" or None if type == None) + + The name of the C function which will deep copy all fields within + this type. + +Type.autogenerate_copy_fn: (default: True) + + Indicates if the above named Type.copy_fn should be + autogenerated. + +Type.autogenerate_copy_fn + Type.init_val: (default: None) C expression for the value to initialise instances of this type to. diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl index 244075a..a412f9c 100644 --- a/tools/libxl/libxl_types.idl +++ b/tools/libxl/libxl_types.idl @@ -5,27 +5,33 @@ namespace("libxl_") -libxl_defbool = Builtin("defbool", json_parse_type="JSON_STRING", passby=PASS_BY_REFERENCE, +libxl_defbool = Builtin("defbool", json_parse_type="JSON_STRING", passby=PASS_BY_REFERENCE, copy_fn=None, check_default_fn="libxl__defbool_is_default") - libxl_domid = Builtin("domid", json_gen_fn = "yajl_gen_integer", json_parse_fn = "libxl__uint32_parse_json", - json_parse_type = "JSON_INTEGER", autogenerate_json = False) + json_parse_type = "JSON_INTEGER", autogenerate_json = False, copy_fn=None) libxl_devid = Builtin("devid", json_gen_fn = "yajl_gen_integer", json_parse_fn = "libxl__int_parse_json", - json_parse_type = "JSON_INTEGER", autogenerate_json = False, signed = True, init_val="-1") -libxl_uuid = Builtin("uuid", json_parse_type="JSON_STRING", passby=PASS_BY_REFERENCE, check_default_fn="libxl_uuid_is_nil") -libxl_mac = Builtin("mac", json_parse_type="JSON_STRING", passby=PASS_BY_REFERENCE, check_default_fn="libxl__mac_is_default") + json_parse_type = "JSON_INTEGER", autogenerate_json = False, signed = True, init_val="-1", + copy_fn=None) +libxl_uuid = Builtin("uuid", json_parse_type="JSON_STRING", passby=PASS_BY_REFERENCE, check_default_fn="libxl_uuid_is_nil", + copy_fn="libxl_uuid_copy") +libxl_mac = Builtin("mac", json_parse_type="JSON_STRING", passby=PASS_BY_REFERENCE, check_default_fn="libxl__mac_is_default", + copy_fn="libxl_mac_copy") libxl_bitmap = Builtin("bitmap", json_parse_type="JSON_ARRAY", dispose_fn="libxl_bitmap_dispose", passby=PASS_BY_REFERENCE, - check_default_fn="libxl_bitmap_is_empty") + check_default_fn="libxl_bitmap_is_empty", copy_fn="libxl_bitmap_copy_alloc") libxl_cpuid_policy_list = Builtin("cpuid_policy_list", dispose_fn="libxl_cpuid_dispose", passby=PASS_BY_REFERENCE, - json_parse_type="JSON_ARRAY", check_default_fn="libxl__cpuid_policy_is_empty") + json_parse_type="JSON_ARRAY", check_default_fn="libxl__cpuid_policy_is_empty", + copy_fn="libxl_cpuid_policy_list_copy") libxl_string_list = Builtin("string_list", dispose_fn="libxl_string_list_dispose", passby=PASS_BY_REFERENCE, - json_parse_type="JSON_ARRAY", check_default_fn="libxl__string_list_is_empty") + json_parse_type="JSON_ARRAY", check_default_fn="libxl__string_list_is_empty", + copy_fn="libxl_string_list_copy") libxl_key_value_list = Builtin("key_value_list", dispose_fn="libxl_key_value_list_dispose", passby=PASS_BY_REFERENCE, - json_parse_type="JSON_MAP", check_default_fn="libxl__key_value_list_is_empty") + json_parse_type="JSON_MAP", check_default_fn="libxl__key_value_list_is_empty", + copy_fn="libxl_key_value_list_copy") libxl_hwcap = Builtin("hwcap", passby=PASS_BY_REFERENCE, json_parse_type="JSON_ARRAY", - check_default_fn="libxl__hwcap_is_default") -libxl_ms_vm_genid = Builtin("ms_vm_genid", passby=PASS_BY_REFERENCE, check_default_fn="libxl_ms_vm_genid_is_zero") + check_default_fn="libxl__hwcap_is_default", copy_fn="libxl_hwcap_copy") +libxl_ms_vm_genid = Builtin("ms_vm_genid", passby=PASS_BY_REFERENCE, check_default_fn="libxl_ms_vm_genid_is_zero", + copy_fn="libxl_ms_vm_genid_copy") # # Specific integer types diff --git a/tools/libxl/libxl_types_internal.idl b/tools/libxl/libxl_types_internal.idl index 17533f1..800361b 100644 --- a/tools/libxl/libxl_types_internal.idl +++ b/tools/libxl/libxl_types_internal.idl @@ -3,7 +3,7 @@ hidden(True) libxl_domid = Builtin("domid", namespace="libxl_", json_gen_fn = "yajl_gen_integer", json_parse_fn = "libxl__uint32_parse_json", json_parse_type = "JSON_INTEGER", - autogenerate_json = False) + autogenerate_json = False, copy_fn = None) libxl__qmp_message_type = Enumeration("qmp_message_type", [ (1, "QMP"), -- 1.7.10.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |