From 71fb02953c2acedf30bc2a09eab68a6c2f682e13 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Wed, 18 Jan 2017 17:25:59 +0100 Subject: [PATCH 1/2] Remove usage of phf_macros. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It’s a compiler plugin that uses unstable compiler APIs that are not on a path to stabilization. With this changes, there is one less thing that might break when we update the compiler. For example: https://github.com/sfackler/rust-phf/pull/101 --- Cargo.lock | 14 ++--------- components/script/Cargo.toml | 4 ++- components/script/build.rs | 48 ++++++++++++++++++++++++++++++++++++ components/script/lib.rs | 1 - ports/servo/Cargo.toml | 1 - 5 files changed, 53 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3962dc8a78f..20d6d73428a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2015,15 +2015,6 @@ dependencies = [ "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "phf_macros" -version = "0.7.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "phf_generator 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)", - "phf_shared 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "phf_shared" version = "0.7.20" @@ -2295,7 +2286,8 @@ dependencies = [ "open 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "phf 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)", - "phf_macros 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_codegen 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_shared 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", "profile_traits 0.0.1", "range 0.0.1", @@ -2483,7 +2475,6 @@ dependencies = [ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "net_tests 0.0.1", "net_traits_tests 0.0.1", - "phf_macros 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)", "plugin_compiletest 0.0.1", "profile_tests 0.0.1", "script_tests 0.0.1", @@ -3541,7 +3532,6 @@ dependencies = [ "checksum phf 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)" = "0c6afb2057bb5f846a7b75703f90bc1cef4970c35209f712925db7768e999202" "checksum phf_codegen 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)" = "6b63f121bf9a128f2172a65d8313a8e0e79d63874eeb4b4b7d82e6dda6b62f7c" "checksum phf_generator 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)" = "50ffbd7970f75afa083c5dd7b6830c97b72b81579c7a92d8134ef2ee6c0c7eb0" -"checksum phf_macros 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)" = "619b2c128703c63376de760377600b924fc0257487f51bc156f596cf8762e497" "checksum phf_shared 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)" = "286385a0e50d4147bce15b2c19f0cf84c395b0e061aaf840898a7bf664c2cfb7" "checksum pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8cee804ecc7eaf201a4a207241472cc870e825206f6c031e3ee2a72fa425f2fa" "checksum pnacl-build-helper 1.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "61c9231d31aea845007443d62fcbb58bb6949ab9c18081ee1e09920e0cf1118b" diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml index 22b75316bd8..559ee596a45 100644 --- a/components/script/Cargo.toml +++ b/components/script/Cargo.toml @@ -16,6 +16,9 @@ debugmozjs = ['js/debugmozjs'] [build-dependencies] cmake = "0.1" +phf_codegen = "0.7.18" +phf_shared = "0.7.18" +regex = "0.2" [target.'cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))'.dependencies] tinyfiledialogs = "2.5.9" @@ -57,7 +60,6 @@ offscreen_gl_context = "0.5.0" open = "1.1.1" parking_lot = "0.3" phf = "0.7.18" -phf_macros = "0.7.18" plugins = {path = "../plugins"} profile_traits = {path = "../profile_traits"} range = {path = "../range"} diff --git a/components/script/build.rs b/components/script/build.rs index 019a55f25a6..389468f226c 100644 --- a/components/script/build.rs +++ b/components/script/build.rs @@ -3,7 +3,16 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ extern crate cmake; +extern crate phf_codegen; +extern crate phf_shared; +extern crate regex; + +use regex::Regex; use std::env; +use std::fmt; +use std::fs::File; +use std::io::{Read, Write}; +use std::path::PathBuf; use std::time::Instant; fn main() { @@ -34,4 +43,43 @@ fn main() { build.build(); println!("Binding generation completed in {}s", start.elapsed().as_secs()); + + convert_phf(); +} + +fn convert_phf() { + let filename = PathBuf::from(env::var("OUT_DIR").unwrap()).join("InterfaceObjectMap.rs"); + let mut source = String::new(); + File::open(&filename).unwrap().read_to_string(&mut source).unwrap(); + let map_macro = Regex::new("phf_map! \\{([^}]+)\\}").unwrap().captures(&source).unwrap(); + let entries_re = Regex::new("b\"([^\"]+)\" => ([^\n]+),\n").unwrap(); + let entries = entries_re.captures_iter(&map_macro[1]); + + let mut map = phf_codegen::Map::new(); + for entry in entries { + map.entry(Bytes(entry.get(1).unwrap().as_str()), entry.get(2).unwrap().as_str()); + } + + let mut file = File::create(&filename).unwrap(); + let map_macro = map_macro.get(0).unwrap(); + file.write_all(source[..map_macro.start()].as_bytes()).unwrap(); + map.build(&mut file).unwrap(); + file.write_all(source[map_macro.end()..].as_bytes()).unwrap(); +} + +#[derive(Eq, PartialEq, Hash)] +struct Bytes<'a>(&'a str); + +impl<'a> fmt::Debug for Bytes<'a> { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("b\"")?; + formatter.write_str(self.0)?; + formatter.write_str("\" as &'static [u8]") + } +} + +impl<'a> phf_shared::PhfHash for Bytes<'a> { + fn phf_hash(&self, hasher: &mut H) { + self.0.as_bytes().phf_hash(hasher) + } } diff --git a/components/script/lib.rs b/components/script/lib.rs index f1fbe6f99c5..0ee202fab01 100644 --- a/components/script/lib.rs +++ b/components/script/lib.rs @@ -23,7 +23,6 @@ #![doc = "The script crate contains all matters DOM."] -#![plugin(phf_macros)] #![plugin(plugins)] extern crate angle; diff --git a/ports/servo/Cargo.toml b/ports/servo/Cargo.toml index cfaaa2faf1d..54408d25d74 100644 --- a/ports/servo/Cargo.toml +++ b/ports/servo/Cargo.toml @@ -41,7 +41,6 @@ browserhtml = {git = "https://github.com/browserhtml/browserhtml", branch = "cra glutin_app = {path = "../../ports/glutin"} log = "0.3" libservo = {path = "../../components/servo"} -phf_macros = "0.7.19" [target.'cfg(not(target_os = "android"))'.dependencies] sig = "0.1" From 0b9ff576e0ad35c75440ea4953b28fef7f5af4df Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Thu, 19 Jan 2017 17:13:35 +0100 Subject: [PATCH 2/2] script codegen: Avoid modifying in-place a generated file. --- Cargo.lock | 1 + components/script/Cargo.toml | 2 +- components/script/build.rs | 34 +++++++------------ .../dom/bindings/codegen/CodegenRust.py | 25 ++++++++------ .../script/dom/bindings/codegen/GlobalGen.py | 1 + 5 files changed, 29 insertions(+), 34 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 20d6d73428a..0733fe31568 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2299,6 +2299,7 @@ dependencies = [ "script_traits 0.0.1", "selectors 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", "servo_atoms 0.0.1", "servo_config 0.0.1", "servo_geometry 0.0.1", diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml index 559ee596a45..4f13003b7f2 100644 --- a/components/script/Cargo.toml +++ b/components/script/Cargo.toml @@ -18,7 +18,7 @@ debugmozjs = ['js/debugmozjs'] cmake = "0.1" phf_codegen = "0.7.18" phf_shared = "0.7.18" -regex = "0.2" +serde_json = "0.8" [target.'cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))'.dependencies] tinyfiledialogs = "2.5.9" diff --git a/components/script/build.rs b/components/script/build.rs index 389468f226c..189ce765e01 100644 --- a/components/script/build.rs +++ b/components/script/build.rs @@ -5,13 +5,13 @@ extern crate cmake; extern crate phf_codegen; extern crate phf_shared; -extern crate regex; +extern crate serde_json; -use regex::Regex; +use serde_json::Value; use std::env; use std::fmt; use std::fs::File; -use std::io::{Read, Write}; +use std::io::Write; use std::path::PathBuf; use std::time::Instant; @@ -44,27 +44,17 @@ fn main() { println!("Binding generation completed in {}s", start.elapsed().as_secs()); - convert_phf(); -} - -fn convert_phf() { - let filename = PathBuf::from(env::var("OUT_DIR").unwrap()).join("InterfaceObjectMap.rs"); - let mut source = String::new(); - File::open(&filename).unwrap().read_to_string(&mut source).unwrap(); - let map_macro = Regex::new("phf_map! \\{([^}]+)\\}").unwrap().captures(&source).unwrap(); - let entries_re = Regex::new("b\"([^\"]+)\" => ([^\n]+),\n").unwrap(); - let entries = entries_re.captures_iter(&map_macro[1]); - + let json = PathBuf::from(env::var("OUT_DIR").unwrap()).join("build").join("InterfaceObjectMapData.json"); + let json: Value = serde_json::from_reader(File::open(&json).unwrap()).unwrap(); let mut map = phf_codegen::Map::new(); - for entry in entries { - map.entry(Bytes(entry.get(1).unwrap().as_str()), entry.get(2).unwrap().as_str()); + for (key, value) in json.as_object().unwrap() { + map.entry(Bytes(key), value.as_str().unwrap()); } - - let mut file = File::create(&filename).unwrap(); - let map_macro = map_macro.get(0).unwrap(); - file.write_all(source[..map_macro.start()].as_bytes()).unwrap(); - map.build(&mut file).unwrap(); - file.write_all(source[map_macro.end()..].as_bytes()).unwrap(); + let phf = PathBuf::from(env::var("OUT_DIR").unwrap()).join("InterfaceObjectMapPhf.rs"); + let mut phf = File::create(&phf).unwrap(); + write!(&mut phf, "pub static MAP: phf::Map<&'static [u8], unsafe fn(*mut JSContext, HandleObject)> = ").unwrap(); + map.build(&mut phf).unwrap(); + write!(&mut phf, ";\n").unwrap(); } #[derive(Eq, PartialEq, Hash)] diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index f531937d05e..2994734751e 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -6815,6 +6815,15 @@ class GlobalGenRoots(): ], "\n")), pre="pub flags Globals: u8 {\n", post="\n}") globals_ = CGWrapper(CGIndenter(global_flags), pre="bitflags! {\n", post="\n}") + phf = CGGeneric("include!(concat!(env!(\"OUT_DIR\"), \"/InterfaceObjectMapPhf.rs\"));") + + return CGList([ + CGGeneric(AUTOGENERATED_WARNING_COMMENT), + CGList([imports, globals_, phf], "\n\n") + ]) + + @staticmethod + def InterfaceObjectMapData(config): pairs = [] for d in config.getDescriptors(hasInterfaceObject=True, isInline=False): binding = toBindingNamespace(d.name) @@ -6823,19 +6832,13 @@ class GlobalGenRoots(): pairs.append((ctor.identifier.name, binding, binding)) pairs.sort(key=operator.itemgetter(0)) mappings = [ - CGGeneric('b"%s" => codegen::Bindings::%s::%s::DefineDOMInterface as unsafe fn(_, _),' % pair) + CGGeneric('"%s": "codegen::Bindings::%s::%s::DefineDOMInterface as unsafe fn(_, _)"' % pair) for pair in pairs ] - mapType = "phf::Map<&'static [u8], unsafe fn(*mut JSContext, HandleObject)>" - phf = CGWrapper( - CGIndenter(CGList(mappings, "\n")), - pre="pub static MAP: %s = phf_map! {\n" % mapType, - post="\n};\n") - - return CGList([ - CGGeneric(AUTOGENERATED_WARNING_COMMENT), - CGList([imports, globals_, phf], "\n\n") - ]) + return CGWrapper( + CGList(mappings, ",\n"), + pre="{\n", + post="\n}\n") @staticmethod def PrototypeList(config): diff --git a/components/script/dom/bindings/codegen/GlobalGen.py b/components/script/dom/bindings/codegen/GlobalGen.py index 8f122f52bd1..966e4bdbcd2 100644 --- a/components/script/dom/bindings/codegen/GlobalGen.py +++ b/components/script/dom/bindings/codegen/GlobalGen.py @@ -76,6 +76,7 @@ def main(): ('PrototypeList', 'PrototypeList.rs'), ('RegisterBindings', 'RegisterBindings.rs'), ('InterfaceObjectMap', 'InterfaceObjectMap.rs'), + ('InterfaceObjectMapData', 'InterfaceObjectMapData.json'), ('InterfaceTypes', 'InterfaceTypes.rs'), ('InheritTypes', 'InheritTypes.rs'), ('Bindings', os.path.join('Bindings', 'mod.rs')),