| 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 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 """Adds an API header for the given file to the ThunkBodyMetadata.""" | 94 """Adds an API header for the given file to the ThunkBodyMetadata.""" |
| 95 # The API header matches the file name, not the interface name. | 95 # The API header matches the file name, not the interface name. |
| 96 api_basename = _GetBaseFileName(filenode) | 96 api_basename = _GetBaseFileName(filenode) |
| 97 if api_basename.endswith('_dev'): | 97 if api_basename.endswith('_dev'): |
| 98 api_basename = api_basename[:-len('_dev')] | 98 api_basename = api_basename[:-len('_dev')] |
| 99 if api_basename.endswith('_trusted'): | 99 if api_basename.endswith('_trusted'): |
| 100 api_basename = api_basename[:-len('_trusted')] | 100 api_basename = api_basename[:-len('_trusted')] |
| 101 meta.AddApi(api_basename + '_api') | 101 meta.AddApi(api_basename + '_api') |
| 102 | 102 |
| 103 | 103 |
| 104 def _MakeEnterLine(filenode, interface, arg, handle_errors, callback, meta): | 104 def _MakeEnterLine(filenode, interface, member, arg, handle_errors, callback, |
| 105 meta): |
| 105 """Returns an EnterInstance/EnterResource string for a function.""" | 106 """Returns an EnterInstance/EnterResource string for a function.""" |
| 106 api_name = interface.GetName() | 107 api_name = interface.GetName() |
| 107 if api_name.endswith('Trusted'): | 108 if api_name.endswith('Trusted'): |
| 108 api_name = api_name[:-len('Trusted')] | 109 api_name = api_name[:-len('Trusted')] |
| 109 if api_name.endswith('_Dev'): | 110 if api_name.endswith('_Dev'): |
| 110 api_name = api_name[:-len('_Dev')] | 111 api_name = api_name[:-len('_Dev')] |
| 111 api_name += '_API' | 112 api_name += '_API' |
| 113 if member.GetProperty('api'): # Override API name. |
| 114 manually_provided_api = True |
| 115 # TODO(teravest): Automatically guess the API header file. |
| 116 api_name = member.GetProperty('api') |
| 117 else: |
| 118 manually_provided_api = False |
| 112 | 119 |
| 113 if arg[0] == 'PP_Instance': | 120 if arg[0] == 'PP_Instance': |
| 114 if callback is None: | 121 if callback is None: |
| 115 arg_string = arg[1] | 122 arg_string = arg[1] |
| 116 else: | 123 else: |
| 117 arg_string = '%s, %s' % (arg[1], callback) | 124 arg_string = '%s, %s' % (arg[1], callback) |
| 118 if interface.GetProperty('singleton_resource'): | 125 if member.GetProperty('singleton'): |
| 119 _AddApiHeader(filenode, meta) | 126 if not manually_provided_api: |
| 127 _AddApiHeader(filenode, meta) |
| 120 return 'EnterInstanceAPI<%s> enter(%s);' % (api_name, arg_string) | 128 return 'EnterInstanceAPI<%s> enter(%s);' % (api_name, arg_string) |
| 121 else: | 129 else: |
| 122 return 'EnterInstance enter(%s);' % arg_string | 130 return 'EnterInstance enter(%s);' % arg_string |
| 123 elif arg[0] == 'PP_Resource': | 131 elif arg[0] == 'PP_Resource': |
| 124 enter_type = 'EnterResource<%s>' % api_name | 132 enter_type = 'EnterResource<%s>' % api_name |
| 125 _AddApiHeader(filenode, meta) | 133 if not manually_provided_api: |
| 134 _AddApiHeader(filenode, meta) |
| 126 if callback is None: | 135 if callback is None: |
| 127 return '%s enter(%s, %s);' % (enter_type, arg[1], | 136 return '%s enter(%s, %s);' % (enter_type, arg[1], |
| 128 str(handle_errors).lower()) | 137 str(handle_errors).lower()) |
| 129 else: | 138 else: |
| 130 return '%s enter(%s, %s, %s);' % (enter_type, arg[1], | 139 return '%s enter(%s, %s, %s);' % (enter_type, arg[1], |
| 131 callback, | 140 callback, |
| 132 str(handle_errors).lower()) | 141 str(handle_errors).lower()) |
| 133 else: | 142 else: |
| 134 raise TGenError("Unknown type for _MakeEnterLine: %s" % arg[0]) | 143 raise TGenError("Unknown type for _MakeEnterLine: %s" % arg[0]) |
| 135 | 144 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 if include_version: | 247 if include_version: |
| 239 version = node.GetVersion(release).replace('.', '_') | 248 version = node.GetVersion(release).replace('.', '_') |
| 240 function_name += version | 249 function_name += version |
| 241 | 250 |
| 242 invocation = 'enter.%s()->%s(%s)' % (function_container, | 251 invocation = 'enter.%s()->%s(%s)' % (function_container, |
| 243 function_name, | 252 function_name, |
| 244 call_arglist) | 253 call_arglist) |
| 245 | 254 |
| 246 handle_errors = not (member.GetProperty('report_errors') == 'False') | 255 handle_errors = not (member.GetProperty('report_errors') == 'False') |
| 247 if is_callback_func: | 256 if is_callback_func: |
| 248 body = '%s\n' % _MakeEnterLine(filenode, node, args[0], handle_errors, | 257 body = '%s\n' % _MakeEnterLine(filenode, node, member, args[0], |
| 249 args[len(args) - 1][1], meta) | 258 handle_errors, args[len(args) - 1][1], meta) |
| 250 body += 'if (enter.failed())\n' | 259 body += 'if (enter.failed())\n' |
| 251 value = member.GetProperty('on_failure') | 260 value = member.GetProperty('on_failure') |
| 252 if value is None: | 261 if value is None: |
| 253 value = 'enter.retval()' | 262 value = 'enter.retval()' |
| 254 body += ' return %s;\n' % value | 263 body += ' return %s;\n' % value |
| 255 body += 'return enter.SetResult(%s);' % invocation | 264 body += 'return enter.SetResult(%s);' % invocation |
| 256 elif rtype == 'void': | 265 elif rtype == 'void': |
| 257 # On failure, zero out all output parameters. | 266 # On failure, zero out all output parameters. |
| 258 out_params = [] | 267 out_params = [] |
| 259 callnode = member.GetOneOf('Callspec') | 268 callnode = member.GetOneOf('Callspec') |
| 260 if callnode: | 269 if callnode: |
| 261 cgen = CGen() | 270 cgen = CGen() |
| 262 for param in callnode.GetListOf('Param'): | 271 for param in callnode.GetListOf('Param'): |
| 263 mode = cgen.GetParamMode(param) | 272 mode = cgen.GetParamMode(param) |
| 264 if mode == 'out': | 273 if mode == 'out': |
| 265 # We use the 'store' mode when getting the parameter type, since we | 274 # We use the 'store' mode when getting the parameter type, since we |
| 266 # need to call sizeof() for memset(). | 275 # need to call sizeof() for memset(). |
| 267 ptype, pname, _, _ = cgen.GetComponents(param, release, 'store') | 276 ptype, pname, _, _ = cgen.GetComponents(param, release, 'store') |
| 268 out_params.append((pname, ptype)) | 277 out_params.append((pname, ptype)) |
| 269 | 278 |
| 270 body = '%s\n' % _MakeEnterLine(filenode, node, args[0], handle_errors, | 279 body = '%s\n' % _MakeEnterLine(filenode, node, member, args[0], |
| 271 None, meta) | 280 handle_errors, None, meta) |
| 272 if not out_params: | 281 if not out_params: |
| 273 body += 'if (enter.succeeded())\n' | 282 body += 'if (enter.succeeded())\n' |
| 274 body += ' %s;' % invocation | 283 body += ' %s;' % invocation |
| 275 else: | 284 else: |
| 276 body += 'if (enter.succeeded()) {\n' | 285 body += 'if (enter.succeeded()) {\n' |
| 277 body += ' %s;\n' % invocation | 286 body += ' %s;\n' % invocation |
| 278 body += ' return;\n' | 287 body += ' return;\n' |
| 279 body += '}' | 288 body += '}' |
| 280 for param in out_params: | 289 for param in out_params: |
| 281 body += '\nmemset(%s, 0, sizeof(%s));' % param | 290 body += '\nmemset(%s, 0, sizeof(%s));' % param |
| 282 meta.AddBuiltinInclude('string.h') | 291 meta.AddBuiltinInclude('string.h') |
| 283 | 292 |
| 284 else: | 293 else: |
| 285 value = member.GetProperty('on_failure') | 294 value = member.GetProperty('on_failure') |
| 286 if value is None: | 295 if value is None: |
| 287 value = _GetDefaultFailureValue(rtype) | 296 value = _GetDefaultFailureValue(rtype) |
| 288 if value is None: | 297 if value is None: |
| 289 raise TGenError('No default value for rtype %s' % rtype) | 298 raise TGenError('No default value for rtype %s' % rtype) |
| 290 | 299 |
| 291 body = '%s\n' % _MakeEnterLine(filenode, node, args[0], handle_errors, | 300 body = '%s\n' % _MakeEnterLine(filenode, node, member, args[0], |
| 292 None, meta) | 301 handle_errors, None, meta) |
| 293 body += 'if (enter.failed())\n' | 302 body += 'if (enter.failed())\n' |
| 294 body += ' return %s;\n' % value | 303 body += ' return %s;\n' % value |
| 295 body += 'return %s;' % invocation | 304 body += 'return %s;' % invocation |
| 296 return body | 305 return body |
| 297 | 306 |
| 298 | 307 |
| 299 def DefineMember(filenode, node, member, release, include_version, meta): | 308 def DefineMember(filenode, node, member, release, include_version, meta): |
| 300 """Returns a definition for a member function of an interface. | 309 """Returns a definition for a member function of an interface. |
| 301 | 310 |
| 302 Args: | 311 Args: |
| 303 filenode - IDLNode for the file | 312 filenode - IDLNode for the file |
| 304 node - IDLNode for the interface | 313 node - IDLNode for the interface |
| 305 member - IDLNode for the member function | 314 member - IDLNode for the member function |
| 306 release - release to generate | 315 release - release to generate |
| 307 include_version - include the version in emitted function name. | 316 include_version - include the version in emitted function name. |
| 308 meta - ThunkMetadata for header hints | 317 meta - ThunkMetadata for header hints |
| 309 Returns: | 318 Returns: |
| 310 A string with the member definition. | 319 A string with the member definition. |
| 311 """ | 320 """ |
| 312 cgen = CGen() | 321 cgen = CGen() |
| 313 rtype, name, arrays, args = cgen.GetComponents(member, release, 'return') | 322 rtype, name, arrays, args = cgen.GetComponents(member, release, 'return') |
| 314 | 323 |
| 315 if _IsTypeCheck(node, member): | 324 if _IsTypeCheck(node, member) or member.GetProperty('is_function'): |
| 316 body = '%s\n' % _MakeEnterLine(filenode, node, args[0], False, None, meta) | 325 body = '%s\n' % _MakeEnterLine(filenode, node, member, args[0], False, None, |
| 326 meta) |
| 317 body += 'return PP_FromBool(enter.succeeded());' | 327 body += 'return PP_FromBool(enter.succeeded());' |
| 318 elif member.GetName() == 'Create': | 328 elif member.GetName() == 'Create': |
| 319 body = _MakeCreateMemberBody(node, member, args) | 329 body = _MakeCreateMemberBody(node, member, args) |
| 320 else: | 330 else: |
| 321 body = _MakeNormalMemberBody(filenode, release, node, member, rtype, args, | 331 body = _MakeNormalMemberBody(filenode, release, node, member, rtype, args, |
| 322 include_version, meta) | 332 include_version, meta) |
| 323 | 333 |
| 324 signature = cgen.GetSignature(member, release, 'return', func_as_ptr=False, | 334 signature = cgen.GetSignature(member, release, 'return', func_as_ptr=False, |
| 325 include_version=include_version) | 335 include_version=include_version) |
| 326 return '%s\n%s\n}' % (cgen.Indent('%s {' % signature, tabs=0), | 336 return '%s\n%s\n}' % (cgen.Indent('%s {' % signature, tabs=0), |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 if os.path.isfile(savename): | 377 if os.path.isfile(savename): |
| 368 print "Removing stale %s for this range." % filenode.GetName() | 378 print "Removing stale %s for this range." % filenode.GetName() |
| 369 os.remove(os.path.realpath(savename)) | 379 os.remove(os.path.realpath(savename)) |
| 370 return False | 380 return False |
| 371 do_generate = filenode.GetProperty('generate_thunk') | 381 do_generate = filenode.GetProperty('generate_thunk') |
| 372 if not do_generate: | 382 if not do_generate: |
| 373 return False | 383 return False |
| 374 | 384 |
| 375 thunk_out = IDLOutFile(savename) | 385 thunk_out = IDLOutFile(savename) |
| 376 body, meta = self.GenerateBody(thunk_out, filenode, releases, options) | 386 body, meta = self.GenerateBody(thunk_out, filenode, releases, options) |
| 387 # TODO(teravest): How do we handle repeated values? |
| 388 if filenode.GetProperty('thunk_include'): |
| 389 meta.AddInclude(filenode.GetProperty('thunk_include')) |
| 377 self.WriteHead(thunk_out, filenode, releases, options, meta) | 390 self.WriteHead(thunk_out, filenode, releases, options, meta) |
| 378 thunk_out.Write('\n\n'.join(body)) | 391 thunk_out.Write('\n\n'.join(body)) |
| 379 self.WriteTail(thunk_out, filenode, releases, options) | 392 self.WriteTail(thunk_out, filenode, releases, options) |
| 380 return thunk_out.Close() | 393 return thunk_out.Close() |
| 381 | 394 |
| 382 def WriteHead(self, out, filenode, releases, options, meta): | 395 def WriteHead(self, out, filenode, releases, options, meta): |
| 383 __pychecker__ = 'unusednames=options' | 396 __pychecker__ = 'unusednames=options' |
| 384 cgen = CGen() | 397 cgen = CGen() |
| 385 | 398 |
| 386 cright_node = filenode.GetChildren()[0] | 399 cright_node = filenode.GetChildren()[0] |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 524 print "Golden file for M13-M14 failed." | 537 print "Golden file for M13-M14 failed." |
| 525 failed = 1 | 538 failed = 1 |
| 526 else: | 539 else: |
| 527 print "Golden file for M13-M14 passed." | 540 print "Golden file for M13-M14 passed." |
| 528 | 541 |
| 529 return failed | 542 return failed |
| 530 | 543 |
| 531 | 544 |
| 532 if __name__ == '__main__': | 545 if __name__ == '__main__': |
| 533 sys.exit(Main(sys.argv[1:])) | 546 sys.exit(Main(sys.argv[1:])) |
| OLD | NEW |