# vim: set ts=8 sts=4 et sw=4 tw=79:
# 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/.

#----------------------------------------------------------------------------
# All heap allocations in SpiderMonkey must go through js_malloc, js_calloc,
# js_realloc, and js_free.  This is so that any embedder who uses a custom
# allocator (by defining JS_USE_CUSTOM_ALLOCATOR) will see all heap allocation
# go through that custom allocator.
#
# Therefore, the presence of any calls to "vanilla" allocation/free functions
# (e.g. malloc(), free()) is a bug.
#
# This script checks for the presence of such disallowed vanilla
# allocation/free function in SpiderMonkey when it's built as a library.  It
# relies on |nm| from the GNU binutils, and so only works on Linux, but one
# platform is good enough to catch almost all violations.
#
# This checking is only 100% reliable in a JS_USE_CUSTOM_ALLOCATOR build in
# which the default definitions of js_malloc et al (in Utility.h) -- which call
# malloc et al -- are replaced with empty definitions.  This is because the
# presence and possible inlining of the default js_malloc et al can cause
# malloc/calloc/realloc/free calls show up in unpredictable places.
#
# Unfortunately, that configuration cannot be tested on Mozilla's standard
# testing infrastructure.  Instead, by default this script only tests that none
# of the other vanilla allocation/free functions (operator new, memalign, etc)
# are present.  If given the --aggressive flag, it will also check for
# malloc/calloc/realloc/free.
#
# Note:  We don't check for |operator delete| and |operator delete[]|.  These
# can be present somehow due to virtual destructors, but this is not too
# because vanilla delete/delete[] calls don't make sense without corresponding
# vanilla new/new[] calls, and any explicit calls will be caught by Valgrind's
# mismatched alloc/free checking.
#----------------------------------------------------------------------------

from __future__ import print_function

import argparse
import re
import subprocess
import sys

# The obvious way to implement this script is to search for occurrences of
# malloc et al, succeed if none are found, and fail is some are found.
# However, "none are found" does not necessarily mean "none are present" --
# this script could be buggy.  (Or the output format of |nm| might change in
# the future.)
#
# So jsutil.cpp deliberately contains a (never-called) function that contains a
# single use of all the vanilla allocation/free functions.  And this script
# fails if it (a) finds uses of those functions in files other than jsutil.cpp,
# *or* (b) fails to find them in jsutil.cpp.

# Tracks overall success of the test.
has_failed = False


def fail(msg):
    print('TEST-UNEXPECTED-FAIL | check_vanilla_allocations.py |', msg)
    global has_failed
    has_failed = True


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--aggressive', action='store_true',
                        help='also check for malloc, calloc, realloc and free')
    parser.add_argument('file', type=str,
                        help='name of the file to check')
    args = parser.parse_args()

    # Run |nm|.  Options:
    # -u: show only undefined symbols
    # -C: demangle symbol names
    # -A: show an object filename for each undefined symbol
    cmd = ['nm', '-u', '-C', '-A', args.file]
    lines = subprocess.check_output(cmd, universal_newlines=True,
                                    stderr=subprocess.PIPE).split('\n')

    # alloc_fns contains all the vanilla allocation/free functions that we look
    # for. Regexp chars are escaped appropriately.

    alloc_fns = [
        # Matches |operator new(unsigned T)|, where |T| is |int| or |long|.
        r'operator new\(unsigned',

        # Matches |operator new[](unsigned T)|, where |T| is |int| or |long|.
        r'operator new\[\]\(unsigned',

        r'memalign',
        # These three aren't available on all Linux configurations.
        #r'posix_memalign',
        #r'aligned_alloc',
        #r'valloc',
    ]

    if args.aggressive:
        alloc_fns += [
            r'malloc',
            r'calloc',
            r'realloc',
            r'free',
            r'strdup'
        ]

    # This is like alloc_fns, but regexp chars are not escaped.
    alloc_fns_unescaped = [fn.translate(None, r'\\') for fn in alloc_fns]

    # This regexp matches the relevant lines in the output of |nm|, which look
    # like the following.
    #
    #   js/src/libjs_static.a:jsutil.o:              U malloc
    #
    alloc_fns_re = r'([^:/ ]+):\s+U (' + r'|'.join(alloc_fns) + r')'

    # This tracks which allocation/free functions have been seen in jsutil.cpp.
    jsutil_cpp = set([])

    # Would it be helpful to emit detailed line number information after a failure?
    emit_line_info = False

    for line in lines:
        m = re.search(alloc_fns_re, line)
        if m is None:
            continue

        filename = m.group(1)
        fn = m.group(2)
        if filename == 'jsutil.o':
            jsutil_cpp.add(fn)
        else:
            # An allocation is present in a non-special file.  Fail!
            fail("'" + fn + "' present in " + filename)
            # Try to give more precise information about the offending code.
            emit_line_info = True


    # Check that all functions we expect are used in jsutil.cpp.  (This will
    # fail if the function-detection code breaks at any point.)
    for fn in alloc_fns_unescaped:
        if fn not in jsutil_cpp:
            fail("'" + fn + "' isn't used as expected in jsutil.cpp")
        else:
            jsutil_cpp.remove(fn)

    # This should never happen, but check just in case.
    if jsutil_cpp:
        fail('unexpected allocation fns used in jsutil.cpp: ' +
             ', '.join(jsutil_cpp))

    # If we found any improper references to allocation functions, try to use
    # DWARF debug info to get more accurate line number information about the
    # bad calls. This is a lot slower than 'nm -A', and it is not always
    # precise when building with --enable-optimized.
    if emit_line_info:
        print('check_vanilla_allocations.py: Source lines with allocation calls:')
        print('check_vanilla_allocations.py: Accurate in unoptimized builds; jsutil.cpp expected.')

        # Run |nm|.  Options:
        # -u: show only undefined symbols
        # -C: demangle symbol names
        # -l: show line number information for each undefined symbol
        cmd = ['nm', '-u', '-C', '-l', args.file]
        lines = subprocess.check_output(cmd, universal_newlines=True,
                                        stderr=subprocess.PIPE).split('\n')

        # This regexp matches the relevant lines in the output of |nm -l|,
        # which look like the following.
        #
        #       U malloc jsutil.cpp:117
        #
        alloc_lines_re = r'U ((' + r'|'.join(alloc_fns) + r').*)\s+(\S+:\d+)$'

        for line in lines:
            m = re.search(alloc_lines_re, line)
            if m:
                print('check_vanilla_allocations.py:', m.group(1), 'called at', m.group(3))

    if has_failed:
        sys.exit(1)

    print('TEST-PASS | check_vanilla_allocations.py | ok')
    sys.exit(0)


if __name__ == '__main__':
    main()

