diff --git a/ports/geckolib/gecko_bindings/tools/regen.py b/ports/geckolib/gecko_bindings/tools/regen.py new file mode 100755 index 00000000000..90949f4fdd2 --- /dev/null +++ b/ports/geckolib/gecko_bindings/tools/regen.py @@ -0,0 +1,382 @@ +#!/usr/bin/env python + +# 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 +import sys +import argparse +import platform +import copy +import subprocess +import tempfile + +DESCRIPTION = 'Regenerate the rust version of the structs or the bindings file.' +TOOLS_DIR = os.path.dirname(os.path.abspath(__file__)) +COMMON_BUILD_KEY = "__common__" + +COMPILATION_TARGETS = { + # Flags common for all the targets. + COMMON_BUILD_KEY: { + "flags": [ + "-x", "c++", "-std=gnu++0x", + "-allow-unknown-types", "-no-bitfield-methods", + "-no-type-renaming", + "-DTRACING=1", "-DIMPL_LIBXUL", "-DMOZ_STYLO_BINDINGS=1", + "-DMOZILLA_INTERNAL_API", + ], + "search_dirs": [ + "{}/dist/include", + "{}/dist/include/nspr", + "{}/../nsprpub/pr/include" + ], + "includes": [ + "{}/mozilla-config.h", + ], + }, + # Generation of style structs. + "structs": { + "test": True, + "flags": [ + "-ignore-functions", + ], + "includes": [ + "{}/dist/include/nsThemeConstants.h", + ], + "files": [ + "{}/dist/include/nsStyleStruct.h", + # TODO: Add the DOM files we need for animations. + ], + "build_kinds": { + "debug": { + "flags": [ + "-DDEBUG=1", + "-DJS_DEBUG=1", + ] + }, + "release": { + } + }, + "match_headers": [ + "RefCountType.h", "nscore.h", "nsError.h", "nsID.h", "nsString", + "nsAString", "nsSubstring", "nsTSubstring", "nsTString", + "nsISupportsBase.h", "nsCOMPtr.h", "nsIAtom.h", "nsIURI.h", + "nsAutoPtr.h", "nsColor.h", "nsCoord.h", "nsPoint.h", "nsRect.h", + "nsMargin.h", "nsThemeConstants.h", "nsCSSProperty.h", + "CSSVariableValues.h", "nsFont.h", "nsTHashtable.h", + "PLDHashTable.h", "nsColor.h", "nsStyleStruct.h", "nsStyleCoord.h", + "RefPtr.h", "nsISupportsImpl.h", "gfxFontConstants.h", + "gfxFontFamilyList.h", "gfxFontFeatures.h", "imgRequestProxy.h", + "nsIRequest.h", "imgIRequest.h", "CounterStyleManager.h", + "nsStyleConsts.h", "nsCSSValue.h", "SheetType.h", "nsIPrincipal.h", + "nsDataHashtable.h", "nsCSSScanner.h", "Types.h", "utility", + "nsTArray", "pair", "SheetParsingMode.h", "StaticPtr.h", + "nsProxyRelease.h" + ], + "blacklist": [ + "IsDestructibleFallbackImpl", "IsDestructibleFallback", + "nsProxyReleaseEvent", "FallibleTArray", "nsTArray_Impl", + "__is_tuple_like_impl", "tuple_size", "tuple", + "__make_pair_return_impl", "__make_pair_return", "tuple_element", + "_Itup_cat" + ], + "opaque_types": [ + "nsIntMargin", "nsIntPoint", "nsIntRect", "nsCOMArray", + "nsDependentString", "EntryStore", "gfxFontFeatureValueSet", + "imgRequestProxy", "imgRequestProxyStatic", "CounterStyleManager", + "ImageValue", "URLValue", "URLValueData", "nsIPrincipal", + "nsDataHashtable", "imgIRequest" + ] + }, + # Generation of the ffi bindings. + "bindings": { + "raw_lines": [ + "use heapsize::HeapSizeOf;", + ], + "match_headers": [ + "ServoBindings.h", + "nsStyleStructList.h", + ], + "files": [ + "{}/dist/include/mozilla/ServoBindings.h", + ], + + # Types to just use from the `structs` target. + "structs_types": [ + "nsStyleFont", "nsStyleColor", "nsStyleList", "nsStyleText", + "nsStyleVisibility", "nsStyleUserInterface", "nsStyleTableBorder", + "nsStyleSVG", "nsStyleVariables", "nsStyleBackground", + "nsStylePosition", "nsStyleTextReset", "nsStyleDisplay", + "nsStyleContent", "nsStyleUIReset", "nsStyleTable", + "nsStyleMargin", "nsStylePadding", "nsStyleBorder", + "nsStyleOutline", "nsStyleXUL", "nsStyleSVGReset", "nsStyleColumn", + "nsStyleEffects", "nsStyleImage", "nsStyleGradient", + "nsStyleCoord", "nsStyleGradientStop", + + "SheetParsingMode", "nsMainThreadPtrHandle", + "nsMainThreadPtrHolder", "nscolor", "nsFont", "FontFamilyList", + "FontFamilyType", "nsIAtom", + ], + } +} + + +def platform_dependent_defines(): + ret = [] + + if os.name == "posix": + ret.append("-DOS_POSIX=1") + + ret.append({ + "Linux": "-DOS_LINUX=1", + "Darwin": "-DOS_MACOSX=1", + # TODO: Windows? + }[platform.system()]) + + return ret + + +def extend_object(obj, other): + if not obj or not other: + return obj + + if isinstance(obj, list) and isinstance(other, list): + obj.extend(other) + return + + assert isinstance(obj, dict) and isinstance(other, dict) + + for key in other.keys(): + if key in obj: + extend_object(obj[key], other[key]) + else: + obj[key] = copy.deepcopy(other[key]) + + +def build(objdir, target_name, kind_name=None, + output_filename=None, bindgen=None, skip_test=False, + verbose=False): + assert target_name in COMPILATION_TARGETS + + current_target = COMPILATION_TARGETS[target_name] + if COMMON_BUILD_KEY in COMPILATION_TARGETS: + current_target = copy.deepcopy(COMPILATION_TARGETS[COMMON_BUILD_KEY]) + extend_object(current_target, COMPILATION_TARGETS[target_name]) + + assert ((kind_name is None and "build_kinds" not in current_target) or + (kind_name in current_target["build_kinds"])) + + if bindgen is None: + bindgen = "{}/rust-bindgen/target/debug/bindgen".format(TOOLS_DIR) + + if output_filename is None: + filename = "{}.rs".format(target_name) + + if kind_name is not None: + filename = "{}_{}.rs".format(target_name, kind_name) + + output_filename = "{}/../{}".format(TOOLS_DIR, filename) + + if kind_name is not None: + current_target = copy.deepcopy(current_target) + extend_object(current_target, current_target["build_kinds"][kind_name]) + + print("[BINDGEN] {}::{} in \"{}\"... ".format(target_name, kind_name, objdir), end='') + sys.stdout.flush() + + flags = [] + flags.extend(platform_dependent_defines()) + + if "flags" in current_target: + flags.extend(current_target["flags"]) + + if "raw_lines" in current_target: + for raw_line in current_target["raw_lines"]: + flags.append("-raw-line") + flags.append(raw_line) + + if "search_dirs" in current_target: + for dir_name in current_target["search_dirs"]: + flags.append("-I") + flags.append(dir_name.format(objdir)) + + if "includes" in current_target: + for file_name in current_target["includes"]: + flags.append("-include") + flags.append(file_name.format(objdir)) + + if "match_headers" in current_target: + for header in current_target["match_headers"]: + flags.append("-match") + flags.append(header.format(objdir)) + + if "blacklist" in current_target: + for ty in current_target["blacklist"]: + flags.append("-blacklist-type") + flags.append(ty) + + if "opaque_types" in current_target: + for ty in current_target["opaque_types"]: + flags.append("-opaque-type") + flags.append(ty) + + if "structs_types" in current_target: + for ty in current_target["structs_types"]: + flags.append("-blacklist-type") + flags.append(ty) + flags.append("-raw-line") + flags.append("use structs::{};".format(ty)) + # TODO: this is hacky, figure out a better way to do it without + # hardcoding everything... + if ty.startswith("nsStyle"): + flags.extend([ + "-raw-line", + "unsafe impl Send for {} {{}}".format(ty), + "-raw-line", + "unsafe impl Sync for {} {{}}".format(ty), + "-raw-line", + "impl HeapSizeOf for {} {{ fn heap_size_of_children(&self) -> usize {{ 0 }} }}".format(ty) + ]) + + flags.append("-o") + flags.append(output_filename) + + # TODO: support more files, that's the whole point of this. + assert len(current_target["files"]) == 1 + flags.append(current_target["files"][0].format(objdir)) + + flags.insert(0, bindgen) + output = None + try: + output = subprocess.check_output(flags, stderr=subprocess.STDOUT) + output = output.decode('utf8') + except subprocess.CalledProcessError as e: + print("FAIL\n", e.output.decode('utf8')) + return 1 + + print("OK") + + if verbose: + print(output) + + if current_target.get("test", False) and not skip_test: + print("[RUSTC]... ", end='') + sys.stdout.flush() + + tests_file = tempfile.NamedTemporaryFile() + output = None + try: + rustc_command = ["rustc", output_filename, "--test", "-o", tests_file.name] + output = subprocess.check_output(rustc_command, stderr=subprocess.STDOUT) + output = output.decode('utf8') + except subprocess.CalledProcessError as e: + print("FAIL\n", e.output.decode('utf8')) + return 1 + + print("OK") + + if verbose: + print(output) + + tests_file.file.close() + print("[RUSTC_TEST]... ", end='') + sys.stdout.flush() + + try: + output = subprocess.check_output([tests_file.name], stderr=subprocess.STDOUT) + output = output.decode('utf8') + except subprocess.CalledProcessError as e: + print("tests failed: ", e.output.decode('utf8')) + return 1 + + print("OK") + + # TODO: this -3 is hacky as heck + print(output.split('\n')[-3]) + + if verbose: + print(output) + + return 0 + + +def builds_for(target_name, kind): + if target_name == "all": + for target in COMPILATION_TARGETS.keys(): + if target == COMMON_BUILD_KEY: + continue + + if "build_kinds" in COMPILATION_TARGETS[target]: + for kind in COMPILATION_TARGETS[target]["build_kinds"].keys(): + yield (target, kind) + else: + yield (target, None) + return + + target = COMPILATION_TARGETS[target_name] + if "build_kinds" in target: + if kind is None: + for kind in target["build_kinds"].keys(): + yield(target_name, kind) + else: + yield (target_name, kind) + return + + yield (target_name, None) + + +def main(): + parser = argparse.ArgumentParser(description=DESCRIPTION) + parser.add_argument('--target', + help='The target to build, either "structs" or "bindings"') + parser.add_argument('--kind', + help='Kind of build') + parser.add_argument('--bindgen', + help='Override bindgen binary') + parser.add_argument('--output', '-o', + help='Output of the script') + parser.add_argument('--skip-test', + action='store_true', + help='Skip automatic tests, useful for debugging') + parser.add_argument('--verbose', '-v', + action='store_true', + help='Be... verbose') + parser.add_argument('objdir') + + args = parser.parse_args() + + if not os.path.isdir(args.objdir): + print("\"{}\" doesn't seem to be a directory".format(args.objdir)) + return 1 + + if args.target != COMMON_BUILD_KEY and args.target != "all" and args.target not in COMPILATION_TARGETS: + print("{} is not a valid compilation target.".format(args.target)) + print("Valid compilation targets are:") + for target in COMPILATION_TARGETS.keys(): + if target != COMMON_BUILD_KEY: + print("\t * {}".format(target)) + return 1 + + current_target = COMPILATION_TARGETS.get(args.target, {}) + if args.kind and "build_kinds" in current_target and args.kind not in current_target["build_kinds"]: + print("{} is not a valid build kind.".format(args.kind)) + print("Valid build kinds are:") + for kind in current_target["build_kinds"].keys(): + print("\t * {}".format(kind)) + return 1 + + for target, kind in builds_for(args.target, args.kind): + ret = build(args.objdir, target, kind, + bindgen=args.bindgen, skip_test=args.skip_test, + output_filename=args.output, + verbose=args.verbose) + if ret != 0: + print("{}::{} failed".format(target, kind)) + return ret + + return 0 + +if __name__ == '__main__': + sys.exit(main()) diff --git a/ports/geckolib/gecko_bindings/tools/regen.sh b/ports/geckolib/gecko_bindings/tools/regen.sh new file mode 100755 index 00000000000..ffdf99688f1 --- /dev/null +++ b/ports/geckolib/gecko_bindings/tools/regen.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +if [ $# -eq 0 ]; then + echo "Usage: $0 /path/to/gecko/objdir [other-regen.py-flags]" + exit 1 +fi + +# Check for rust-bindgen +if [ ! -d rust-bindgen ]; then + echo "rust-bindgen not found. Run setup_bindgen.sh first." + exit 1 +fi + +# Check for /usr/include +if [ ! -d /usr/include ]; then + echo "/usr/include doesn't exist. Mac users may need to run xcode-select --install." + exit 1 +fi + +if [ "$(uname)" == "Linux" ]; then + LIBCLANG_PATH=/usr/lib/llvm-3.8/lib; +else + LIBCLANG_PATH=`brew --prefix llvm38`/lib/llvm-3.8/lib; +fi + +./regen.py --target all "$@" diff --git a/ports/geckolib/gecko_bindings/tools/regen_bindings.sh b/ports/geckolib/gecko_bindings/tools/regen_bindings.sh deleted file mode 100755 index 73da1e1399c..00000000000 --- a/ports/geckolib/gecko_bindings/tools/regen_bindings.sh +++ /dev/null @@ -1,94 +0,0 @@ -#!/bin/bash - -# Run in the tools directory. -cd "$(dirname $0)" - -if [ $# -ne 1 ]; then - echo "Usage: $0 /path/to/gecko/objdir" - exit 1 -fi - -# Check for rust-bindgen -if [ ! -d rust-bindgen ]; then - echo "rust-bindgen not found. Run setup_bindgen.sh first." - exit 1 -fi - -# Check for /usr/include -if [ ! -d /usr/include ]; then - echo "/usr/include doesn't exist. Mac users may need to run xcode-select --install." - exit 1 -fi - -if [ "$(uname)" == "Linux" ]; then - PLATFORM_DEPENDENT_DEFINES+="-DOS_LINUX"; - LIBCLANG_PATH=/usr/lib/llvm-3.8/lib; -else - PLATFORM_DEPENDENT_DEFINES+="-DOS_MACOSX"; - LIBCLANG_PATH=`brew --prefix llvm38`/lib/llvm-3.8/lib; -fi - -# Prevent bindgen from generating opaque types for common gecko types. -export MAP_GECKO_TYPES="" - -# Extra code we want to generate. -export EXTRA_CODE="-raw-line 'use heapsize::HeapSizeOf;' " - -# Style structs. -for STRUCT in nsStyleFont nsStyleColor nsStyleList nsStyleText \ - nsStyleVisibility nsStyleUserInterface nsStyleTableBorder \ - nsStyleSVG nsStyleVariables nsStyleBackground nsStylePosition \ - nsStyleTextReset nsStyleDisplay nsStyleContent nsStyleUIReset \ - nsStyleTable nsStyleMargin nsStylePadding nsStyleBorder \ - nsStyleOutline nsStyleXUL nsStyleSVGReset nsStyleColumn nsStyleEffects \ - nsStyleImage nsStyleGradient nsStyleCoord nsStyleGradientStop -do - MAP_GECKO_TYPES=$MAP_GECKO_TYPES"-blacklist-type $STRUCT " - MAP_GECKO_TYPES=$MAP_GECKO_TYPES"-raw-line 'use structs::$STRUCT;' " - EXTRA_CODE=$EXTRA_CODE"-raw-line 'unsafe impl Send for $STRUCT {}' " - EXTRA_CODE=$EXTRA_CODE"-raw-line 'unsafe impl Sync for $STRUCT {}' " - EXTRA_CODE=$EXTRA_CODE"-raw-line 'impl HeapSizeOf for $STRUCT { fn heap_size_of_children(&self) -> usize { 0 } }' " -done - -# Other mapped types. -for TYPE in SheetParsingMode nsMainThreadPtrHandle nsMainThreadPtrHolder nscolor nsFont \ - FontFamilyList FontFamilyType nsIAtom -do - MAP_GECKO_TYPES=$MAP_GECKO_TYPES"-blacklist-type $TYPE " - MAP_GECKO_TYPES=$MAP_GECKO_TYPES"-raw-line 'use structs::$TYPE;' " -done - - - -# Check for the include directory. -export OBJDIR="$1" -export SRCDIR="$1/.." # Not necessarily true, but let's assume. -export DIST_INCLUDE="$1/dist/include" -if [ ! -d "$DIST_INCLUDE" ]; then - echo "$DIST_INCLUDE: directory not found" - exit 1 -fi - -export RUST_BACKTRACE=1 - -# We need to use 'eval' here to make MAP_GECKO_TYPES evaluate properly as -# multiple arguments. -eval ./rust-bindgen/target/debug/bindgen \ - -x c++ -std=gnu++0x \ - "-I$DIST_INCLUDE" \ - "-I$DIST_INCLUDE/nspr/" \ - "-I$1/nsprpub/pr/include/" \ - $PLATFORM_DEPENDENT_DEFINES \ - -DMOZILLA_INTERNAL_API \ - -DMOZ_STYLO_BINDINGS=1 \ - -DJS_DEBUG=1 \ - -DDEBUG=1 -DTRACING=1 -DOS_POSIX=1 \ - -DIMPL_LIBXUL \ - -o ../bindings.rs \ - -no-type-renaming \ - -include "$1/mozilla-config.h" \ - "$DIST_INCLUDE/mozilla/ServoBindings.h" \ - -match "ServoBindings.h" \ - -match "nsStyleStructList.h" \ - $MAP_GECKO_TYPES \ - $EXTRA_CODE diff --git a/ports/geckolib/gecko_bindings/tools/regen_style_structs.sh b/ports/geckolib/gecko_bindings/tools/regen_style_structs.sh deleted file mode 100755 index 3c9adc8147e..00000000000 --- a/ports/geckolib/gecko_bindings/tools/regen_style_structs.sh +++ /dev/null @@ -1,148 +0,0 @@ -#!/bin/bash - -# Run in the tools directory. -cd "$(dirname $0)" - -if [ $# -ne 1 ]; then - echo "Usage: $0 /path/to/gecko/objdir" - exit 1 -fi - -# Check for rust-bindgen -if [ ! -d rust-bindgen ]; then - echo "rust-bindgen not found. Run setup_bindgen.sh first." - exit 1 -fi - -# Check for /usr/include -if [ ! -d /usr/include ]; then - echo "/usr/include doesn't exist. Mac users may need to run xcode-select --install." - exit 1 -fi - -if [ "$(uname)" == "Linux" ]; then - PLATFORM_DEPENDENT_DEFINES+="-DOS_LINUX"; - LIBCLANG_PATH=/usr/lib/llvm-3.8/lib; -else - PLATFORM_DEPENDENT_DEFINES+="-DOS_MACOSX"; - LIBCLANG_PATH=`brew --prefix llvm38`/lib/llvm-3.8/lib; -fi - - -# Check for the include directory. -export DIST_INCLUDE="$1/dist/include" -if [ ! -d "$DIST_INCLUDE" ]; then - echo "$DIST_INCLUDE: directory not found" - exit 1 -fi - -export RUST_BACKTRACE=1 - -for target in debug release; do - ./rust-bindgen/target/debug/bindgen \ - -o ../structs_${target}.rs \ - -x c++ -std=gnu++0x \ - -allow-unknown-types \ - -no-bitfield-methods \ - "-I$DIST_INCLUDE" "-I$DIST_INCLUDE/nspr" \ - "-I$1/../nsprpub/pr/include" \ - $PLATFORM_DEPENDENT_DEFINES \ - -ignore-functions \ - -no-type-renaming \ - -DMOZILLA_INTERNAL_API \ - -DMOZ_STYLO_BINDINGS=1 \ - `[ "$target" = debug ] && echo "-DDEBUG=1 -DJS_DEBUG=1"` \ - -DTRACING=1 -DOS_POSIX=1 \ - -DIMPL_LIBXUL \ - -include "nsThemeConstants.h" \ - -match "RefCountType.h" \ - -match "nscore.h" \ - -match "nsError.h" \ - -match "nsID.h" \ - -match "nsString" \ - -match "nsAString" \ - -match "nsSubstring" \ - -match "nsTSubstring" \ - -match "nsTString" \ - -match "nsISupportsBase.h" \ - -match "nsCOMPtr.h" \ - -match "nsIAtom.h" \ - -match "nsIURI.h" \ - -match "nsAutoPtr.h" \ - -match "nsColor.h" \ - -match "nsCoord.h" \ - -match "nsPoint.h" \ - -match "nsRect.h" \ - -match "nsMargin.h" \ - -match "nsThemeConstants.h" \ - -match "nsCSSProperty.h" \ - -match "CSSVariableValues.h" \ - -match "nsFont.h" \ - -match "nsTHashtable.h" \ - -match "PLDHashTable.h" \ - -match "nsColor.h" \ - -match "nsStyleStruct.h" \ - -match "nsStyleCoord.h" \ - -match "RefPtr.h" \ - -match "nsISupportsImpl.h" \ - -match "gfxFontConstants.h" \ - -match "gfxFontFamilyList.h" \ - -match "gfxFontFeatures.h" \ - -match "imgRequestProxy.h" \ - -match "nsIRequest.h" \ - -match "imgIRequest.h" \ - -match "CounterStyleManager.h" \ - -match "nsStyleConsts.h" \ - -match "nsCSSValue.h" \ - -match "SheetType.h" \ - -match "nsIPrincipal.h" \ - -match "nsDataHashtable.h" \ - -match "nsCSSScanner.h" \ - -match "Types.h" \ - -match "utility" \ - -match "nsTArray" \ - -match "pair" \ - -match "SheetParsingMode.h" \ - -match "StaticPtr.h" \ - -match "nsProxyRelease.h" \ - -blacklist-type "IsDestructibleFallbackImpl" \ - -blacklist-type "IsDestructibleFallback" \ - -blacklist-type "nsProxyReleaseEvent" \ - -blacklist-type "FallibleTArray" \ - -blacklist-type "nsTArray_Impl" \ - -blacklist-type "__is_tuple_like_impl" \ - -opaque-type "nsIntMargin" \ - -opaque-type "nsIntPoint" \ - -opaque-type "nsIntRect" \ - -opaque-type "nsCOMArray" \ - -opaque-type "nsDependentString" \ - -opaque-type "EntryStore" \ - -opaque-type "gfxFontFeatureValueSet" \ - -opaque-type "imgRequestProxy" \ - -opaque-type "imgRequestProxyStatic" \ - -opaque-type "CounterStyleManager" \ - -opaque-type "ImageValue" \ - -opaque-type "URLValue" \ - -opaque-type "URLValueData" \ - -opaque-type "nsIPrincipal" \ - -opaque-type "nsDataHashtable" \ - -opaque-type "imgIRequest" \ - -include "$1/mozilla-config.h" \ - "$DIST_INCLUDE/nsStyleStruct.h" - if [ $? -ne 0 ]; then - echo -e "\e[91mwarning:\e[0m bindgen exited with nonzero exit status" - exit 1 - fi -done - -echo -e "\e[34minfo:\e[0m bindgen exited successfully, running tests" -TESTS_FILE=$(mktemp) -TESTS_SRC=$(mktemp) -for target in debug release; do - echo "#![feature(const_fn)]" > $TESTS_SRC - cat ../structs_${target}.rs >> $TESTS_SRC - multirust run nightly rustc $TESTS_SRC --test -o $TESTS_FILE - $TESTS_FILE -done -rm $TESTS_FILE -rm $TESTS_SRC diff --git a/python/tidy/servo_tidy/tidy.py b/python/tidy/servo_tidy/tidy.py index 3b1b443eb87..fa0708d403a 100644 --- a/python/tidy/servo_tidy/tidy.py +++ b/python/tidy/servo_tidy/tidy.py @@ -70,8 +70,6 @@ IGNORED_DIRS = [ # Generated and upstream code combined with our own. Could use cleanup os.path.join(".", "target"), os.path.join(".", "ports", "cef"), - # Tooling, generated locally from external repos. - os.path.join(".", "ports", "geckolib", "gecko_bindings", "tools"), # Hidden directories os.path.join(".", "."), ]