config/make-stl-wrappers.py
author Mike Hommey <mh+mozilla@glandium.org>
Wed, 18 May 2016 16:37:19 +0900
changeset 298410 68da139d0866977c0ada86319fa94388f2255446
parent 145808 20a4b8ad2107aa23f9aae1aa7e63f03edcd7b0e5
child 391024 828d43ec1b16edaac69c42f15561f26e209051f1
permissions -rw-r--r--
Bug 1269171 - Change how mozalloc.h is hooked in STL wrappers. r=froydnj Since the introduction of the STL wrappers, they have included mozalloc.h, and multiple times, we've hit header reentrancy problems, and worked around them as best as we could. Taking a step back, all mozalloc.h does is: - declare moz_* allocator functions. - define inline implementations of various operator new/delete variants. The first only requires the functions to be declared before they are used, so mozalloc.h only needs to be included before anything that would use those functions. The second doesn't actually require a specific order, as long as the declaration for those functions comes before their use, and they are either declared in <new> or implicitly by the C++ compiler. So all in all, it doesn't matter that mozalloc.h is included before the wrapped STL headers. What matters is that it's included when STL headers are included. So arrange things such that mozalloc.h is included after the first wrapped STL header is fully preprocessed (and all its includes have been included).

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from __future__ import print_function
import os, re, string, sys
from mozbuild.util import FileAvoidWrite

def find_in_path(file, searchpath):
    for dir in searchpath.split(os.pathsep):
        f = os.path.join(dir, file)
        if os.path.exists(f):
            return f
    return ''

def header_path(header, compiler):
    if compiler == 'gcc':
        # we use include_next on gcc
        return header
    elif compiler == 'msvc':
        return find_in_path(header, os.environ.get('INCLUDE', ''))
    else:
        # hope someone notices this ...
        raise NotImplementedError(compiler)

def is_comment(line):
    return re.match(r'\s*#.*', line)

def main(outdir, compiler, template_file, header_list_file):
    if not os.path.isdir(outdir):
        os.mkdir(outdir)

    template = open(template_file, 'r').read()

    for header in open(header_list_file, 'r'):
        header = header.rstrip()
        if 0 == len(header) or is_comment(header):
            continue

        path = header_path(header, compiler)
        with FileAvoidWrite(os.path.join(outdir, header)) as f:
            f.write(string.Template(template).substitute(HEADER=header,
                                                         HEADER_PATH=path))


if __name__ == '__main__':
    if 5 != len(sys.argv):
        print("""Usage:
  python {0} OUT_DIR ('msvc'|'gcc') TEMPLATE_FILE HEADER_LIST_FILE
""".format(sys.argv[0]), file=sys.stderr)
        sys.exit(1)

    main(*sys.argv[1:])