| Index: ppapi/generators/idl_thunk.py
|
| diff --git a/ppapi/generators/idl_thunk.py b/ppapi/generators/idl_thunk.py
|
| index 6018753580de0e64bcf193285e8ad288f68140b2..d183e4b9224e407b94403aa745925b285409c3a5 100755
|
| --- a/ppapi/generators/idl_thunk.py
|
| +++ b/ppapi/generators/idl_thunk.py
|
| @@ -214,6 +214,30 @@ def _MakeCreateMemberBody(interface, member, args):
|
| return body
|
|
|
|
|
| +def _GetOutputParams(member, release):
|
| + """Returns output parameters (and their types) for a member function.
|
| +
|
| + Args:
|
| + member - IDLNode for the member function
|
| + release - Release to get output parameters for
|
| + Returns:
|
| + A list of name strings for all output parameters of the member
|
| + function.
|
| + """
|
| + 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().
|
| + _, pname, _, _ = cgen.GetComponents(param, release, 'store')
|
| + out_params.append(pname)
|
| + return out_params
|
| +
|
| +
|
| def _MakeNormalMemberBody(filenode, release, node, member, rtype, args,
|
| include_version, meta):
|
| """Returns the body of a typical function.
|
| @@ -253,42 +277,40 @@ def _MakeNormalMemberBody(filenode, release, node, member, rtype, args,
|
| call_arglist)
|
|
|
| handle_errors = not (member.GetProperty('report_errors') == 'False')
|
| + out_params = _GetOutputParams(member, release)
|
| if is_callback_func:
|
| + # TODO(teravest): Reduce code duplication below.
|
| body = '%s\n' % _MakeEnterLine(filenode, node, member, args[0],
|
| handle_errors, args[len(args) - 1][1], meta)
|
| - body += 'if (enter.failed())\n'
|
| value = member.GetProperty('on_failure')
|
| if value is None:
|
| value = 'enter.retval()'
|
| - body += ' return %s;\n' % value
|
| - body += 'return enter.SetResult(%s);' % invocation
|
| + if member.GetProperty('always_set_output_parameters'):
|
| + body += 'if (enter.failed()) {\n'
|
| + for param in out_params:
|
| + body += ' memset(%s, 0, sizeof(*%s));\n' % (param, param)
|
| + body += ' return %s;\n' % value
|
| + body += '}\n'
|
| + body += 'return enter.SetResult(%s);' % invocation
|
| + meta.AddBuiltinInclude('string.h')
|
| + else:
|
| + body += 'if (enter.failed())\n'
|
| + 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, member, args[0],
|
| handle_errors, None, meta)
|
| - if not out_params:
|
| - body += 'if (enter.succeeded())\n'
|
| - body += ' %s;' % invocation
|
| - else:
|
| + if member.GetProperty('always_set_output_parameters'):
|
| 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
|
| + body += '\nmemset(%s, 0, sizeof(*%s));' % (param, param)
|
| meta.AddBuiltinInclude('string.h')
|
| + else:
|
| + body += 'if (enter.succeeded())\n'
|
| + body += ' %s;' % invocation
|
|
|
| else:
|
| value = member.GetProperty('on_failure')
|
| @@ -299,9 +321,18 @@ def _MakeNormalMemberBody(filenode, release, node, member, rtype, args,
|
|
|
| body = '%s\n' % _MakeEnterLine(filenode, node, member, args[0],
|
| handle_errors, None, meta)
|
| - body += 'if (enter.failed())\n'
|
| - body += ' return %s;\n' % value
|
| - body += 'return %s;' % invocation
|
| + if member.GetProperty('always_set_output_parameters'):
|
| + body += 'if (enter.failed()) {\n'
|
| + for param in out_params:
|
| + body += ' memset(%s, 0, sizeof(*%s));\n' % (param, param)
|
| + body += ' return %s;\n' % value
|
| + body += '}\n'
|
| + body += 'return %s;' % invocation
|
| + meta.AddBuiltinInclude('string.h')
|
| + else:
|
| + body += 'if (enter.failed())\n'
|
| + body += ' return %s;\n' % value
|
| + body += 'return %s;' % invocation
|
| return body
|
|
|
|
|
|
|