OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """ Generator for C++ style thunks """ | 6 """ Generator for C++ style thunks """ |
7 | 7 |
8 import glob | 8 import glob |
9 import os | 9 import os |
10 import re | 10 import re |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 arg_list = ', '.join([a[1] for a in args]) | 207 arg_list = ', '.join([a[1] for a in args]) |
208 if member.GetProperty('create_func'): | 208 if member.GetProperty('create_func'): |
209 create_func = member.GetProperty('create_func') | 209 create_func = member.GetProperty('create_func') |
210 else: | 210 else: |
211 create_func = _GetCreateFuncName(interface) | 211 create_func = _GetCreateFuncName(interface) |
212 body += 'return enter.functions()->%s(%s);' % (create_func, | 212 body += 'return enter.functions()->%s(%s);' % (create_func, |
213 arg_list) | 213 arg_list) |
214 return body | 214 return body |
215 | 215 |
216 | 216 |
217 def _GetOutputParams(member, release): | |
218 """Returns output parameters (and their types) for a member function. | |
219 | |
220 Args: | |
221 member - IDLNode for the member function | |
222 release - Release to get output parameters for | |
223 Returns: | |
224 A list of name strings for all output parameters of the member | |
225 function. | |
226 """ | |
227 out_params = [] | |
228 callnode = member.GetOneOf('Callspec') | |
229 if callnode: | |
230 cgen = CGen() | |
231 for param in callnode.GetListOf('Param'): | |
232 mode = cgen.GetParamMode(param) | |
233 if mode == 'out': | |
234 # We use the 'store' mode when getting the parameter type, since we | |
235 # need to call sizeof() for memset(). | |
236 _, pname, _, _ = cgen.GetComponents(param, release, 'store') | |
237 out_params.append(pname) | |
238 return out_params | |
239 | |
240 | |
241 def _MakeNormalMemberBody(filenode, release, node, member, rtype, args, | 217 def _MakeNormalMemberBody(filenode, release, node, member, rtype, args, |
242 include_version, meta): | 218 include_version, meta): |
243 """Returns the body of a typical function. | 219 """Returns the body of a typical function. |
244 | 220 |
245 Args: | 221 Args: |
246 filenode - IDLNode for the file | 222 filenode - IDLNode for the file |
247 release - release to generate body for | 223 release - release to generate body for |
248 node - IDLNode for the interface | 224 node - IDLNode for the interface |
249 member - IDLNode for the member function | 225 member - IDLNode for the member function |
250 rtype - Return type for the member function | 226 rtype - Return type for the member function |
(...skipping 19 matching lines...) Expand all Loading... |
270 function_name = member.GetName() | 246 function_name = member.GetName() |
271 if include_version: | 247 if include_version: |
272 version = node.GetVersion(release).replace('.', '_') | 248 version = node.GetVersion(release).replace('.', '_') |
273 function_name += version | 249 function_name += version |
274 | 250 |
275 invocation = 'enter.%s()->%s(%s)' % (function_container, | 251 invocation = 'enter.%s()->%s(%s)' % (function_container, |
276 function_name, | 252 function_name, |
277 call_arglist) | 253 call_arglist) |
278 | 254 |
279 handle_errors = not (member.GetProperty('report_errors') == 'False') | 255 handle_errors = not (member.GetProperty('report_errors') == 'False') |
280 out_params = _GetOutputParams(member, release) | |
281 if is_callback_func: | 256 if is_callback_func: |
282 # TODO(teravest): Reduce code duplication below. | |
283 body = '%s\n' % _MakeEnterLine(filenode, node, member, args[0], | 257 body = '%s\n' % _MakeEnterLine(filenode, node, member, args[0], |
284 handle_errors, args[len(args) - 1][1], meta) | 258 handle_errors, args[len(args) - 1][1], meta) |
| 259 body += 'if (enter.failed())\n' |
285 value = member.GetProperty('on_failure') | 260 value = member.GetProperty('on_failure') |
286 if value is None: | 261 if value is None: |
287 value = 'enter.retval()' | 262 value = 'enter.retval()' |
288 if member.GetProperty('always_set_output_parameters'): | 263 body += ' return %s;\n' % value |
289 body += 'if (enter.failed()) {\n' | 264 body += 'return enter.SetResult(%s);' % invocation |
290 for param in out_params: | |
291 body += ' memset(%s, 0, sizeof(%s));\n' % (param, param) | |
292 body += ' return %s;\n' % value | |
293 body += '}\n' | |
294 body += 'return enter.SetResult(%s);' % invocation | |
295 meta.AddBuiltinInclude('string.h') | |
296 else: | |
297 body += 'if (enter.failed())\n' | |
298 body += ' return %s;\n' % value | |
299 body += 'return enter.SetResult(%s);' % invocation | |
300 elif rtype == 'void': | 265 elif rtype == 'void': |
| 266 # On failure, zero out all output parameters. |
| 267 out_params = [] |
| 268 callnode = member.GetOneOf('Callspec') |
| 269 if callnode: |
| 270 cgen = CGen() |
| 271 for param in callnode.GetListOf('Param'): |
| 272 mode = cgen.GetParamMode(param) |
| 273 if mode == 'out': |
| 274 # We use the 'store' mode when getting the parameter type, since we |
| 275 # need to call sizeof() for memset(). |
| 276 ptype, pname, _, _ = cgen.GetComponents(param, release, 'store') |
| 277 out_params.append((pname, ptype)) |
| 278 |
301 body = '%s\n' % _MakeEnterLine(filenode, node, member, args[0], | 279 body = '%s\n' % _MakeEnterLine(filenode, node, member, args[0], |
302 handle_errors, None, meta) | 280 handle_errors, None, meta) |
303 if member.GetProperty('always_set_output_parameters'): | 281 if not out_params: |
| 282 body += 'if (enter.succeeded())\n' |
| 283 body += ' %s;' % invocation |
| 284 else: |
304 body += 'if (enter.succeeded()) {\n' | 285 body += 'if (enter.succeeded()) {\n' |
305 body += ' %s;\n' % invocation | 286 body += ' %s;\n' % invocation |
306 body += ' return;\n' | 287 body += ' return;\n' |
307 body += '}' | 288 body += '}' |
308 for param in out_params: | 289 for param in out_params: |
309 body += '\nmemset(%s, 0, sizeof(%s));' % (param, param) | 290 body += '\nmemset(%s, 0, sizeof(%s));' % param |
310 meta.AddBuiltinInclude('string.h') | 291 meta.AddBuiltinInclude('string.h') |
311 else: | |
312 body += 'if (enter.succeeded())\n' | |
313 body += ' %s;' % invocation | |
314 | 292 |
315 else: | 293 else: |
316 value = member.GetProperty('on_failure') | 294 value = member.GetProperty('on_failure') |
317 if value is None: | 295 if value is None: |
318 value = _GetDefaultFailureValue(rtype) | 296 value = _GetDefaultFailureValue(rtype) |
319 if value is None: | 297 if value is None: |
320 raise TGenError('No default value for rtype %s' % rtype) | 298 raise TGenError('No default value for rtype %s' % rtype) |
321 | 299 |
322 body = '%s\n' % _MakeEnterLine(filenode, node, member, args[0], | 300 body = '%s\n' % _MakeEnterLine(filenode, node, member, args[0], |
323 handle_errors, None, meta) | 301 handle_errors, None, meta) |
324 if member.GetProperty('always_set_output_parameters'): | 302 body += 'if (enter.failed())\n' |
325 body += 'if (enter.failed()) {\n' | 303 body += ' return %s;\n' % value |
326 for param in out_params: | 304 body += 'return %s;' % invocation |
327 body += ' memset(%s, 0, sizeof(%s));\n' % (param, param) | |
328 body += ' return %s;\n' % value | |
329 body += '}\n' | |
330 body += 'return %s;' % invocation | |
331 meta.AddBuiltinInclude('string.h') | |
332 else: | |
333 body += 'if (enter.failed())\n' | |
334 body += ' return %s;\n' % value | |
335 body += 'return %s;' % invocation | |
336 return body | 305 return body |
337 | 306 |
338 | 307 |
339 def DefineMember(filenode, node, member, release, include_version, meta): | 308 def DefineMember(filenode, node, member, release, include_version, meta): |
340 """Returns a definition for a member function of an interface. | 309 """Returns a definition for a member function of an interface. |
341 | 310 |
342 Args: | 311 Args: |
343 filenode - IDLNode for the file | 312 filenode - IDLNode for the file |
344 node - IDLNode for the interface | 313 node - IDLNode for the interface |
345 member - IDLNode for the member function | 314 member - IDLNode for the member function |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
569 print "Golden file for M13-M14 failed." | 538 print "Golden file for M13-M14 failed." |
570 failed = 1 | 539 failed = 1 |
571 else: | 540 else: |
572 print "Golden file for M13-M14 passed." | 541 print "Golden file for M13-M14 passed." |
573 | 542 |
574 return failed | 543 return failed |
575 | 544 |
576 | 545 |
577 if __name__ == '__main__': | 546 if __name__ == '__main__': |
578 sys.exit(Main(sys.argv[1:])) | 547 sys.exit(Main(sys.argv[1:])) |
OLD | NEW |