diff mbox series

[RFC,1/2] libxl: add Function class to IDL

Message ID 7e1774dffe69c702f738566abeb04a3a9d29e21b.1595854292.git.rosbrookn@ainfosec.com (mailing list archive)
State New, archived
Headers show
Series add function support to IDL | expand

Commit Message

Nick Rosbrook July 27, 2020, 1:26 p.m. UTC
Add a Function and CtxFunction classes to idl.py to allow generator
scripts to generate wrappers which are repetitive and straight forward
when doing so by hand. Examples of such functions are the
device_add/remove functions.

To start, a Function has attributes for namespace, name, parameters,
return type, and an indication if the return value should be interpreted as
a status code. The CtxFunction class extends this by indicating that a
libxl_ctx is a required parmeter, and can optionally be an async
function.

Also, add logic to idl.parse to return the list of functions found in an
IDL file. For now, have users of idl.py -- i.e. libxl/gentypes.py and
golang/xenlight/gengotypes.py -- ignore the list of functions returned.

Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
---
 tools/golang/xenlight/gengotypes.py |  2 +-
 tools/libxl/gentypes.py             |  2 +-
 tools/libxl/idl.py                  | 46 ++++++++++++++++++++++++++++-
 3 files changed, 47 insertions(+), 3 deletions(-)

Comments

Anthony PERARD Aug. 14, 2020, 10:52 a.m. UTC | #1
On Mon, Jul 27, 2020 at 09:26:32AM -0400, Nick Rosbrook wrote:
> Add a Function and CtxFunction classes to idl.py to allow generator
> scripts to generate wrappers which are repetitive and straight forward
> when doing so by hand. Examples of such functions are the
> device_add/remove functions.
> 
> To start, a Function has attributes for namespace, name, parameters,
> return type, and an indication if the return value should be interpreted as
> a status code. The CtxFunction class extends this by indicating that a
> libxl_ctx is a required parmeter, and can optionally be an async
> function.
> 
> Also, add logic to idl.parse to return the list of functions found in an
> IDL file. For now, have users of idl.py -- i.e. libxl/gentypes.py and
> golang/xenlight/gengotypes.py -- ignore the list of functions returned.
> 
> Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
> ---
>  
> +class Function(object):
> +    """
> +    A general description of a function signature.
> +
> +    Attributes:
> +      name (str): name of the function, excluding namespace.
> +      params (list of (str,Type)): list of function parameters.
> +      return_type (Type): the Type (if any), returned by the function.
> +      return_is_status (bool): Indicates that the return value should be
> +                               interpreted as an error/status code.

Can we get away without `return_is_status`? Couldn't we try to have
return_type=libxl_error to indicate that return is a kind of status?

> +    """
> +class CtxFunction(Function):
> +    """
> +    A function that requires a libxl_ctx.
> +
> +    Attributes:
> +      is_asyncop (bool): indicates that the function accepts a
> +                         libxl_asyncop_how parameter.

While CtxFunction can be a function that takes `libxl_ctx` as first
parameter, I don't think `is_asyncop` can be used. We can't know if
`ao_how` will be last or not. For some function, `ao_how` is second to
last. So, I guess `ao_how` might need to be listed in `params`

What do you think?

Thanks,
Nick Rosbrook Aug. 17, 2020, 3:26 p.m. UTC | #2
On Fri, Aug 14, 2020 at 11:52:33AM +0100, Anthony PERARD wrote:
> On Mon, Jul 27, 2020 at 09:26:32AM -0400, Nick Rosbrook wrote:
> > Add a Function and CtxFunction classes to idl.py to allow generator
> > scripts to generate wrappers which are repetitive and straight forward
> > when doing so by hand. Examples of such functions are the
> > device_add/remove functions.
> > 
> > To start, a Function has attributes for namespace, name, parameters,
> > return type, and an indication if the return value should be interpreted as
> > a status code. The CtxFunction class extends this by indicating that a
> > libxl_ctx is a required parmeter, and can optionally be an async
> > function.
> > 
> > Also, add logic to idl.parse to return the list of functions found in an
> > IDL file. For now, have users of idl.py -- i.e. libxl/gentypes.py and
> > golang/xenlight/gengotypes.py -- ignore the list of functions returned.
> > 
> > Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
> > ---
> >  
> > +class Function(object):
> > +    """
> > +    A general description of a function signature.
> > +
> > +    Attributes:
> > +      name (str): name of the function, excluding namespace.
> > +      params (list of (str,Type)): list of function parameters.
> > +      return_type (Type): the Type (if any), returned by the function.
> > +      return_is_status (bool): Indicates that the return value should be
> > +                               interpreted as an error/status code.
> 
> Can we get away without `return_is_status`? Couldn't we try to have
> return_type=libxl_error to indicate that return is a kind of status?
> 
Yes, I think that is much better.

> > +    """
> > +class CtxFunction(Function):
> > +    """
> > +    A function that requires a libxl_ctx.
> > +
> > +    Attributes:
> > +      is_asyncop (bool): indicates that the function accepts a
> > +                         libxl_asyncop_how parameter.
> 
> While CtxFunction can be a function that takes `libxl_ctx` as first
> parameter, I don't think `is_asyncop` can be used. We can't know if
> `ao_how` will be last or not. For some function, `ao_how` is second to
> last. So, I guess `ao_how` might need to be listed in `params`
> 
> What do you think?
That's a good point. Do you think it would make sense to add `Builtin`
definitions to libxl_types.idl for `libxl_asyncop_how`,
`libxl_asyncprogress_how`, etc.? That way the generation scripts could
work with those types more easily. But, I guess since those definitions
aren't known until parse time we couldn't use them in the
`DeviceFunction` class definition (but maybe that's not a big deal).

Thank you for the feedback.

-NR
diff mbox series

Patch

diff --git a/tools/golang/xenlight/gengotypes.py b/tools/golang/xenlight/gengotypes.py
index 557fecd07b..bd3663c9ea 100644
--- a/tools/golang/xenlight/gengotypes.py
+++ b/tools/golang/xenlight/gengotypes.py
@@ -718,7 +718,7 @@  def xenlight_golang_fmt_name(name, exported = True):
 if __name__ == '__main__':
     idlname = sys.argv[1]
 
-    (builtins, types) = idl.parse(idlname)
+    (builtins, types, _) = idl.parse(idlname)
 
     for b in builtins:
         name = b.typename
diff --git a/tools/libxl/gentypes.py b/tools/libxl/gentypes.py
index 9a45e45acc..ac7306f3f7 100644
--- a/tools/libxl/gentypes.py
+++ b/tools/libxl/gentypes.py
@@ -592,7 +592,7 @@  if __name__ == '__main__':
 
     (_, idlname, header, header_private, header_json, impl) = sys.argv
 
-    (builtins,types) = idl.parse(idlname)
+    (builtins,types,_) = idl.parse(idlname)
 
     print("outputting libxl type definitions to %s" % header)
 
diff --git a/tools/libxl/idl.py b/tools/libxl/idl.py
index d7367503b4..1839871f86 100644
--- a/tools/libxl/idl.py
+++ b/tools/libxl/idl.py
@@ -347,6 +347,45 @@  class OrderedDict(dict):
     def ordered_items(self):
         return [(x,self[x]) for x in self.__ordered]
 
+class Function(object):
+    """
+    A general description of a function signature.
+
+    Attributes:
+      name (str): name of the function, excluding namespace.
+      params (list of (str,Type)): list of function parameters.
+      return_type (Type): the Type (if any), returned by the function.
+      return_is_status (bool): Indicates that the return value should be
+                               interpreted as an error/status code.
+    """
+    def __init__(self, name=None, params=None, return_type=None,
+                 return_is_status=False, namespace=None):
+
+        if namespace is None:
+            self.namespace = _get_default_namespace()
+        else:
+            self.namespace = namespace
+
+        self.name = self.namespace + name
+        self.params = params
+        self.return_type = return_type
+        self.return_is_status = return_is_status
+
+class CtxFunction(Function):
+    """
+    A function that requires a libxl_ctx.
+
+    Attributes:
+      is_asyncop (bool): indicates that the function accepts a
+                         libxl_asyncop_how parameter.
+    """
+    def __init__(self, name=None, params=None, return_type=None,
+                 return_is_status=False, is_asyncop=False):
+
+        self.is_asyncop = is_asyncop
+
+        Function.__init__(self, name, params, return_type, return_is_status)
+
 def parse(f):
     print("Parsing %s" % f, file=sys.stderr)
 
@@ -358,6 +397,10 @@  def parse(f):
             globs[n] = t
         elif isinstance(t,type(object)) and issubclass(t, Type):
             globs[n] = t
+        elif isinstance(t, Function):
+            globs[n] = t
+        elif isinstance(t,type(object)) and issubclass(t, Function):
+            globs[n] = t
         elif n in ['PASS_BY_REFERENCE', 'PASS_BY_VALUE',
                    'DIR_NONE', 'DIR_IN', 'DIR_OUT', 'DIR_BOTH',
                    'namespace', 'hidden']:
@@ -370,8 +413,9 @@  def parse(f):
                           % (e.lineno, f, e.text))
 
     types = [t for t in locs.ordered_values() if isinstance(t,Type)]
+    funcs = [f for f in locs.ordered_values() if isinstance(f,Function)]
 
     builtins = [t for t in types if isinstance(t,Builtin)]
     types = [t for t in types if not isinstance(t,Builtin)]
 
-    return (builtins,types)
+    return (builtins,types,funcs)