Index: ppapi/generators/idl_thunk.py |
diff --git a/ppapi/generators/idl_thunk.py b/ppapi/generators/idl_thunk.py |
index 3358f188f0a5641dcb66b9f64a24b6d0caf67137..72b7eb1e7072d534d9a056a2c22d5fa0a543d944 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', |