summaryrefslogtreecommitdiffstats
path: root/ppapi/generators
diff options
context:
space:
mode:
authorteravest@chromium.org <teravest@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-30 00:13:25 +0000
committerteravest@chromium.org <teravest@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-30 00:13:25 +0000
commit2a7e8c52d4cc4e6adb055cc0ddebd0398b6c0fab (patch)
tree871d95dea43db9e9b45b09d989fc214f9f2b4a8d /ppapi/generators
parenta1287ea400e61be595736aff5437af3af63c5928 (diff)
downloadchromium_src-2a7e8c52d4cc4e6adb055cc0ddebd0398b6c0fab.zip
chromium_src-2a7e8c52d4cc4e6adb055cc0ddebd0398b6c0fab.tar.gz
chromium_src-2a7e8c52d4cc4e6adb055cc0ddebd0398b6c0fab.tar.bz2
IDL: Autogenerate thunk for PPB_Gamepad.
This required adding two features to the thunk generator. * Support for a 'singleton_resource' annotation, which forces the use of EnterInstanceAPI. * When a function fails in the thunk layer, and it returns void, automatically zero out the output arguments. This will probably have to be moved to an annotation later, but seems like a good heuristic for now. BUG=187666 Review URL: https://chromiumcodereview.appspot.com/13142007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@191477 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/generators')
-rwxr-xr-xppapi/generators/idl_thunk.py83
1 files changed, 62 insertions, 21 deletions
diff --git a/ppapi/generators/idl_thunk.py b/ppapi/generators/idl_thunk.py
index 3358f18..72b7eb1 100755
--- a/ppapi/generators/idl_thunk.py
+++ b/ppapi/generators/idl_thunk.py
@@ -35,6 +35,7 @@ class ThunkBodyMetadata(object):
"""Metadata about thunk body. Used for selecting which headers to emit."""
def __init__(self):
self._apis = set()
+ self._builtin_includes = set()
self._includes = set()
def AddApi(self, api):
@@ -49,6 +50,12 @@ class ThunkBodyMetadata(object):
def Includes(self):
return self._includes
+ def AddBuiltinInclude(self, include):
+ self._builtin_includes.add(include)
+
+ def BuiltinIncludes(self):
+ return self._builtin_includes
+
def _GetBaseFileName(filenode):
"""Returns the base name for output files, given the filenode.
@@ -83,32 +90,39 @@ def _GetThunkFileName(filenode, relpath):
return name
+def _AddApiHeader(filenode, meta):
+ """Adds an API header for the given file to the ThunkBodyMetadata."""
+ # The API header matches the file name, not the interface name.
+ api_basename = _GetBaseFileName(filenode)
+ if api_basename.endswith('_dev'):
+ api_basename = api_basename[:-len('_dev')]
+ if api_basename.endswith('_trusted'):
+ api_basename = api_basename[:-len('_trusted')]
+ meta.AddApi(api_basename + '_api')
+
+
def _MakeEnterLine(filenode, interface, arg, handle_errors, callback, meta):
"""Returns an EnterInstance/EnterResource string for a function."""
+ api_name = interface.GetName()
+ if api_name.endswith('Trusted'):
+ api_name = api_name[:-len('Trusted')]
+ if api_name.endswith('_Dev'):
+ api_name = api_name[:-len('_Dev')]
+ api_name += '_API'
+
if arg[0] == 'PP_Instance':
if callback is None:
- return 'EnterInstance enter(%s);' % arg[1]
+ arg_string = arg[1]
+ else:
+ arg_string = '%s, %s' % (arg[1], callback)
+ if interface.GetProperty('singleton_resource'):
+ _AddApiHeader(filenode, meta)
+ return 'EnterInstanceAPI<%s> enter(%s);' % (api_name, arg_string)
else:
- return 'EnterInstance enter(%s, %s);' % (arg[1], callback)
+ return 'EnterInstance enter(%s);' % arg_string
elif arg[0] == 'PP_Resource':
- api_name = interface.GetName()
- if api_name.endswith('Trusted'):
- api_name = api_name[:-len('Trusted')]
- if api_name.endswith('_Dev'):
- api_name = api_name[:-len('_Dev')]
- api_name += '_API'
-
enter_type = 'EnterResource<%s>' % api_name
- # The API header matches the file name, not the interface name.
- api_basename = _GetBaseFileName(filenode)
- if api_basename.endswith('_dev'):
- # Clip off _dev suffix.
- api_basename = api_basename[:-len('_dev')]
- if api_basename.endswith('_trusted'):
- # Clip off _trusted suffix.
- api_basename = api_basename[:-len('_trusted')]
- meta.AddApi(api_basename + '_api')
-
+ _AddApiHeader(filenode, meta)
if callback is None:
return '%s enter(%s, %s);' % (enter_type, arg[1],
str(handle_errors).lower())
@@ -240,10 +254,33 @@ def _MakeNormalMemberBody(filenode, release, node, member, rtype, args,
body += ' return %s;\n' % value
body += 'return enter.SetResult(%s);' % invocation
elif rtype == 'void':
+ # On failure, zero out all output parameters.
+ out_params = []
+ callnode = member.GetOneOf('Callspec')
+ if callnode:
+ cgen = CGen()
+ for param in callnode.GetListOf('Param'):
+ mode = cgen.GetParamMode(param)
+ if mode == 'out':
+ # We use the 'store' mode when getting the parameter type, since we
+ # need to call sizeof() for memset().
+ ptype, pname, _, _ = cgen.GetComponents(param, release, 'store')
+ out_params.append((pname, ptype))
+
body = '%s\n' % _MakeEnterLine(filenode, node, args[0], handle_errors,
None, meta)
- body += 'if (enter.succeeded())\n'
- body += ' %s;' % invocation
+ if not out_params:
+ body += 'if (enter.succeeded())\n'
+ body += ' %s;' % invocation
+ else:
+ body += 'if (enter.succeeded()) {\n'
+ body += ' %s;\n' % invocation
+ body += ' return;\n'
+ body += '}'
+ for param in out_params:
+ body += '\nmemset(%s, 0, sizeof(%s));' % param
+ meta.AddBuiltinInclude('string.h')
+
else:
value = member.GetProperty('on_failure')
if value is None:
@@ -360,6 +397,10 @@ class TGen(GeneratorByFile):
else:
out.Write('// %s,\n// %s\n\n' % (from_text, modified_text))
+ if meta.BuiltinIncludes():
+ for include in sorted(meta.BuiltinIncludes()):
+ out.Write('#include <%s>\n' % include)
+ out.Write('\n')
# TODO(teravest): Don't emit includes we don't need.
includes = ['ppapi/c/pp_errors.h',