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 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 arg_list = ', '.join([a[1] for a in args]) | 198 arg_list = ', '.join([a[1] for a in args]) |
199 if member.GetProperty('create_func'): | 199 if member.GetProperty('create_func'): |
200 create_func = member.GetProperty('create_func') | 200 create_func = member.GetProperty('create_func') |
201 else: | 201 else: |
202 create_func = _GetCreateFuncName(interface) | 202 create_func = _GetCreateFuncName(interface) |
203 body += 'return enter.functions()->%s(%s);' % (create_func, | 203 body += 'return enter.functions()->%s(%s);' % (create_func, |
204 arg_list) | 204 arg_list) |
205 return body | 205 return body |
206 | 206 |
207 | 207 |
| 208 def _GetOutputParams(member, release): |
| 209 """Returns output parameters (and their types) for a member function. |
| 210 |
| 211 Args: |
| 212 member - IDLNode for the member function |
| 213 release - Release to get output parameters for |
| 214 Returns: |
| 215 A list of (name, type) tuples for all output parameters of the member |
| 216 function. |
| 217 """ |
| 218 out_params = [] |
| 219 callnode = member.GetOneOf('Callspec') |
| 220 if callnode: |
| 221 cgen = CGen() |
| 222 for param in callnode.GetListOf('Param'): |
| 223 mode = cgen.GetParamMode(param) |
| 224 if mode == 'out': |
| 225 # We use the 'store' mode when getting the parameter type, since we |
| 226 # need to call sizeof() for memset(). |
| 227 ptype, pname, _, _ = cgen.GetComponents(param, release, 'store') |
| 228 out_params.append((pname, ptype)) |
| 229 return out_params |
| 230 |
| 231 |
208 def _MakeNormalMemberBody(filenode, release, node, member, rtype, args, | 232 def _MakeNormalMemberBody(filenode, release, node, member, rtype, args, |
209 include_version, meta): | 233 include_version, meta): |
210 """Returns the body of a typical function. | 234 """Returns the body of a typical function. |
211 | 235 |
212 Args: | 236 Args: |
213 filenode - IDLNode for the file | 237 filenode - IDLNode for the file |
214 release - release to generate body for | 238 release - release to generate body for |
215 node - IDLNode for the interface | 239 node - IDLNode for the interface |
216 member - IDLNode for the member function | 240 member - IDLNode for the member function |
217 rtype - Return type for the member function | 241 rtype - Return type for the member function |
(...skipping 19 matching lines...) Expand all Loading... |
237 function_name = member.GetName() | 261 function_name = member.GetName() |
238 if include_version: | 262 if include_version: |
239 version = node.GetVersion(release).replace('.', '_') | 263 version = node.GetVersion(release).replace('.', '_') |
240 function_name += version | 264 function_name += version |
241 | 265 |
242 invocation = 'enter.%s()->%s(%s)' % (function_container, | 266 invocation = 'enter.%s()->%s(%s)' % (function_container, |
243 function_name, | 267 function_name, |
244 call_arglist) | 268 call_arglist) |
245 | 269 |
246 handle_errors = not (member.GetProperty('report_errors') == 'False') | 270 handle_errors = not (member.GetProperty('report_errors') == 'False') |
| 271 out_params = _GetOutputParams(member, release) |
247 if is_callback_func: | 272 if is_callback_func: |
| 273 # TODO(teravest): Reduce code duplication below. |
248 body = '%s\n' % _MakeEnterLine(filenode, node, args[0], handle_errors, | 274 body = '%s\n' % _MakeEnterLine(filenode, node, args[0], handle_errors, |
249 args[len(args) - 1][1], meta) | 275 args[len(args) - 1][1], meta) |
250 body += 'if (enter.failed())\n' | |
251 value = member.GetProperty('on_failure') | 276 value = member.GetProperty('on_failure') |
252 if value is None: | 277 if value is None: |
253 value = 'enter.retval()' | 278 value = 'enter.retval()' |
254 body += ' return %s;\n' % value | 279 if member.GetProperty('always_set_output_parameters'): |
255 body += 'return enter.SetResult(%s);' % invocation | 280 body += 'if (enter.failed()) {\n' |
| 281 for param in out_params: |
| 282 body += ' memset(%s, 0, sizeof(%s));\n' % param |
| 283 body += ' return %s;\n' % value |
| 284 body += '}\n' |
| 285 body += 'return enter.SetResult(%s);' % invocation |
| 286 meta.AddBuiltinInclude('string.h') |
| 287 else: |
| 288 body += 'if (enter.failed())\n' |
| 289 body += ' return %s;\n' % value |
| 290 body += 'return enter.SetResult(%s);' % invocation |
256 elif rtype == 'void': | 291 elif rtype == 'void': |
257 # On failure, zero out all output parameters. | |
258 out_params = [] | |
259 callnode = member.GetOneOf('Callspec') | |
260 if callnode: | |
261 cgen = CGen() | |
262 for param in callnode.GetListOf('Param'): | |
263 mode = cgen.GetParamMode(param) | |
264 if mode == 'out': | |
265 # We use the 'store' mode when getting the parameter type, since we | |
266 # need to call sizeof() for memset(). | |
267 ptype, pname, _, _ = cgen.GetComponents(param, release, 'store') | |
268 out_params.append((pname, ptype)) | |
269 | |
270 body = '%s\n' % _MakeEnterLine(filenode, node, args[0], handle_errors, | 292 body = '%s\n' % _MakeEnterLine(filenode, node, args[0], handle_errors, |
271 None, meta) | 293 None, meta) |
272 if not out_params: | 294 if member.GetProperty('always_set_output_parameters'): |
273 body += 'if (enter.succeeded())\n' | |
274 body += ' %s;' % invocation | |
275 else: | |
276 body += 'if (enter.succeeded()) {\n' | 295 body += 'if (enter.succeeded()) {\n' |
277 body += ' %s;\n' % invocation | 296 body += ' %s;\n' % invocation |
278 body += ' return;\n' | 297 body += ' return;\n' |
279 body += '}' | 298 body += '}' |
280 for param in out_params: | 299 for param in out_params: |
281 body += '\nmemset(%s, 0, sizeof(%s));' % param | 300 body += '\nmemset(%s, 0, sizeof(%s));' % param |
282 meta.AddBuiltinInclude('string.h') | 301 meta.AddBuiltinInclude('string.h') |
| 302 else: |
| 303 body += 'if (enter.succeeded())\n' |
| 304 body += ' %s;' % invocation |
283 | 305 |
284 else: | 306 else: |
285 value = member.GetProperty('on_failure') | 307 value = member.GetProperty('on_failure') |
286 if value is None: | 308 if value is None: |
287 value = _GetDefaultFailureValue(rtype) | 309 value = _GetDefaultFailureValue(rtype) |
288 if value is None: | 310 if value is None: |
289 raise TGenError('No default value for rtype %s' % rtype) | 311 raise TGenError('No default value for rtype %s' % rtype) |
290 | 312 |
291 body = '%s\n' % _MakeEnterLine(filenode, node, args[0], handle_errors, | 313 body = '%s\n' % _MakeEnterLine(filenode, node, args[0], handle_errors, |
292 None, meta) | 314 None, meta) |
293 body += 'if (enter.failed())\n' | 315 if member.GetProperty('always_set_output_parameters'): |
294 body += ' return %s;\n' % value | 316 body += 'if (enter.failed()) {\n' |
295 body += 'return %s;' % invocation | 317 for param in out_params: |
| 318 body += ' memset(%s, 0, sizeof(%s));\n' % param |
| 319 body += ' return %s;\n' % value |
| 320 body += '}\n' |
| 321 body += 'return %s;' % invocation |
| 322 meta.AddBuiltinInclude('string.h') |
| 323 else: |
| 324 body += 'if (enter.failed())\n' |
| 325 body += ' return %s;\n' % value |
| 326 body += 'return %s;' % invocation |
296 return body | 327 return body |
297 | 328 |
298 | 329 |
299 def DefineMember(filenode, node, member, release, include_version, meta): | 330 def DefineMember(filenode, node, member, release, include_version, meta): |
300 """Returns a definition for a member function of an interface. | 331 """Returns a definition for a member function of an interface. |
301 | 332 |
302 Args: | 333 Args: |
303 filenode - IDLNode for the file | 334 filenode - IDLNode for the file |
304 node - IDLNode for the interface | 335 node - IDLNode for the interface |
305 member - IDLNode for the member function | 336 member - IDLNode for the member function |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
525 print "Golden file for M13-M14 failed." | 556 print "Golden file for M13-M14 failed." |
526 failed = 1 | 557 failed = 1 |
527 else: | 558 else: |
528 print "Golden file for M13-M14 passed." | 559 print "Golden file for M13-M14 passed." |
529 | 560 |
530 return failed | 561 return failed |
531 | 562 |
532 | 563 |
533 if __name__ == '__main__': | 564 if __name__ == '__main__': |
534 sys.exit(Main(sys.argv[1:])) | 565 sys.exit(Main(sys.argv[1:])) |
OLD | NEW |