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

#----------------------------------------------------------------------------
# This script checks that SpiderMonkey MacroAssembler methods are properly
# annotated.
#
# The MacroAssembler has one interface for all platforms, but it might have one
# definition per platform. The code of the MacroAssembler use a macro to
# annotate the method declarations, in order to delete the function if it is not
# present on the current platform, and also to locate the files in which the
# methods are defined.
#
# This script scans the MacroAssembler.h header, for method declarations.
# It also scans MacroAssembler-/arch/.cpp, MacroAssembler-/arch/-inl.h, and
# MacroAssembler-inl.h for method definitions. The result of both scans are
# uniformized, and compared, to determine if the MacroAssembler.h header as
# proper methods annotations.
#----------------------------------------------------------------------------

from __future__ import print_function

import difflib
import os
import re
import subprocess
import sys
from check_utils import get_all_toplevel_filenames

architecture_independent = set([ 'generic' ])
all_architecture_names = set([ 'x86', 'x64', 'arm', 'arm64', 'mips32', 'mips64' ])
all_shared_architecture_names = set([ 'x86_shared', 'mips_shared', 'arm', 'arm64' ])

reBeforeArg = "(?<=[(,\s])"
reArgType = "(?P<type>[\w\s:*&]+)"
reArgName = "(?P<name>\s\w+)"
reArgDefault = "(?P<default>(?:\s=[^,)]+)?)"
reAfterArg = "(?=[,)])"
reMatchArg = re.compile(reBeforeArg + reArgType + reArgName + reArgDefault + reAfterArg)

def get_normalized_signatures(signature, fileAnnot = None):
    # Remove semicolon.
    signature = signature.replace(';', ' ')
    # Normalize spaces.
    signature = re.sub(r'\s+', ' ', signature).strip()
    # Match arguments, and keep only the type.
    signature = reMatchArg.sub('\g<type>', signature)
    # Remove class name
    signature = signature.replace('MacroAssembler::', '')

    # Extract list of architectures
    archs = ['generic']
    if fileAnnot:
        archs = [fileAnnot['arch']]

    if 'DEFINED_ON(' in signature:
        archs = re.sub(r'.*DEFINED_ON\((?P<archs>[^()]*)\).*', '\g<archs>', signature).split(',')
        archs = [a.strip() for a in archs]
        signature = re.sub(r'\s+DEFINED_ON\([^()]*\)', '', signature)

    elif 'PER_ARCH' in signature:
        archs = all_architecture_names
        signature = re.sub(r'\s+PER_ARCH', '', signature)

    elif 'PER_SHARED_ARCH' in signature:
        archs = all_shared_architecture_names
        signature = re.sub(r'\s+PER_SHARED_ARCH', '', signature)

    else:
        # No signature annotation, the list of architectures remains unchanged.
        pass

    # Extract inline annotation
    inline = False
    if fileAnnot:
        inline = fileAnnot['inline']

    if 'inline ' in signature:
        signature = re.sub(r'inline\s+', '', signature)
        inline = True

    inlinePrefx = ''
    if inline:
        inlinePrefx = 'inline '
    signatures =  [
        { 'arch': a, 'sig': inlinePrefx + signature }
        for a in archs
    ]

    return signatures

file_suffixes = set([
    a.replace('_', '-') for a in
    all_architecture_names.union(all_shared_architecture_names)
])
def get_file_annotation(filename):
    origFilename = filename
    filename = filename.split('/')[-1]

    inline = False
    if filename.endswith('.cpp'):
        filename = filename[:-len('.cpp')]
    elif filename.endswith('-inl.h'):
        inline = True
        filename = filename[:-len('-inl.h')]
    else:
        raise Exception('unknown file name', origFilename)

    arch = 'generic'
    for suffix in file_suffixes:
        if filename == 'MacroAssembler-' + suffix:
            arch = suffix
            break

    return {
        'inline': inline,
        'arch': arch.replace('-', '_')
    }

def get_macroassembler_definitions(filename):
    try:
        fileAnnot = get_file_annotation(filename)
    except:
        return []

    style_section = False
    code_section = False
    lines = ''
    signatures = []
    with open(os.path.join('../..', filename)) as f:
        for line in f:
            if '//{{{ check_macroassembler_style' in line:
                style_section = True
            elif '//}}} check_macroassembler_style' in line:
                style_section = False
            if not style_section:
                continue

            line = re.sub(r'//.*', '', line)
            if line.startswith('{'):
                if 'MacroAssembler::' in lines:
                    signatures.extend(get_normalized_signatures(lines, fileAnnot))
                code_section = True
                continue
            if line.startswith('}'):
                code_section = False
                lines = ''
                continue
            if code_section:
                continue

            if len(line.strip()) == 0:
                lines = ''
                continue
            lines = lines + line
            # Continue until we have a complete declaration
            if '{' not in lines:
                continue
            # Skip variable declarations
            if ')' not in lines:
                lines = ''
                continue

    return signatures

def get_macroassembler_declaration(filename):
    style_section = False
    lines = ''
    signatures = []
    with open(os.path.join('../..', filename)) as f:
        for line in f:
            if '//{{{ check_macroassembler_style' in line:
                style_section = True
            elif '//}}} check_macroassembler_style' in line:
                style_section = False
            if not style_section:
                continue

            line = re.sub(r'//.*', '', line)
            if len(line.strip()) == 0:
                lines = ''
                continue
            lines = lines + line
            # Continue until we have a complete declaration
            if ';' not in lines:
                continue
            # Skip variable declarations
            if ')' not in lines:
                lines = ''
                continue

            signatures.extend(get_normalized_signatures(lines))
            lines = ''

    return signatures

def append_signatures(d, sigs):
    for s in sigs:
        if s['sig'] not in d:
            d[s['sig']] = []
        d[s['sig']].append(s['arch']);
    return d

def generate_file_content(signatures):
    output = []
    for s in sorted(signatures.keys()):
        archs = set(sorted(signatures[s]))
        if len(archs.symmetric_difference(architecture_independent)) == 0:
            output.append(s + ';\n')
            if s.startswith('inline'):
                output.append('    is defined in MacroAssembler-inl.h\n')
            else:
                output.append('    is defined in MacroAssembler.cpp\n')
        else:
            if len(archs.symmetric_difference(all_architecture_names)) == 0:
                output.append(s + ' PER_ARCH;\n')
            elif len(archs.symmetric_difference(all_shared_architecture_names)) == 0:
                output.append(s + ' PER_SHARED_ARCH;\n')
            else:
                output.append(s + ' DEFINED_ON(' + ', '.join(archs) + ');\n')
            for a in archs:
                a = a.replace('_', '-')
                masm = '%s/MacroAssembler-%s' % (a, a)
                if s.startswith('inline'):
                    output.append('    is defined in %s-inl.h\n' % masm)
                else:
                    output.append('    is defined in %s.cpp\n' % masm)
    return output

def check_style():
    # We read from the header file the signature of each function.
    decls = dict()      # type: dict(signature => ['x86', 'x64'])

    # We infer from each file the signature of each MacroAssembler function.
    defs = dict()       # type: dict(signature => ['x86', 'x64'])

    # Select the appropriate files.
    for filename in get_all_toplevel_filenames():
        if not filename.startswith('js/src/jit/'):
            continue
        if 'MacroAssembler' not in filename:
            continue

        if filename.endswith('MacroAssembler.h'):
            decls = append_signatures(decls, get_macroassembler_declaration(filename))
        else:
            defs = append_signatures(defs, get_macroassembler_definitions(filename))

    # Compare declarations and definitions output.
    difflines = difflib.unified_diff(generate_file_content(decls),
                                     generate_file_content(defs),
                                     fromfile='check_macroassembler_style.py declared syntax',
                                     tofile='check_macroassembler_style.py found definitions')
    ok = True
    for diffline in difflines:
        ok = False
        print(diffline, end='')

    return ok


def main():
    ok = check_style()

    if ok:
        print('TEST-PASS | check_macroassembler_style.py | ok')
    else:
        print('TEST-UNEXPECTED-FAIL | check_macroassembler_style.py | actual output does not match expected output;  diff is above')

    sys.exit(0 if ok else 1)


if __name__ == '__main__':
    main()
