[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH V4 17/24] 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>
---
 tools/libxl/gentypes.py              |   67 ++++++++++++++++++++++++++++++++++
 tools/libxl/idl.py                   |   13 ++++++-
 tools/libxl/idl.txt                  |   12 ++++++
 tools/libxl/libxl_types.idl          |   26 ++++++++-----
 tools/libxl/libxl_types_internal.idl |    2 +-
 5 files changed, 108 insertions(+), 12 deletions(-)

diff --git a/tools/libxl/gentypes.py b/tools/libxl/gentypes.py
index 3e1140d..919d2d3 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"""
 
@@ -430,6 +485,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):
@@ -509,6 +567,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 9ce1e33..3498af1 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)
@@ -121,6 +128,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")
@@ -134,6 +142,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
@@ -150,6 +159,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)
 
@@ -266,6 +276,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",
@@ -280,7 +291,7 @@ uint16 = UInt(16)
 uint32 = UInt(32)
 uint64 = UInt(64)
 
-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 484d5d7..8b54aeb 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 6cf99fd..1bd4185 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -5,23 +5,29 @@
 
 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)
 
 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)
-libxl_mac = Builtin("mac", json_parse_type="JSON_STRING", 
passby=PASS_BY_REFERENCE)
-libxl_bitmap = Builtin("bitmap", json_parse_type="JSON_ARRAY", 
dispose_fn="libxl_bitmap_dispose", passby=PASS_BY_REFERENCE)
+                      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, copy_fn="libxl_uuid_copy_ctx")
+libxl_mac = Builtin("mac", json_parse_type="JSON_STRING", 
passby=PASS_BY_REFERENCE, copy_fn="libxl_mac_copy")
+libxl_bitmap = Builtin("bitmap", json_parse_type="JSON_ARRAY", 
dispose_fn="libxl_bitmap_dispose",
+                       copy_fn='libxl_bitmap_copy_alloc', 
passby=PASS_BY_REFERENCE)
 libxl_cpuid_policy_list = Builtin("cpuid_policy_list", 
json_parse_type="JSON_ARRAY",
-                                  dispose_fn="libxl_cpuid_dispose", 
passby=PASS_BY_REFERENCE)
+                                  dispose_fn="libxl_cpuid_dispose", 
passby=PASS_BY_REFERENCE,
+                                  copy_fn="libxl_cpuid_policy_list_copy")
 
 libxl_string_list = Builtin("string_list", json_parse_type="JSON_ARRAY",
-                            dispose_fn="libxl_string_list_dispose", 
passby=PASS_BY_REFERENCE)
+                            dispose_fn="libxl_string_list_dispose", 
passby=PASS_BY_REFERENCE,
+                            copy_fn="libxl_string_list_copy")
 libxl_key_value_list = Builtin("key_value_list", json_parse_type="JSON_MAP",
-                               dispose_fn="libxl_key_value_list_dispose", 
passby=PASS_BY_REFERENCE)
-libxl_hwcap = Builtin("hwcap", json_parse_type="JSON_ARRAY", 
passby=PASS_BY_REFERENCE)
+                               dispose_fn="libxl_key_value_list_dispose", 
passby=PASS_BY_REFERENCE,
+                               copy_fn="libxl_key_value_list_copy")
+libxl_hwcap = Builtin("hwcap", json_parse_type="JSON_ARRAY", 
passby=PASS_BY_REFERENCE,
+                      copy_fn="libxl_hwcap_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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.