15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#!/usr/bin/env python 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copyright (c) 2012 The Chromium Authors. All rights reserved. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# found in the LICENSE file. 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"""Generator for Pnacl Shim functions that bridges the calling conventions 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)between GCC and PNaCl. """ 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from datetime import datetime 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import difflib 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import glob 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import os 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import sys 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from idl_c_proto import CGen 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from idl_gen_wrapper import Interface, WrapperGen 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from idl_log import ErrOut, InfoOut, WarnOut 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from idl_option import GetOption, Option, ParseOptions 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from idl_parser import ParseFiles 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Option('pnaclshim', 'Name of the pnacl shim file.', 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default='temp_pnacl_shim.c') 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Option('disable_pnacl_opt', 'Turn off optimization of pnacl shim.') 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PnaclGen(WrapperGen): 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """PnaclGen generates shim code to bridge the Gcc ABI with PNaCl. 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) This subclass of WrapperGenerator takes the IDL sources and 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generates shim methods for bridging the calling conventions between GCC 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) and PNaCl (LLVM). Some of the PPAPI methods do not need shimming, so 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this will also detect those situations and provide direct access to the 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original PPAPI methods (rather than the shim methods). 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__(self): 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WrapperGen.__init__(self, 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Pnacl', 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Pnacl Shim Gen', 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'pnacl', 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Generate the PNaCl shim.') 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.cgen = CGen() 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._skip_opt = False 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ############################################################ 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def OwnHeaderFile(self): 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Return the header file that specifies the API of this wrapper. 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) We do not generate the header files. """ 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return 'ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.h' 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def InterfaceVersionNeedsWrapping(self, iface, version): 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Return true if the interface+version has ANY methods that 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) need wrapping. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self._skip_opt: 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return True 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if iface.GetName().endswith('Trusted'): 61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return False 6246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) # TODO(dmichael): We have no way to wrap PPP_ interfaces without an 6346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) # interface string. If any ever need wrapping, we'll need to figure out a 6446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) # way to get the plugin-side of the Pepper proxy (within the IRT) to access 6546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) # and use the wrapper. 6646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if iface.GetProperty("no_interface_string"): 6746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return False 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for member in iface.GetListOf('Member'): 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) release = member.GetRelease(version) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.MemberNeedsWrapping(member, release): 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return True 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return False 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def MemberNeedsWrapping(self, member, release): 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Return true if a particular member function at a particular 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) release needs wrapping. 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self._skip_opt: 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return True 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not member.InReleases([release]): 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return False 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret, name, array, args_spec = self.cgen.GetComponents(member, 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) release, 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'store') 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.TypeNeedsWrapping(ret, []) or self.ArgsNeedWrapping(args_spec) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def ArgsNeedWrapping(self, args): 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Return true if any parameter in the list needs wrapping. 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for arg in args: 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type_str, name, array_dims, more_args) = arg 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.TypeNeedsWrapping(type_str, array_dims): 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return True 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return False 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def TypeNeedsWrapping(self, type_node, array_dims): 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Return true if a parameter type needs wrapping. 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Currently, this is true for byval aggregates. 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_aggregate = type_node.startswith('struct') or \ 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type_node.startswith('union') 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_reference = (type_node.find('*') != -1 or array_dims != []) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return is_aggregate and not is_reference 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ############################################################ 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) def ConvertByValueReturnType(self, ret, args_spec): 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if self.TypeNeedsWrapping(ret, array_dims=[]): 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) args_spec = [(ret, '_struct_result', [], None)] + args_spec 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret2 = 'void' 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) wrap_return = True 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else: 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret2 = ret 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) wrap_return = False 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return wrap_return, ret2, args_spec 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) def ConvertByValueArguments(self, args_spec): 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) args = [] 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for type_str, name, array_dims, more_args in args_spec: 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if self.TypeNeedsWrapping(type_str, array_dims): 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) type_str += '*' 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) args.append((type_str, name, array_dims, more_args)) 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return args 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) def FormatArgs(self, c_operator, args_spec): 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) args = [] 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for type_str, name, array_dims, more_args in args_spec: 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if self.TypeNeedsWrapping(type_str, array_dims): 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) args.append(c_operator + name) 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else: 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) args.append(name) 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return ', '.join(args) 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def GenerateWrapperForPPBMethod(self, iface, member): 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = [] 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) func_prefix = self.WrapperMethodPrefix(iface.node, iface.release) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret, name, array, cspec = self.cgen.GetComponents(member, 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iface.release, 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'store') 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) wrap_return, ret2, cspec2 = self.ConvertByValueReturnType(ret, cspec) 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cspec2 = self.ConvertByValueArguments(cspec2) 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) sig = self.cgen.Compose(ret2, name, array, cspec2, 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) prefix=func_prefix, 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) func_as_ptr=False, 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) include_name=True, 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsized_as_ptr=False) 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result.append('static %s {\n' % sig) 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result.append(' const struct %s *iface = %s.real_iface;\n' % 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (iface.struct_name, self.GetWrapperInfoName(iface))) 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return_prefix = '' 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if wrap_return: 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return_prefix = '*_struct_result = ' 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) elif ret != 'void': 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return_prefix = 'return ' 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result.append(' %siface->%s(%s);\n}\n\n' % (return_prefix, 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) member.GetName(), 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) self.FormatArgs('*', cspec))) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def GenerateWrapperForPPPMethod(self, iface, member): 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = [] 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) func_prefix = self.WrapperMethodPrefix(iface.node, iface.release) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sig = self.cgen.GetSignature(member, iface.release, 'store', 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) func_prefix, False) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.append('static %s {\n' % sig) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.append(' const struct %s *iface = %s.real_iface;\n' % 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (iface.struct_name, self.GetWrapperInfoName(iface))) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret, name, array, cspec = self.cgen.GetComponents(member, 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iface.release, 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'store') 181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) wrap_return, ret2, cspec = self.ConvertByValueReturnType(ret, cspec) 182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cspec2 = self.ConvertByValueArguments(cspec) 183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) temp_fp = self.cgen.Compose(ret2, name, array, cspec2, 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) prefix='temp_fp', 185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) func_as_ptr=True, 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) include_name=False, 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsized_as_ptr=False) 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cast = self.cgen.Compose(ret2, name, array, cspec2, 189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) prefix='', 190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) func_as_ptr=True, 191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) include_name=False, 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsized_as_ptr=False) 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result.append(' %s =\n ((%s)iface->%s);\n' % (temp_fp, 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cast, 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) member.GetName())) 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return_prefix = '' 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if wrap_return: 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result.append(' %s _struct_result;\n' % ret) 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) elif ret != 'void': 200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return_prefix = 'return ' 201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result.append(' %stemp_fp(%s);\n' % (return_prefix, 203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) self.FormatArgs('&', cspec))) 204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if wrap_return: 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result.append(' return _struct_result;\n') 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result.append('}\n\n') 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def GenerateRange(self, ast, releases, options): 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Generate shim code for a range of releases. 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._skip_opt = GetOption('disable_pnacl_opt') 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.SetOutputFile(GetOption('pnaclshim')) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WrapperGen.GenerateRange(self, ast, releases, options) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)pnaclgen = PnaclGen() 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)###################################################################### 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Tests. 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Clean a string representing an object definition and return then string 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# as a single space delimited set of tokens. 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def CleanString(instr): 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instr = instr.strip() 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instr = instr.split() 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ' '.join(instr) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def PrintErrorDiff(old, new): 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) oldlines = old.split(';') 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newlines = new.split(';') 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) d = difflib.Differ() 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) diff = d.compare(oldlines, newlines) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrOut.Log('Diff is:\n%s' % '\n'.join(diff)) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def GetOldTestOutput(ast): 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Scan the top-level comments in the IDL file for comparison. 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old = [] 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for filenode in ast.GetListOf('File'): 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for node in filenode.GetChildren(): 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instr = node.GetOneOf('Comment') 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not instr: continue 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instr.Dump() 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old.append(instr.GetName()) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CleanString(''.join(old)) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def TestFiles(filenames, test_releases): 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ast = ParseFiles(filenames) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iface_releases = pnaclgen.DetermineInterfaces(ast, test_releases) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_output = CleanString(pnaclgen.GenerateWrapperForMethods( 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iface_releases, comments=False)) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old_output = GetOldTestOutput(ast) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if new_output != old_output: 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintErrorDiff(old_output, new_output) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrOut.Log('Failed pnacl generator test.') 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InfoOut.Log('Passed pnacl generator test.') 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def Main(args): 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filenames = ParseOptions(args) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_releases = ['M13', 'M14', 'M15'] 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not filenames: 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idldir = os.path.split(sys.argv[0])[0] 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idldir = os.path.join(idldir, 'test_gen_pnacl', '*.idl') 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filenames = glob.glob(idldir) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filenames = sorted(filenames) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if GetOption('test'): 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Run the tests. 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TestFiles(filenames, test_releases) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Otherwise, generate the output file (for potential use as golden file). 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ast = ParseFiles(filenames) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pnaclgen.GenerateRange(ast, test_releases, filenames) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if __name__ == '__main__': 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) retval = Main(sys.argv[1:]) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sys.exit(retval) 285