def CheckTypedefs(filenode, releases): """Checks that typedefs don't specify callbacks that take some structs. See http://crbug.com/233439 for details. """ cgen = CGen() # TODO(teravest): Fix the following callback to pass PP_Var by pointer # instead of by value. node_whitelist = ['PP_Ext_Alarms_OnAlarm_Func_Dev_0_1'] for node in filenode.GetListOf('Typedef'): if node.GetName() in node_whitelist: continue build_list = node.GetUniqueReleases(releases) callnode = node.GetOneOf('Callspec') if callnode: for param in callnode.GetListOf('Param'): if param.GetListOf('Array'): continue if cgen.GetParamMode(param) != 'in': continue t = param.GetType(build_list[0]) while t.IsA('Typedef'): t = t.GetType(build_list[0]) if t.IsA('Struct'): raise Exception('%s is a struct in callback %s. ' 'See http://crbug.com/233439' % (t.GetName(), node.GetName()))
def DefineMember(filenode, node, member, release, include_version, meta): """Returns a definition for a member function of an interface. Args: filenode - IDLNode for the file node - IDLNode for the interface member - IDLNode for the member function release - release to generate include_version - include the version in emitted function name. meta - ThunkMetadata for header hints Returns: A string with the member definition. """ cgen = CGen() rtype, name, arrays, args = cgen.GetComponents(member, release, 'return') if _IsTypeCheck(node, member): body = ' %s\n' % _MakeEnterLine(filenode, node, args[0], False, None, meta) body += ' return PP_FromBool(enter.succeeded());' elif member.GetName() == 'Create': body = _MakeCreateMemberBody(node, member, args) else: body = _MakeNormalMemberBody(filenode, node, member, rtype, args, meta) signature = cgen.GetSignature(member, release, 'return', func_as_ptr=False, include_version=include_version) member_code = '%s {\n%s\n}' % (signature, body) return cgen.Indent(member_code, tabs=0)
def __init__(self): WrapperGen.__init__(self, 'Pnacl', 'Pnacl Shim Gen', 'pnacl', 'Generate the PNaCl shim.') self.cgen = CGen() self._skip_opt = False
def __init__(self): WrapperGen.__init__(self, 'Pnacl', 'Pnacl Shim Gen', 'pnacl', 'Generate the PNaCl shim.') self.cgen = CGen() self._skip_opt = False self._pnacl_attribute = '__attribute__((pnaclcall))'
def GenerateHeader(out, filenode, releases): cgen = CGen() pref = '' do_comments = True # Generate definitions. last_group = None top_types = ['Typedef', 'Interface', 'Struct', 'Enum', 'Inline'] for node in filenode.GetListOf(*top_types): # Skip if this node is not in this release if not node.InReleases(releases): print "Skiping %s" % node continue # End/Start group marker if do_comments: last_group = WriteGroupMarker(out, node, last_group) if node.IsA('Inline'): item = node.GetProperty('VALUE') # If 'C++' use __cplusplus wrapper if node.GetName() == 'cc': item = '#ifdef __cplusplus\n%s\n#endif /* __cplusplus */\n\n' % item # If not C++ or C, then skip it elif not node.GetName() == 'c': continue if item: out.Write(item) continue # # Otherwise we are defining a file level object, so generate the # correct document notation. # item = cgen.Define(node, releases, prefix=pref, comment=True) if not item: continue asize = node.GetProperty('assert_size()') if asize: name = '%s%s' % (pref, node.GetName()) if node.IsA('Struct'): form = 'PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(%s, %s);\n' elif node.IsA('Enum'): if node.GetProperty('notypedef'): form = 'PP_COMPILE_ASSERT_ENUM_SIZE_IN_BYTES(%s, %s);\n' else: form = 'PP_COMPILE_ASSERT_SIZE_IN_BYTES(%s, %s);\n' else: form = 'PP_COMPILE_ASSERT_SIZE_IN_BYTES(%s, %s);\n' item += form % (name, asize[0]) if item: out.Write(item) if last_group: out.Write(CommentLines(['*', ' @}', '']) + '\n')
def WriteTail(self, out, filenode, releases, options): __pychecker__ = 'unusednames=options' cgen = CGen() version_list = [] out.Write('\n\n') for node in filenode.GetListOf('Interface'): build_list = node.GetUniqueReleases(releases) for build in build_list: version = node.GetVersion(build).replace('.', '_') thunk_name = 'g_' + node.GetName().lower() + '_thunk_' + \ version thunk_type = '_'.join((node.GetName(), version)) version_list.append((thunk_type, thunk_name)) declare_line = 'const %s %s = {' % (thunk_type, thunk_name) if len(declare_line) > 80: declare_line = 'const %s\n %s = {' % (thunk_type, thunk_name) out.Write('%s\n' % declare_line) generated_functions = [] members = node.GetListOf('Member') for child in members: rtype, name, arrays, args = cgen.GetComponents( child, build, 'return') if child.InReleases([build]): if not _IsNewestMember(child, members, releases): version = child.GetVersion( child.first_release[build]).replace('.', '_') name += '_' + version generated_functions.append(name) out.Write(',\n'.join( [' &%s' % f for f in generated_functions])) out.Write('\n};\n\n') out.Write('} // namespace\n') out.Write('\n') for thunk_type, thunk_name in version_list: thunk_decl = ('PPAPI_THUNK_EXPORT const %s* Get%s_Thunk() {\n' % (thunk_type, thunk_type)) if len(thunk_decl) > 80: thunk_decl = ( 'PPAPI_THUNK_EXPORT const %s*\n Get%s_Thunk() {\n' % (thunk_type, thunk_type)) out.Write(thunk_decl) out.Write(' return &%s;\n' % thunk_name) out.Write('}\n') out.Write('\n') out.Write('} // namespace thunk\n') out.Write('} // namespace ppapi\n')
def WriteHead(self, out, filenode, releases, options, meta): __pychecker__ = 'unusednames=options' cgen = CGen() cright_node = filenode.GetChildren()[0] assert(cright_node.IsA('Copyright')) out.Write('%s\n' % cgen.Copyright(cright_node, cpp_style=True)) # Wrap the From ... modified ... comment if it would be >80 characters. from_text = 'From %s' % ( filenode.GetProperty('NAME').replace(os.sep,'/')) modified_text = 'modified %s.' % ( filenode.GetProperty('DATETIME')) if len(from_text) + len(modified_text) < 74: out.Write('// %s %s\n\n' % (from_text, modified_text)) else: out.Write('// %s,\n// %s\n\n' % (from_text, modified_text)) if meta.BuiltinIncludes(): for include in sorted(meta.BuiltinIncludes()): out.Write('#include <%s>\n' % include) out.Write('\n') # TODO(teravest): Don't emit includes we don't need. includes = ['ppapi/c/pp_errors.h', 'ppapi/shared_impl/tracked_callback.h', 'ppapi/thunk/enter.h', 'ppapi/thunk/ppb_instance_api.h', 'ppapi/thunk/resource_creation_api.h', 'ppapi/thunk/thunk.h'] includes.append(_GetHeaderFileName(filenode)) for api in meta.Apis(): includes.append('ppapi/thunk/%s.h' % api.lower()) for i in meta.Includes(): includes.append(i) for include in sorted(includes): out.Write('#include "%s"\n' % include) out.Write('\n') out.Write('namespace ppapi {\n') out.Write('namespace thunk {\n') out.Write('\n') out.Write('namespace {\n') out.Write('\n')
def DefineMember(filenode, node, member, release, include_version, meta): """Returns a definition for a member function of an interface. Args: filenode - IDLNode for the file node - IDLNode for the interface member - IDLNode for the member function release - release to generate include_version - include the version in emitted function name. meta - ThunkMetadata for header hints Returns: A string with the member definition. """ cgen = CGen() rtype, name, arrays, args = cgen.GetComponents(member, release, 'return') log_body = '\"%s::%s()\";' % ( node.GetName(), cgen.GetStructName(member, release, include_version)) if len(log_body) > 69: # Prevent lines over 80 characters. body = 'VLOG(4) <<\n' body += ' %s\n' % log_body else: body = 'VLOG(4) << %s\n' % log_body if _IsTypeCheck(node, member, args): body += '%s\n' % _MakeEnterLine(filenode, node, member, args[0], False, None, meta) body += 'return PP_FromBool(enter.succeeded());' elif member.GetName() == 'Create' or member.GetName() == 'CreateTrusted': body += _MakeCreateMemberBody(node, member, args) else: body += _MakeNormalMemberBody(filenode, release, node, member, rtype, args, include_version, meta) signature = cgen.GetSignature(member, release, 'return', func_as_ptr=False, include_version=include_version) return '%s\n%s\n}' % (cgen.Indent('%s {' % signature, tabs=0), cgen.Indent(body, tabs=1))
def _GetOutputParams(member, release): """Returns output parameters (and their types) for a member function. Args: member - IDLNode for the member function release - Release to get output parameters for Returns: A list of name strings for all output parameters of the member function. """ out_params = [] callnode = member.GetOneOf('Callspec') if callnode: cgen = CGen() for param in callnode.GetListOf('Param'): mode = cgen.GetParamMode(param) if mode == 'out': # We use the 'store' mode when getting the parameter type, since we # need to call sizeof() for memset(). _, pname, _, _ = cgen.GetComponents(param, release, 'store') out_params.append(pname) return out_params
def CheckTypedefs(filenode, releases): """Checks that typedefs don't specify callbacks that take some structs. See http://crbug.com/233439 for details. """ cgen = CGen() for node in filenode.GetListOf('Typedef'): build_list = node.GetUniqueReleases(releases) callnode = node.GetOneOf('Callspec') if callnode: for param in callnode.GetListOf('Param'): if param.GetListOf('Array'): continue if cgen.GetParamMode(param) != 'in': continue t = param.GetType(build_list[0]) while t.IsA('Typedef'): t = t.GetType(build_list[0]) if t.IsA('Struct') and t.GetProperty('passByValue'): raise Exception('%s is a struct in callback %s. ' 'See http://crbug.com/233439' % (t.GetName(), node.GetName()))
def WriteHead(self, out, filenode, releases, options, meta): __pychecker__ = 'unusednames=options' cgen = CGen() cright_node = filenode.GetChildren()[0] assert(cright_node.IsA('Copyright')) out.Write('%s\n' % cgen.Copyright(cright_node, cpp_style=True)) from_text = 'From %s' % ( filenode.GetProperty('NAME').replace(os.sep,'/')) modified_text = 'modified %s.' % ( filenode.GetProperty('DATETIME')) out.Write('// %s %s\n\n' % (from_text, modified_text)) meta.AddBuiltinInclude('stdint.h') if meta.BuiltinIncludes(): for include in sorted(meta.BuiltinIncludes()): out.Write('#include <%s>\n' % include) out.Write('\n') # TODO(teravest): Don't emit includes we don't need. includes = ['ppapi/c/pp_errors.h', 'ppapi/shared_impl/tracked_callback.h', 'ppapi/thunk/enter.h', 'ppapi/thunk/ppapi_thunk_export.h'] includes.append(_GetHeaderFileName(filenode)) for api in meta.Apis(): includes.append('%s' % api.lower()) for i in meta.Includes(): includes.append(i) for include in sorted(includes): out.Write('#include "%s"\n' % include) out.Write('\n') out.Write('namespace ppapi {\n') out.Write('namespace thunk {\n') out.Write('\n') out.Write('namespace {\n') out.Write('\n')
def CheckPassByValue(filenode, releases): """Checks that new pass-by-value structs are not introduced. See http://crbug.com/233439 for details. """ cgen = CGen() # DO NOT add any more entries to this whitelist. # http://crbug.com/233439 type_whitelist = ['PP_ArrayOutput', 'PP_CompletionCallback', 'PP_Ext_EventListener', 'PP_FloatPoint', 'PP_Point', 'PP_TouchPoint', 'PP_Var'] nodes_to_check = filenode.GetListOf('Struct') nodes_to_check.extend(filenode.GetListOf('Union')) for node in nodes_to_check: if node.GetName() in type_whitelist: continue build_list = node.GetUniqueReleases(releases) if node.GetProperty('passByValue'): raise Exception('%s is a new passByValue struct or union. ' 'See http://crbug.com/233439' % node.GetName()) if node.GetProperty('returnByValue'): raise Exception('%s is a new returnByValue struct or union. ' 'See http://crbug.com/233439' % node.GetName())
def WriteTail(self, out, filenode, releases, options): __pychecker__ = 'unusednames=options' cgen = CGen() version_list = [] out.Write('\n\n') for node in filenode.GetListOf('Interface'): build_list = node.GetUniqueReleases(releases) for build in build_list: version = node.GetVersion(build).replace('.', '_') thunk_name = 'g_' + node.GetName().lower() + '_thunk_' + \ version thunk_type = '_'.join((node.GetName(), version)) version_list.append((thunk_type, thunk_name)) out.Write('const %s %s = {\n' % (thunk_type, thunk_name)) for child in node.GetListOf('Member'): rtype, name, arrays, args = cgen.GetComponents( child, build, 'return') if child.InReleases([build]): # TEST out.Write(' &%s,\n' % name) out.Write('};\n\n') out.Write('} // namespace\n') out.Write('\n') for thunk_type, thunk_name in version_list: thunk_decl = 'const %s* Get%s_Thunk() {\n' % (thunk_type, thunk_type) if len(thunk_decl) > 80: thunk_decl = 'const %s*\n Get%s_Thunk() {\n' % (thunk_type, thunk_type) out.Write(thunk_decl) out.Write(' return &%s;\n' % thunk_name) out.Write('}\n') out.Write('\n') out.Write('} // namespace thunk\n') out.Write('} // namespace ppapi\n')
def __init__(self, wrapper_prefix, s1, s2, s3): Generator.__init__(self, s1, s2, s3) self.wrapper_prefix = wrapper_prefix self._skip_opt = False self.output_file = None self.cgen = CGen()
def __init__(self): WrapperGen.__init__(self, 'Pepper', 'Pepper Gen', 'pepper', 'Generate the Pepper DLL export.') self.cgen = CGen() self._skip_opt = False self._skip_region_gen = False
def GenerateHead(self, out, filenode, releases, options): cgen = CGen() gpath = GetOption('guard') release = releases[0] def_guard = GetOutFileName(filenode, relpath=gpath) def_guard = def_guard.replace(os.sep, '_').replace('.', '_').upper() + '_' cright_node = filenode.GetChildren()[0] assert (cright_node.IsA('Copyright')) fileinfo = filenode.GetChildren()[1] assert (fileinfo.IsA('Comment')) out.Write('%s\n' % cgen.Copyright(cright_node)) out.Write('/* From %s modified %s. */\n\n' % (filenode.GetProperty('NAME').replace( os.sep, '/'), filenode.GetProperty('DATETIME'))) out.Write('#ifndef %s\n#define %s\n\n' % (def_guard, def_guard)) # Generate set of includes deps = set() for release in releases: deps |= filenode.GetDeps(release) includes = set([]) for dep in deps: depfile = dep.GetProperty('FILE') if depfile: includes.add(depfile) includes = [ GetOutFileName(include, relpath=gpath).replace(os.sep, '/') for include in includes ] includes.append('ppapi/c/pp_macros.h') # Assume we need stdint if we "include" C or C++ code if filenode.GetListOf('Include'): includes.append('ppapi/c/pp_stdint.h') includes = sorted(set(includes)) cur_include = GetOutFileName(filenode, relpath=gpath).replace(os.sep, '/') for include in includes: if include == cur_include: continue out.Write('#include "%s"\n' % include) # Generate all interface defines out.Write('\n') for node in filenode.GetListOf('Interface'): idefs = '' name = self.GetVersionString(node) macro = node.GetProperty('macro') if not macro: macro = self.GetMacro(node) unique = node.GetUniqueReleases(releases) for rel in unique: version = node.GetVersion(rel) strver = str(version).replace('.', '_') idefs += self.GetDefine('%s_%s' % (macro, strver), '"%s;%s"' % (name, version)) idefs += self.GetDefine(macro, '%s_%s' % (macro, strver)) + '\n' out.Write(idefs) # Generate the @file comment out.Write('%s\n' % Comment(fileinfo, prefix='*\n @file'))
def GenerateHead(self, out, filenode, releases, options): __pychecker__ = 'unusednames=options' proto = ProtoResolver() proto.Visit(filenode, None) cgen = CGen() gpath = GetOption('guard') def_guard = GetHeaderFromNode(filenode, relpath=gpath) def_guard = def_guard.replace(os.sep, '_').replace('.', '_').upper() + '_' cright_node = filenode.GetChildren()[0] assert (cright_node.IsA('Copyright')) fileinfo = filenode.GetChildren()[1] assert (fileinfo.IsA('Comment')) out.Write('%s\n' % cgen.Copyright(cright_node)) # Wrap the From ... modified ... comment if it would be >80 characters. from_text = 'From %s' % GetPathFromNode(filenode).replace(os.sep, '/') modified_text = 'modified %s.' % (filenode.GetProperty('DATETIME')) if len(from_text) + len(modified_text) < 74: out.Write('/* %s %s */\n\n' % (from_text, modified_text)) else: out.Write('/* %s,\n * %s\n */\n\n' % (from_text, modified_text)) out.Write('#ifndef %s\n#define %s\n\n' % (def_guard, def_guard)) # Generate set of includes deps = set() for release in releases: deps |= filenode.GetDeps(release) includes = set([]) for dep in deps: depfile = dep.GetProperty('FILE') if depfile: includes.add(depfile) includes = [ GetHeaderFromNode(include, relpath=gpath).replace(os.sep, '/') for include in includes ] includes.append('ppapi/c/pp_macros.h') # Assume we need stdint if we "include" C or C++ code if filenode.GetListOf('Include'): includes.append('ppapi/c/pp_stdint.h') includes = sorted(set(includes)) cur_include = GetHeaderFromNode(filenode, relpath=gpath).replace(os.sep, '/') for include in includes: if include == cur_include: continue out.Write('#include "%s"\n' % include) # Generate Prototypes if proto.struct_map: out.Write('\n/* Struct prototypes */\n') for struct in proto.struct_map: out.Write('struct %s;\n' % struct) # Create a macro for the highest available release number. if filenode.GetProperty('NAME').endswith('pp_macros.idl'): releasestr = ' '.join(releases) if releasestr: release_numbers = re.findall('[\d\_]+', releasestr) release = re.findall('\d+', release_numbers[-1])[0] if release: out.Write('\n#define PPAPI_RELEASE %s\n' % release) # Generate all interface defines out.Write('\n') for node in filenode.GetListOf('Interface'): idefs = '' macro = cgen.GetInterfaceMacro(node) unique = node.GetUniqueReleases(releases) # Skip this interface if there are no matching versions if not unique: continue for rel in unique: version = node.GetVersion(rel) name = cgen.GetInterfaceString(node, version) strver = str(version).replace('.', '_') idefs += cgen.GetDefine('%s_%s' % (macro, strver), '"%s"' % name) idefs += cgen.GetDefine(macro, '%s_%s' % (macro, strver)) + '\n' out.Write(idefs) # Generate the @file comment out.Write('%s\n' % Comment(fileinfo, prefix='*\n @file'))
def _MakeNormalMemberBody(filenode, release, node, member, rtype, args, include_version, meta): """Returns the body of a typical function. Args: filenode - IDLNode for the file release - release to generate body for node - IDLNode for the interface member - IDLNode for the member function rtype - Return type for the member function args - List of 4-tuple arguments for the member function include_version - whether to include the version in the invocation meta - ThunkBodyMetadata for header hints """ is_callback_func = args[len(args) - 1][0] == 'struct PP_CompletionCallback' if is_callback_func: call_args = args[:-1] + [('', 'enter.callback()', '', '')] meta.AddInclude('ppapi/c/pp_completion_callback.h') else: call_args = args if args[0][0] == 'PP_Instance': call_arglist = ', '.join(a[1] for a in call_args) function_container = 'functions' else: call_arglist = ', '.join(a[1] for a in call_args[1:]) function_container = 'object' function_name = member.GetName() if include_version: version = node.GetVersion(release).replace('.', '_') function_name += version invocation = 'enter.%s()->%s(%s)' % (function_container, function_name, call_arglist) handle_errors = not (member.GetProperty('report_errors') == 'False') if is_callback_func: body = '%s\n' % _MakeEnterLine(filenode, node, args[0], handle_errors, args[len(args) - 1][1], meta) body += 'if (enter.failed())\n' value = member.GetProperty('on_failure') if value is None: value = 'enter.retval()' body += ' return %s;\n' % value body += 'return enter.SetResult(%s);' % invocation elif rtype == 'void': # On failure, zero out all output parameters. out_params = [] callnode = member.GetOneOf('Callspec') if callnode: cgen = CGen() for param in callnode.GetListOf('Param'): mode = cgen.GetParamMode(param) if mode == 'out': # We use the 'store' mode when getting the parameter type, since we # need to call sizeof() for memset(). ptype, pname, _, _ = cgen.GetComponents(param, release, 'store') out_params.append((pname, ptype)) body = '%s\n' % _MakeEnterLine(filenode, node, args[0], handle_errors, None, meta) if not out_params: body += 'if (enter.succeeded())\n' body += ' %s;' % invocation else: body += 'if (enter.succeeded()) {\n' body += ' %s;\n' % invocation body += ' return;\n' body += '}' for param in out_params: body += '\nmemset(%s, 0, sizeof(%s));' % param meta.AddBuiltinInclude('string.h') else: value = member.GetProperty('on_failure') if value is None: value = _GetDefaultFailureValue(rtype) if value is None: raise TGenError('No default value for rtype %s' % rtype) body = '%s\n' % _MakeEnterLine(filenode, node, args[0], handle_errors, None, meta) body += 'if (enter.failed())\n' body += ' return %s;\n' % value body += 'return %s;' % invocation return body
def GenerateHead(self, out, filenode, releases, options): __pychecker__ = 'unusednames=options' cgen = CGen() gpath = GetOption('guard') def_guard = GetOutFileName(filenode, relpath=gpath) def_guard = def_guard.replace(os.sep, '_').replace('.', '_').upper() + '_' cright_node = filenode.GetChildren()[0] assert (cright_node.IsA('Copyright')) fileinfo = filenode.GetChildren()[1] assert (fileinfo.IsA('Comment')) out.Write('%s\n' % cgen.Copyright(cright_node)) # Wrap the From ... modified ... comment if it would be >80 characters. from_text = 'From %s' % (filenode.GetProperty('NAME').replace( os.sep, '/')) modified_text = 'modified %s.' % (filenode.GetProperty('DATETIME')) if len(from_text) + len(modified_text) < 74: out.Write('/* %s %s */\n\n' % (from_text, modified_text)) else: out.Write('/* %s,\n * %s\n */\n\n' % (from_text, modified_text)) out.Write('#ifndef %s\n#define %s\n\n' % (def_guard, def_guard)) # Generate set of includes deps = set() for release in releases: deps |= filenode.GetDeps(release) includes = set([]) for dep in deps: depfile = dep.GetProperty('FILE') if depfile: includes.add(depfile) includes = [ GetOutFileName(include, relpath=gpath).replace(os.sep, '/') for include in includes ] includes.append('ppapi/c/pp_macros.h') # Assume we need stdint if we "include" C or C++ code if filenode.GetListOf('Include'): includes.append('ppapi/c/pp_stdint.h') includes = sorted(set(includes)) cur_include = GetOutFileName(filenode, relpath=gpath).replace(os.sep, '/') for include in includes: if include == cur_include: continue out.Write('#include "%s"\n' % include) # Generate all interface defines out.Write('\n') for node in filenode.GetListOf('Interface'): idefs = '' macro = cgen.GetInterfaceMacro(node) unique = node.GetUniqueReleases(releases) # Skip this interface if there are no matching versions if not unique: continue for rel in unique: version = node.GetVersion(rel) name = cgen.GetInterfaceString(node, version) strver = str(version).replace('.', '_') idefs += cgen.GetDefine('%s_%s' % (macro, strver), '"%s"' % name) idefs += cgen.GetDefine(macro, '%s_%s' % (macro, strver)) + '\n' out.Write(idefs) # Generate the @file comment out.Write('%s\n' % Comment(fileinfo, prefix='*\n @file'))
def __init__(self): self.cgen = CGen() self.interfaceStructs = [] self.pppInterfaceGetters = []