Backed out 4 changesets (bug 1553482) for build bustages in BinASTTokenReaderBase.h CLOSED TREE

Backed out changeset 49278023aa7d (bug 1553482)
Backed out changeset 57a5c8689ed3 (bug 1553482)
Backed out changeset c50879a48ff8 (bug 1553482)
Backed out changeset 5570e3e6c5e5 (bug 1553482)
This commit is contained in:
Noemi Erli 2019-05-24 16:49:30 +03:00
Родитель 7e9e422495
Коммит dde2e3cd9f
11 изменённых файлов: 446 добавлений и 3092 удалений

1
Cargo.lock сгенерированный
Просмотреть файл

@ -229,7 +229,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "binast"
version = "0.1.1"
dependencies = [
"Inflector 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)",
"binjs_meta 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",

Просмотреть файл

@ -91,7 +91,6 @@ hpp:
#define frontend_BinASTParser_h
#include "mozilla/Maybe.h"
#include "mozilla/Variant.h"
#include "frontend/BCEParserHandle.h"
#include "frontend/BinASTParserPerTokenizer.h"
@ -123,9 +122,6 @@ hpp:
using AutoTaggedTuple = typename Tokenizer::AutoTaggedTuple;
using Chars = typename Tokenizer::Chars;
using Context = typename BinASTTokenReaderBase::Context;
using ListContext = typename BinASTTokenReaderBase::ListContext;
using FieldContext = typename BinASTTokenReaderBase::FieldContext;
using RootContext = typename BinASTTokenReaderBase::RootContext;
public:
// Auto-generated types.
@ -348,11 +344,6 @@ hpp:
*/
const char* describeBinASTField(const BinASTField& field);
/**
* Return a string describing a `BinASTInterfaceAndField`.
*/
const char* describeBinASTInterfaceAndField(const BinASTInterfaceAndField& field);
/**
* Return a string describing a `BinASTVariant`.
*/
@ -641,7 +632,7 @@ BreakStatement:
block:
replace: |
RootedAtom label(cx_);
MOZ_TRY_VAR(label, tokenizer_->readMaybeAtom(Context(FieldContext(BinASTInterfaceAndField::BreakStatement__Label))));
MOZ_TRY_VAR(label, tokenizer_->readMaybeAtom(fieldContext++));
build: |
if (label) {
@ -785,7 +776,7 @@ ContinueStatement:
block:
replace: |
RootedAtom label(cx_);
MOZ_TRY_VAR(label, tokenizer_->readMaybeAtom(Context(FieldContext(BinASTInterfaceAndField::ContinueStatement__Label))));
MOZ_TRY_VAR(label, tokenizer_->readMaybeAtom(fieldContext++));
build: |
if (label) {
@ -1298,7 +1289,7 @@ LiteralRegExpExpression:
block:
replace: |
Chars flags(cx_);
MOZ_TRY(tokenizer_->readChars(flags, Context(FieldContext(BinASTInterfaceAndField::BreakStatement__Label))));
MOZ_TRY(tokenizer_->readChars(flags, fieldContext++));
build: |
RegExpFlags reflags = RegExpFlag::NoFlags;
for (auto c : flags) {

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -13,7 +13,6 @@
#define frontend_BinASTParser_h
#include "mozilla/Maybe.h"
#include "mozilla/Variant.h"
#include "frontend/BCEParserHandle.h"
#include "frontend/BinASTParserPerTokenizer.h"
@ -45,9 +44,6 @@ class BinASTParser : public BinASTParserPerTokenizer<Tok> {
using AutoTaggedTuple = typename Tokenizer::AutoTaggedTuple;
using Chars = typename Tokenizer::Chars;
using Context = typename BinASTTokenReaderBase::Context;
using ListContext = typename BinASTTokenReaderBase::ListContext;
using FieldContext = typename BinASTTokenReaderBase::FieldContext;
using RootContext = typename BinASTTokenReaderBase::RootContext;
public:
// Auto-generated types.

Просмотреть файл

@ -133,7 +133,7 @@ JS::Result<ParseNode*> BinASTParserPerTokenizer<Tok>::parseAux(
MOZ_TRY(tokenizer_->readHeader());
ParseNode* result(nullptr);
const Context topContext((RootContext()));
const Context topContext(Context::topLevel());
MOZ_TRY_VAR(result, asFinalParser()->parseProgram(topContext));
mozilla::Maybe<GlobalScope::Data*> bindings =
@ -196,7 +196,7 @@ JS::Result<FunctionNode*> BinASTParserPerTokenizer<Tok>::parseLazyFunction(
// Inject a toplevel context (i.e. no parent) to parse the lazy content.
// In the future, we may move this to a more specific context.
const Context context((RootContext()));
const Context context(Context::topLevel());
MOZ_TRY(
(asFinalParser()->*parseFunc)(func->nargs(), &params, &tmpBody, context));

Просмотреть файл

@ -57,7 +57,6 @@ class BinASTParserPerTokenizer : public BinASTParserBase,
using AutoTaggedTuple = typename Tokenizer::AutoTaggedTuple;
using BinASTFields = typename Tokenizer::BinASTFields;
using Chars = typename Tokenizer::Chars;
using RootContext = BinASTTokenReaderBase::RootContext;
using Context = BinASTTokenReaderBase::Context;
public:

Просмотреть файл

@ -19,7 +19,7 @@ namespace js {
namespace frontend {
const BinaryASTSupport::CharSlice BINASTKIND_DESCRIPTIONS[] = {
#define WITH_VARIANT(_, SPEC_NAME, _2) \
#define WITH_VARIANT(_, SPEC_NAME) \
BinaryASTSupport::CharSlice(SPEC_NAME, sizeof(SPEC_NAME) - 1),
FOR_EACH_BIN_KIND(WITH_VARIANT)
#undef WITH_VARIANT

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -7,8 +7,6 @@
#ifndef frontend_BinASTTokenReaderBase_h
#define frontend_BinASTTokenReaderBase_h
#include "mozilla/Variant.h"
#include <string.h>
#include "frontend/BinASTToken.h"
@ -29,29 +27,53 @@ class MOZ_STACK_CLASS BinASTTokenReaderBase {
template <typename T>
using ErrorResult = mozilla::GenericErrorResult<T>;
// Part of variant `Context`
// Reading the root of the tree, before we enter any tagged tuple.
struct RootContext {};
// Part of variant `Context`
// Reading an element from a list.
struct ListContext {
const BinASTInterfaceAndField position;
const BinASTList content;
ListContext(const BinASTInterfaceAndField position,
const BinASTList content)
: position(position), content(content) {}
};
// Part of variant `Context`
// Reading a field from an interface.
struct FieldContext {
const BinASTInterfaceAndField position;
FieldContext(const BinASTInterfaceAndField position) : position(position) {}
};
// The context in which we read a token.
typedef mozilla::Variant<RootContext, ListContext, FieldContext> Context;
struct Context {
// Construct a context for a root node.
constexpr static Context topLevel() {
return Context(BinASTKind::_Null, 0, ElementOf::TaggedTuple);
}
Context arrayElement() const {
return Context(kind, fieldIndex, ElementOf::Array);
}
// Construct a context for a field of a tagged tuple.
constexpr static Context firstField(BinASTKind kind) {
return Context(kind, 0, ElementOf::TaggedTuple);
}
const Context operator++(int) {
MOZ_ASSERT(elementOf == ElementOf::TaggedTuple);
Context result = *this;
fieldIndex++;
return result;
}
// The kind of the tagged tuple containing the token.
//
// If the parent is the root, use `BinASTKind::_Null`.
BinASTKind kind;
// The index of the token as a field of the parent.
uint8_t fieldIndex;
enum class ElementOf {
// This token is an element of an array.
Array,
// This token is a field of a tagged tuple.
TaggedTuple,
};
ElementOf elementOf;
Context() = delete;
private:
constexpr Context(BinASTKind kind_, uint8_t fieldIndex_,
ElementOf elementOf_)
: kind(kind_), fieldIndex(fieldIndex_), elementOf(elementOf_) {}
};
// The information needed to skip a subtree.
class SkippableSubTree {

Просмотреть файл

@ -8,7 +8,6 @@ autobins = false
binjs_meta = "^0.4.3"
clap = "^2"
env_logger = "^0.5.6"
Inflector = "^0.11"
itertools = "^0.7.6"
log = "0.4"
yaml-rust = "^0.4.2"

Просмотреть файл

@ -1,7 +1,6 @@
extern crate binjs_meta;
extern crate clap;
extern crate env_logger;
extern crate inflector;
extern crate itertools;
#[macro_use] extern crate log;
extern crate webidl;
@ -25,16 +24,6 @@ use clap::{ App, Arg };
use itertools::Itertools;
/// An extension of `ToCases` to produce macro-style names, e.g. `FOO_BAR`
/// from `FooBar` or `foo_bar`.
trait ToCases2: ToCases {
fn to_cpp_macro_case(&self) -> String {
use inflector::cases::screamingsnakecase::to_screaming_snake_case;
to_screaming_snake_case(&self.to_cpp_enum_case())
}
}
impl<T: ToCases> ToCases2 for T {}
/// Rules for generating the code for parsing a single field
/// of a node.
///
@ -970,14 +959,13 @@ impl CPPExporter {
let kind_limit = node_names.len();
buffer.push_str(&format!("\n#define FOR_EACH_BIN_KIND(F) \\\n{nodes}\n",
nodes = node_names.iter()
.map(|name| format!(" F({enum_name}, \"{spec_name}\", {macro_name})",
.map(|name| format!(" F({enum_name}, \"{spec_name}\")",
enum_name = name.to_cpp_enum_case(),
spec_name = name,
macro_name = name.to_cpp_macro_case()))
spec_name = name))
.format(" \\\n")));
buffer.push_str("
enum class BinASTKind: uint16_t {
#define EMIT_ENUM(name, _1, _2) name,
#define EMIT_ENUM(name, _) name,
FOR_EACH_BIN_KIND(EMIT_ENUM)
#undef EMIT_ENUM
};
@ -1006,169 +994,7 @@ enum class BinASTField: uint16_t {
#undef EMIT_ENUM
};
");
buffer.push_str(&format!("\n// The number of distinct values of BinASTField.\nconst size_t BINASTFIELD_LIMIT = {};\n", field_limit));
buffer.push_str(&format!("\n#define FOR_EACH_BIN_INTERFACE_AND_FIELD(F) \\\n{nodes}\n",
nodes = self.syntax.interfaces_by_name()
.iter()
.sorted_by_key(|a| a.0)
.into_iter()
.flat_map(|(interface_name, interface)| {
let interface_enum_name = interface_name.to_cpp_enum_case();
let interface_spec_name = interface_name.clone();
interface.contents().fields()
.iter()
.map(move |field| format!(" F({interface_enum_name}__{field_enum_name}, \"{interface_spec_name}::{field_spec_name}\")",
interface_enum_name = interface_enum_name,
field_enum_name = field.name().to_cpp_enum_case(),
interface_spec_name = interface_spec_name,
field_spec_name = field.name().to_str(),
)
)
})
.format(" \\\n")));
buffer.push_str("
enum class BinASTInterfaceAndField: uint16_t {
#define EMIT_ENUM(name, _) name,
FOR_EACH_BIN_INTERFACE_AND_FIELD(EMIT_ENUM)
#undef EMIT_ENUM
};
");
buffer.push_str("
// Strongly typed iterations through the fields of interfaces.
//
// Each of these macros accepts the following arguments:
// - F: callback
// - PRIMITIVE: wrapper for primitive type names - called as `PRIMITIVE(typename)`
// - INTERFACE: wrapper for non-optional interface type names - called as `INTERFACE(typename)`
// - OPTIONAL_INTERFACE: wrapper for optional interface type names - called as `OPTIONAL_INTERFACE(typename)` where
// `typename` is the name of the interface (e.g. no `Maybe` prefix)
// - LIST: wrapper for list types - called as `LIST(list_typename, element_typename)`
// - SUM: wrapper for non-optional type names - called as `SUM(typename)`
// - OPTIONAL_SUM: wrapper for optional sum type names - called as `OPTIONAL_SUM(typename)` where
// `typename` is the name of the sum (e.g. no `Maybe` prefix)
// - STRING_ENUM: wrapper for non-optional string enum types - called as `STRING_ENUNM(typename)`
// - OPTIONAL_STRING_ENUM: wrapper for optional string enum type names - called as `OPTIONAL_STRING_ENUM(typename)` where
// `typename` is the name of the string enum (e.g. no `Maybe` prefix)
");
for (interface_name, interface) in self.syntax.interfaces_by_name().iter().sorted_by_key(|a| a.0) {
use std::borrow::Cow;
let interface_enum_name = interface_name.to_cpp_enum_case();
let interface_spec_name = interface_name.clone();
let interface_macro_name = interface.name().to_cpp_macro_case();
buffer.push_str(&format!("\n\n
// Strongly typed iteration through the fields of interface {interface_enum_name}.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_{interface_macro_name}(F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, STRING_ENUM, OPTIONAL_STRING_ENUM) \\\n{nodes}\n",
interface_macro_name = interface_macro_name,
interface_enum_name = interface_enum_name.clone(),
nodes = interface.contents().fields()
.iter()
.enumerate()
.map(|(i, field)| {
fn get_field_type_name(spec: &Spec, type_: &Type, make_optional: bool) -> Cow<'static, str> {
let optional = make_optional || type_.is_optional();
match *type_.spec() {
TypeSpec::Boolean if optional => Cow::from("PRIMITIVE(MaybeBoolean)"),
TypeSpec::Boolean => Cow::from("PRIMITIVE(Boolean)"),
TypeSpec::String if optional => Cow::from("PRIMITIVE(MaybeString)"),
TypeSpec::String => Cow::from("PRIMITIVE(String)"),
TypeSpec::Number if optional => Cow::from("PRIMITIVE(MaybeNumber)"),
TypeSpec::Number => Cow::from("PRIMITIVE(Number)"),
TypeSpec::UnsignedLong if optional => Cow::from("PRIMITIVE(MaybeUnsignedLong)"),
TypeSpec::UnsignedLong => Cow::from("PRIMITIVE(UnsignedLong)"),
TypeSpec::Offset if optional => Cow::from("PRIMITIVE(MaybeLazy)"),
TypeSpec::Offset => Cow::from("PRIMITIVE(Lazy)"),
TypeSpec::Void if optional => Cow::from("PRIMITIVE(MaybeVoid)"),
TypeSpec::Void => Cow::from("PRIMITIVE(Void)"),
TypeSpec::IdentifierName if optional => Cow::from("PRIMITIVE(MaybeIdentifierName)"),
TypeSpec::IdentifierName => Cow::from("PRIMITIVE(IdentifierName)"),
TypeSpec::PropertyKey if optional => Cow::from("PRIMITIVE(MaybePropertyKey)"),
TypeSpec::PropertyKey => Cow::from("PRIMITIVE(PropertyKey)"),
TypeSpec::Array { ref contents, .. } => Cow::from(
format!("LIST({name}, {contents})",
name = TypeName::type_(type_),
contents = TypeName::type_(contents),
)),
TypeSpec::NamedType(ref name) => match spec.get_type_by_name(name).expect("By now, all types MUST exist") {
NamedType::Typedef(alias_type) => {
if alias_type.is_optional() {
return get_field_type_name(spec, alias_type.as_ref(), true)
}
// Keep the simple name of sums and lists if there is one.
match *alias_type.spec() {
TypeSpec::TypeSum(_) => {
if optional {
Cow::from(format!("OPTIONAL_SUM({name})", name = name.to_cpp_enum_case()))
} else {
Cow::from(format!("SUM({name})", name = name.to_cpp_enum_case()))
}
}
TypeSpec::Array { ref contents, .. } => {
let contents = TypeName::type_(contents);
if optional {
Cow::from(format!("OPTIONAL_LIST({name}, {contents})",
name = name.to_cpp_enum_case(),
contents = contents))
} else {
Cow::from(format!("LIST({name}, {contents})",
name = name.to_cpp_enum_case(),
contents = contents))
}
}
_ => {
get_field_type_name(spec, alias_type.as_ref(), optional)
}
}
}
NamedType::StringEnum(_) if type_.is_optional() => Cow::from(
format!("OPTIONAL_STRING_ENUM({name})",
name = TypeName::type_(type_))),
NamedType::StringEnum(_) => Cow::from(
format!("STRING_ENUM({name})",
name = TypeName::type_(type_))),
NamedType::Interface(ref interface) if type_.is_optional() => Cow::from(
format!("OPTIONAL_INTERFACE({name})",
name = interface.name().to_class_cases())),
NamedType::Interface(ref interface) => Cow::from(
format!("INTERFACE({name})",
name = interface.name().to_class_cases())),
}
TypeSpec::TypeSum(ref contents) if type_.is_optional() => {
// We need to make sure that we don't count the `optional` part twice.
// FIXME: The problem seems to only show up in this branch, but it looks like
// it might (should?) appear in other branches, too.
let non_optional_type = Type::sum(contents.types()).required();
let name = TypeName::type_(&non_optional_type);
Cow::from(format!("OPTIONAL_SUM({name})", name = name))
}
TypeSpec::TypeSum(_) => Cow::from(format!("SUM({name})", name = TypeName::type_(type_))),
}
}
let field_type_name = get_field_type_name(&self.syntax, field.type_(), false);
format!(" F({interface_enum_name}, {field_enum_name}, {field_index}, {field_type}, \"{interface_spec_name}::{field_spec_name}\")",
interface_enum_name = interface_enum_name,
field_enum_name = field.name().to_cpp_enum_case(),
field_index = i,
interface_spec_name = interface_spec_name,
field_spec_name = field.name().to_str(),
field_type = field_type_name
)
})
.format(" \\\n")));
buffer.push_str(&format!("
// The number of fields of interface {interface_spec_name}.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_{interface_macro_name} = {len};",
interface_spec_name = interface_spec_name,
interface_macro_name = interface_macro_name,
len = interface.contents().fields().len()));
}
let total_number_of_fields: usize = self.syntax.interfaces_by_name()
.values()
.map(|interface| interface.contents().fields().len())
.sum();
buffer.push_str(&format!("\n// The total number of fields across all interfaces. Used typically to maintain a probability table per field.\nconst size_t BINAST_INTERFACE_AND_FIELD_LIMIT = {};\n\n\n", total_number_of_fields));
buffer.push_str(&format!("\n// The number of distinct values of BinASTField.\nconst size_t BINASTFIELD_LIMIT = {};\n\n\n", field_limit));
if self.rules.hpp_tokens_variants_doc.is_some() {
buffer.push_str(&self.rules.hpp_tokens_variants_doc.reindent(""));
@ -1198,61 +1024,6 @@ enum class BinASTVariant: uint16_t {
buffer.push_str(&format!("\n// The number of distinct values of BinASTVariant.\nconst size_t BINASTVARIANT_LIMIT = {};\n\n\n",
variants_limit));
buffer.push_str(&format!("\n#define FOR_EACH_BIN_STRING_ENUM(F) \\\n{nodes}\n",
nodes = self.syntax.string_enums_by_name()
.keys()
.sorted()
.into_iter()
.map(|name| format!(" F({enum_name}, \"{spec_name}\")",
enum_name = name.to_cpp_enum_case(),
spec_name = name.to_str()))
.format(" \\\n")));
buffer.push_str("
enum class BinASTStringEnum: uint16_t {
#define EMIT_ENUM(name, _) name,
FOR_EACH_BIN_STRING_ENUM(EMIT_ENUM)
#undef EMIT_ENUM
};
");
buffer.push_str(&format!("\n// The number of distinct values of BinASTStringEnum.\nconst size_t BINASTSTRINGENUM_LIMIT = {};\n\n\n",
self.syntax.string_enums_by_name().len()));
buffer.push_str(&format!("\n#define FOR_EACH_BIN_LIST(F) \\\n{nodes}\n",
nodes = self.list_parsers_to_generate.iter()
.sorted_by_key(|data| &data.name)
.into_iter()
.map(|data| format!(" F({list_name}, {content_name}, \"{spec_name}\")",
list_name = data.name.to_cpp_enum_case(),
content_name = data.elements.to_cpp_enum_case(),
spec_name = data.name.to_str()))
.format(" \\\n")));
buffer.push_str("
enum class BinASTList: uint16_t {
#define EMIT_ENUM(name, _content, _user) name,
FOR_EACH_BIN_LIST(EMIT_ENUM)
#undef EMIT_ENUM
};
");
buffer.push_str(&format!("\n// The number of distinct list types in the grammar. Used typically to maintain a probability table per list type.\nconst size_t BINAST_NUMBER_OF_LIST_TYPES = {};\n\n\n", self.list_parsers_to_generate.len()));
buffer.push_str(&format!("\n#define FOR_EACH_BIN_SUM(F) \\\n{nodes}\n",
nodes = self.syntax.resolved_sums_of_interfaces_by_name()
.iter()
.sorted_by(|a, b| a.0.cmp(&b.0))
.into_iter()
.map(|(name, _)| format!(" F({name}, \"{spec_name}\")",
name = name.to_cpp_enum_case(),
spec_name = name.to_str()))
.format(" \\\n")));
buffer.push_str("
enum class BinASTSum: uint16_t {
#define EMIT_ENUM(name, _user) name,
FOR_EACH_BIN_SUM(EMIT_ENUM)
#undef EMIT_ENUM
};
");
buffer.push_str(&self.rules.hpp_tokens_footer.reindent(""));
buffer.push_str("\n");
}
@ -1632,8 +1403,8 @@ impl CPPExporter {
MOZ_TRY(tokenizer_->enterList(length, context, guard));{empty_check}
{init}
const Context childContext(context.arrayElement());
for (uint32_t i = 0; i < length; ++i) {{
const Context childContext(Context(ListContext(context.as<FieldContext>().position, BinASTList::{content_kind})));
{call}
{append} }}
@ -1641,7 +1412,6 @@ impl CPPExporter {
return result;
}}\n",
first_line = first_line,
content_kind = parser.name.to_class_cases(),
empty_check =
if parser.supports_empty {
"".to_string()
@ -1964,9 +1734,7 @@ impl CPPExporter {
let mut fields_implem = String::new();
for field in interface.contents().fields() {
let context = format!("Context(FieldContext(BinASTInterfaceAndField::{kind}__{field}))",
kind = name.to_cpp_enum_case(),
field = field.name().to_cpp_enum_case());
let context = "fieldContext++";
let rules_for_this_field = rules_for_this_interface.by_field.get(field.name())
.cloned()
@ -2168,7 +1936,7 @@ impl CPPExporter {
{{
MOZ_ASSERT(kind == BinASTKind::{kind});
BINJS_TRY(CheckRecursionLimit(cx_));
{check_fields}
{maybe_field_context}{check_fields}
{pre}{fields_implem}
{post} return result;
}}
@ -2180,6 +1948,11 @@ impl CPPExporter {
post = build_result.newline_if_not_empty(),
kind = name.to_cpp_enum_case(),
first_line = first_line,
maybe_field_context = if interface.contents().fields().len() > 0 {
" Context fieldContext = Context::firstField(kind);\n"
} else {
""
},
));
}
}