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 |
217 def _MakeNormalMemberBody(filenode, release, node, member, rtype, args, | 241 def _MakeNormalMemberBody(filenode, release, node, member, rtype, args, |
218 include_version, meta): | 242 include_version, meta): |
219 """Returns the body of a typical function. | 243 """Returns the body of a typical function. |
220 | 244 |
221 Args: | 245 Args: |
222 filenode - IDLNode for the file | 246 filenode - IDLNode for the file |
223 release - release to generate body for | 247 release - release to generate body for |
224 node - IDLNode for the interface | 248 node - IDLNode for the interface |
225 member - IDLNode for the member function | 249 member - IDLNode for the member function |
226 rtype - Return type for the member function | 250 rtype - Return type for the member function |
(...skipping 19 matching lines...) Expand all Loading... |
246 function_name = member.GetName() | 270 function_name = member.GetName() |
247 if include_version: | 271 if include_version: |
248 version = node.GetVersion(release).replace('.', '_') | 272 version = node.GetVersion(release).replace('.', '_') |
249 function_name += version | 273 function_name += version |
250 | 274 |
251 invocation = 'enter.%s()->%s(%s)' % (function_container, | 275 invocation = 'enter.%s()->%s(%s)' % (function_container, |
252 function_name, | 276 function_name, |
253 call_arglist) | 277 call_arglist) |
254 | 278 |
255 handle_errors = not (member.GetProperty('report_errors') == 'False') | 279 handle_errors = not (member.GetProperty('report_errors') == 'False') |
| 280 out_params = _GetOutputParams(member, release) |
256 if is_callback_func: | 281 if is_callback_func: |
| 282 # TODO(teravest): Reduce code duplication below. |
257 body = '%s\n' % _MakeEnterLine(filenode, node, member, args[0], | 283 body = '%s\n' % _MakeEnterLine(filenode, node, member, args[0], |
258 handle_errors, args[len(args) - 1][1], meta) | 284 handle_errors, args[len(args) - 1][1], meta) |
259 body += 'if (enter.failed())\n' | |
260 value = member.GetProperty('on_failure') | 285 value = member.GetProperty('on_failure') |
261 if value is None: | 286 if value is None: |
262 value = 'enter.retval()' | 287 value = 'enter.retval()' |
263 body += ' return %s;\n' % value | 288 if member.GetProperty('always_set_output_parameters'): |
264 body += 'return enter.SetResult(%s);' % invocation | 289 body += 'if (enter.failed()) {\n' |
| 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 |
265 elif rtype == 'void': | 300 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 | |
279 body = '%s\n' % _MakeEnterLine(filenode, node, member, args[0], | 301 body = '%s\n' % _MakeEnterLine(filenode, node, member, args[0], |
280 handle_errors, None, meta) | 302 handle_errors, None, meta) |
281 if not out_params: | 303 if member.GetProperty('always_set_output_parameters'): |
282 body += 'if (enter.succeeded())\n' | |
283 body += ' %s;' % invocation | |
284 else: | |
285 body += 'if (enter.succeeded()) {\n' | 304 body += 'if (enter.succeeded()) {\n' |
286 body += ' %s;\n' % invocation | 305 body += ' %s;\n' % invocation |
287 body += ' return;\n' | 306 body += ' return;\n' |
288 body += '}' | 307 body += '}' |
289 for param in out_params: | 308 for param in out_params: |
290 body += '\nmemset(%s, 0, sizeof(%s));' % param | 309 body += '\nmemset(%s, 0, sizeof(*%s));' % (param, param) |
291 meta.AddBuiltinInclude('string.h') | 310 meta.AddBuiltinInclude('string.h') |
| 311 else: |
| 312 body += 'if (enter.succeeded())\n' |
| 313 body += ' %s;' % invocation |
292 | 314 |
293 else: | 315 else: |
294 value = member.GetProperty('on_failure') | 316 value = member.GetProperty('on_failure') |
295 if value is None: | 317 if value is None: |
296 value = _GetDefaultFailureValue(rtype) | 318 value = _GetDefaultFailureValue(rtype) |
297 if value is None: | 319 if value is None: |
298 raise TGenError('No default value for rtype %s' % rtype) | 320 raise TGenError('No default value for rtype %s' % rtype) |
299 | 321 |
300 body = '%s\n' % _MakeEnterLine(filenode, node, member, args[0], | 322 body = '%s\n' % _MakeEnterLine(filenode, node, member, args[0], |
301 handle_errors, None, meta) | 323 handle_errors, None, meta) |
302 body += 'if (enter.failed())\n' | 324 if member.GetProperty('always_set_output_parameters'): |
303 body += ' return %s;\n' % value | 325 body += 'if (enter.failed()) {\n' |
304 body += 'return %s;' % invocation | 326 for param in out_params: |
| 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 |
305 return body | 336 return body |
306 | 337 |
307 | 338 |
308 def DefineMember(filenode, node, member, release, include_version, meta): | 339 def DefineMember(filenode, node, member, release, include_version, meta): |
309 """Returns a definition for a member function of an interface. | 340 """Returns a definition for a member function of an interface. |
310 | 341 |
311 Args: | 342 Args: |
312 filenode - IDLNode for the file | 343 filenode - IDLNode for the file |
313 node - IDLNode for the interface | 344 node - IDLNode for the interface |
314 member - IDLNode for the member function | 345 member - IDLNode for the member function |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
538 print "Golden file for M13-M14 failed." | 569 print "Golden file for M13-M14 failed." |
539 failed = 1 | 570 failed = 1 |
540 else: | 571 else: |
541 print "Golden file for M13-M14 passed." | 572 print "Golden file for M13-M14 passed." |
542 | 573 |
543 return failed | 574 return failed |
544 | 575 |
545 | 576 |
546 if __name__ == '__main__': | 577 if __name__ == '__main__': |
547 sys.exit(Main(sys.argv[1:])) | 578 sys.exit(Main(sys.argv[1:])) |
OLD | NEW |