mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 10:44:56 +00:00
Bug 1472103 - Part 1.1: Result of mach vendor rust. r=me
This commit is contained in:
parent
63240b4b60
commit
37c4b7c0dc
@ -1 +1 @@
|
||||
{"files":{"Cargo.toml":"e32d2641e2dcfeda5cd201df66d5910e5e37fb59b2bc84e82dbf14b53dcb52f1","README.md":"17e5ed3a3bd9b898e73c3056711daabe1238fe9682d24d255f8263fae4eb783d","examples/generate_spidermonkey.rs":"a831abf8d7a1ab73c5d70a9e8517b8af1df492589a2f180698145ac5d46d7102","src/export.rs":"dba92bc4864178b0265e954334303e156827edb9585ce0640ac866c0aff0c9f4","src/import.rs":"50c9e2a399286f0bd86e5fef9f1c8968564cb1db75a86a7472f2f59fd17247d3","src/lib.rs":"d4ea18ec850054a817c6b91ed52412a2f2f39639628e5918dee688d829d3ed4b","src/spec.rs":"15a22ecea4dc3473e34c6cfe121e95edb1a83cfa5e264245e10d19f68456ac72","src/util.rs":"1d934eec75d9dee44289f9a9a9e67c96dd6205367430b9bcf9fc66e730bf6eb0"},"package":"fd7ca5635f1c6f94aaef7de76cb834c5920578355ce41dbcaf731b7ebe348518"}
|
||||
{"files":{".cargo_vcs_info.json":"5a666f68ab005317d058d78c58936ebf66086a242f6a4b8415230649bbce768d","Cargo.toml":"04c87832069d5462b4b87c935fa448213e00a804fcf827334a02beda1fd7f971","README.md":"17e5ed3a3bd9b898e73c3056711daabe1238fe9682d24d255f8263fae4eb783d","examples/generate_spidermonkey.rs":"a831abf8d7a1ab73c5d70a9e8517b8af1df492589a2f180698145ac5d46d7102","src/export.rs":"e889c2f45f00c1787e2270a50fc6d9628446d620c3c0d2ac6ba3f031c561197d","src/import.rs":"7a8525aa55ff0c6c266edfb69a351345ab0c36176deeb0fb91901d4a4e6bd9d6","src/lib.rs":"d4ea18ec850054a817c6b91ed52412a2f2f39639628e5918dee688d829d3ed4b","src/spec.rs":"8f442a5d218360681ad3a5b4c4740b7ae227e087eb745df38cca07a88d8484c4","src/util.rs":"1d934eec75d9dee44289f9a9a9e67c96dd6205367430b9bcf9fc66e730bf6eb0"},"package":"cc0956bac41c458cf38340699dbb54c2220c91cdbfa33be19670fe69e0a6ac9b"}
|
5
third_party/rust/binjs_meta/.cargo_vcs_info.json
vendored
Normal file
5
third_party/rust/binjs_meta/.cargo_vcs_info.json
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"git": {
|
||||
"sha1": "4c24254cdcfba7a929573f34e5ac12686a86bb60"
|
||||
}
|
||||
}
|
2
third_party/rust/binjs_meta/Cargo.toml
vendored
2
third_party/rust/binjs_meta/Cargo.toml
vendored
@ -12,7 +12,7 @@
|
||||
|
||||
[package]
|
||||
name = "binjs_meta"
|
||||
version = "0.3.8"
|
||||
version = "0.3.10"
|
||||
authors = ["David Teller <D.O.Teller@gmail.com>"]
|
||||
description = "Part of binjs-ref. Tools for manipulating grammars. You probably do not want to use this crate directly unless you're writing an encoder, decoder or parser generator for binjs."
|
||||
homepage = "https://binast.github.io/ecmascript-binary-ast/"
|
||||
|
39
third_party/rust/binjs_meta/src/export.rs
vendored
39
third_party/rust/binjs_meta/src/export.rs
vendored
@ -77,13 +77,21 @@ impl TypeDeanonymizer {
|
||||
builder: SpecBuilder::new(),
|
||||
supersums_of: HashMap::new(),
|
||||
};
|
||||
let mut skip_name_map: HashMap<&FieldName, FieldName> = HashMap::new();
|
||||
|
||||
// Copy field names
|
||||
for (_, name) in spec.field_names() {
|
||||
result.builder.import_field_name(name)
|
||||
}
|
||||
|
||||
// We may need to introduce name `_skip`, we'll see.
|
||||
let mut field_skip = None;
|
||||
for (_, interface) in spec.interfaces_by_name() {
|
||||
for field in interface.contents().fields() {
|
||||
if field.is_lazy() {
|
||||
let skip_name = result.builder.field_name(format!("{}_skip", field.name().to_str()).to_str());
|
||||
skip_name_map.insert(field.name(), skip_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Copy and deanonymize interfaces.
|
||||
for (name, interface) in spec.interfaces_by_name() {
|
||||
@ -92,16 +100,6 @@ impl TypeDeanonymizer {
|
||||
// and walk through their fields to deanonymize types.
|
||||
|
||||
let mut fields = vec![];
|
||||
// If the interface is skippable, introduce a first invisible field `_skip`.
|
||||
if interface.is_skippable() {
|
||||
let name = field_skip.get_or_insert_with(||
|
||||
result.builder.field_name("_skip")
|
||||
);
|
||||
fields.push(Field::new(
|
||||
name.clone(),
|
||||
Type::offset().required()
|
||||
))
|
||||
}
|
||||
|
||||
// Copy other fields.
|
||||
for field in interface.contents().fields() {
|
||||
@ -113,9 +111,16 @@ impl TypeDeanonymizer {
|
||||
let mut declaration = result.builder.add_interface(name)
|
||||
.unwrap();
|
||||
for field in fields.drain(..) {
|
||||
declaration.with_field(field.name(), field.type_().clone());
|
||||
// Create *_skip field just before the lazy field.
|
||||
// See also tagged_tuple in write.rs.
|
||||
if field.is_lazy() {
|
||||
declaration.with_field(skip_name_map.get(field.name()).unwrap(),
|
||||
Type::offset().required(),
|
||||
Laziness::Eager);
|
||||
}
|
||||
declaration.with_field(field.name(), field.type_().clone(),
|
||||
field.laziness());
|
||||
}
|
||||
declaration.with_skippable(interface.is_skippable());
|
||||
}
|
||||
// Copy and deanonymize typedefs
|
||||
for (name, definition) in spec.typedefs_by_name() {
|
||||
@ -185,6 +190,7 @@ impl TypeDeanonymizer {
|
||||
match *type_spec {
|
||||
TypeSpec::Boolean |
|
||||
TypeSpec::Number |
|
||||
TypeSpec::UnsignedLong |
|
||||
TypeSpec::String |
|
||||
TypeSpec::Offset |
|
||||
TypeSpec::Void => {
|
||||
@ -233,6 +239,7 @@ impl TypeDeanonymizer {
|
||||
Some(IsNullable { content: Primitive::Interface(_), .. }) => Type::named(&content).required(),
|
||||
Some(IsNullable { content: Primitive::String, .. }) => Type::string().required(),
|
||||
Some(IsNullable { content: Primitive::Number, .. }) => Type::number().required(),
|
||||
Some(IsNullable { content: Primitive::UnsignedLong, .. }) => Type::unsigned_long().required(),
|
||||
Some(IsNullable { content: Primitive::Boolean, .. }) => Type::bool().required(),
|
||||
Some(IsNullable { content: Primitive::Offset, .. }) => Type::offset().required(),
|
||||
Some(IsNullable { content: Primitive::Void, .. }) => Type::void().required()
|
||||
@ -362,6 +369,8 @@ impl TypeName {
|
||||
"_Bool".to_string(),
|
||||
TypeSpec::Number =>
|
||||
"_Number".to_string(),
|
||||
TypeSpec::UnsignedLong =>
|
||||
"_UnsignedLong".to_string(),
|
||||
TypeSpec::String =>
|
||||
"_String".to_string(),
|
||||
TypeSpec::Void =>
|
||||
@ -401,6 +410,8 @@ impl ToWebidl {
|
||||
"string".to_string(),
|
||||
TypeSpec::Number =>
|
||||
"number".to_string(),
|
||||
TypeSpec::UnsignedLong =>
|
||||
"unsigned long".to_string(),
|
||||
TypeSpec::NamedType(ref name) =>
|
||||
name.to_str().to_string(),
|
||||
TypeSpec::TypeSum(ref sum) => {
|
||||
|
75
third_party/rust/binjs_meta/src/import.rs
vendored
75
third_party/rust/binjs_meta/src/import.rs
vendored
@ -1,4 +1,4 @@
|
||||
use spec::{ self, SpecBuilder, TypeSum };
|
||||
use spec::{ self, SpecBuilder, TypeSum, Laziness };
|
||||
|
||||
use webidl::ast::*;
|
||||
|
||||
@ -12,33 +12,52 @@ impl Importer {
|
||||
/// extern crate binjs_meta;
|
||||
/// extern crate webidl;
|
||||
/// use webidl;
|
||||
/// use binjs_meta::spec::SpecOptions;
|
||||
///
|
||||
/// let ast = webidl::parse_string("
|
||||
/// [Skippable] interface SkippableFoo {
|
||||
/// attribute EagerFoo eager;
|
||||
/// interface FooContents {
|
||||
/// attribute boolean value;
|
||||
/// };
|
||||
/// interface LazyFoo {
|
||||
/// [Lazy] attribute FooContents contents;
|
||||
/// };
|
||||
/// interface EagerFoo {
|
||||
/// attribute bool value;
|
||||
/// attribute FooContents contents;
|
||||
/// };
|
||||
/// ").expect("Could not parse");
|
||||
///
|
||||
/// let mut builder = binjs_meta::import::Importer::import(&ast);
|
||||
///
|
||||
/// let name_eager = builder.get_node_name("EagerFoo")
|
||||
/// let fake_root = builder.node_name("@@ROOT@@"); // Unused
|
||||
/// let null = builder.node_name(""); // Used
|
||||
/// let spec = builder.into_spec(SpecOptions {
|
||||
/// root: &fake_root,
|
||||
/// null: &null,
|
||||
/// });
|
||||
///
|
||||
/// let name_eager = spec.get_node_name("EagerFoo")
|
||||
/// .expect("Missing name EagerFoo");
|
||||
/// let name_skippable = builder.get_node_name("SkippableFoo")
|
||||
/// .expect("Missing name SkippableFoo");
|
||||
/// let name_lazy = spec.get_node_name("LazyFoo")
|
||||
/// .expect("Missing name LazyFoo");
|
||||
/// let name_contents = spec.get_field_name("contents")
|
||||
/// .expect("Missing name contents");
|
||||
///
|
||||
/// {
|
||||
/// let interface_eager = builder.get_interface(&name_eager)
|
||||
/// let interface_eager = spec.get_interface_by_name(&name_eager)
|
||||
/// .expect("Missing interface EagerFoo");
|
||||
/// assert_eq!(interface_eager.is_skippable(), false);
|
||||
/// let contents_field =
|
||||
/// interface_eager.get_field_by_name(&name_contents)
|
||||
/// .expect("Missing field contents");
|
||||
/// assert_eq!(contents_field.is_lazy(), false);
|
||||
/// }
|
||||
///
|
||||
/// {
|
||||
/// let interface_skippable = builder.get_interface(&name_skippable)
|
||||
/// .expect("Missing interface SkippableFoo");
|
||||
/// assert_eq!(interface_skippable.is_skippable(), true);
|
||||
/// let interface_lazy = spec.get_interface_by_name(&name_lazy)
|
||||
/// .expect("Missing interface LazyFoo");
|
||||
/// let contents_field =
|
||||
/// interface_lazy.get_field_by_name(&name_contents)
|
||||
/// .expect("Missing field contents");
|
||||
/// assert_eq!(contents_field.is_lazy(), true);
|
||||
/// }
|
||||
/// ```
|
||||
pub fn import(ast: &AST) -> SpecBuilder {
|
||||
@ -95,7 +114,19 @@ impl Importer {
|
||||
if let InterfaceMember::Attribute(Attribute::Regular(ref attribute)) = *member {
|
||||
let name = self.builder.field_name(&attribute.name);
|
||||
let type_ = self.convert_type(&*attribute.type_);
|
||||
fields.push((name, type_));
|
||||
let mut laziness = Laziness::Eager;
|
||||
|
||||
for extended_attribute in &attribute.extended_attributes {
|
||||
use webidl::ast::ExtendedAttribute::NoArguments;
|
||||
use webidl::ast::Other::Identifier;
|
||||
if let &NoArguments(Identifier(ref id)) = extended_attribute.as_ref() {
|
||||
if &*id == "Lazy" {
|
||||
laziness = Laziness::Lazy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fields.push((name, type_, laziness));
|
||||
} else {
|
||||
panic!("Expected an attribute, got {:?}", member);
|
||||
}
|
||||
@ -103,18 +134,8 @@ impl Importer {
|
||||
let name = self.builder.node_name(&interface.name);
|
||||
let mut node = self.builder.add_interface(&name)
|
||||
.expect("Name already present");
|
||||
for (field_name, field_type) in fields.drain(..) {
|
||||
node.with_field(&field_name, field_type);
|
||||
}
|
||||
|
||||
for extended_attribute in &interface.extended_attributes {
|
||||
use webidl::ast::ExtendedAttribute::NoArguments;
|
||||
use webidl::ast::Other::Identifier;
|
||||
if let &NoArguments(Identifier(ref id)) = extended_attribute.as_ref() {
|
||||
if &*id == "Skippable" {
|
||||
node.with_skippable(true);
|
||||
}
|
||||
}
|
||||
for (field_name, field_type, field_laziness) in fields.drain(..) {
|
||||
node.with_field(&field_name, field_type, field_laziness);
|
||||
}
|
||||
}
|
||||
fn convert_type(&mut self, t: &Type) -> spec::Type {
|
||||
@ -140,6 +161,8 @@ impl Importer {
|
||||
}
|
||||
TypeKind::RestrictedDouble =>
|
||||
spec::TypeSpec::Number,
|
||||
TypeKind::UnsignedLong =>
|
||||
spec::TypeSpec::UnsignedLong,
|
||||
_ => {
|
||||
panic!("I don't know how to import {:?} yet", t);
|
||||
}
|
||||
@ -151,4 +174,4 @@ impl Importer {
|
||||
spec.required()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
70
third_party/rust/binjs_meta/src/spec.rs
vendored
70
third_party/rust/binjs_meta/src/spec.rs
vendored
@ -100,12 +100,20 @@ impl TypeSum {
|
||||
}
|
||||
}
|
||||
|
||||
/// Lazy for a field with [lazy] attribute. Eager for others.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum Laziness {
|
||||
Eager,
|
||||
Lazy,
|
||||
}
|
||||
|
||||
/// Representation of a field in an interface.
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct Field {
|
||||
name: FieldName,
|
||||
type_: Type,
|
||||
documentation: Option<String>,
|
||||
laziness: Laziness,
|
||||
}
|
||||
impl Hash for Field {
|
||||
fn hash<H>(&self, state: &mut H) where H: Hasher {
|
||||
@ -118,6 +126,7 @@ impl Field {
|
||||
name,
|
||||
type_,
|
||||
documentation: None,
|
||||
laziness: Laziness::Eager,
|
||||
}
|
||||
}
|
||||
pub fn name(&self) -> &FieldName {
|
||||
@ -126,6 +135,12 @@ impl Field {
|
||||
pub fn type_(&self) -> &Type {
|
||||
&self.type_
|
||||
}
|
||||
pub fn is_lazy(&self) -> bool {
|
||||
self.laziness == Laziness::Lazy
|
||||
}
|
||||
pub fn laziness(&self) -> Laziness {
|
||||
self.laziness.clone()
|
||||
}
|
||||
pub fn doc(&self) -> Option<&str> {
|
||||
match self.documentation {
|
||||
None => None,
|
||||
@ -163,11 +178,13 @@ pub enum TypeSpec {
|
||||
/// A number, as per JavaScript specifications.
|
||||
Number,
|
||||
|
||||
UnsignedLong,
|
||||
|
||||
/// A number of bytes in the binary file.
|
||||
///
|
||||
/// This spec is used only internally, as a hidden
|
||||
/// field injected by deanonymization, to represent
|
||||
/// Skippable nodes.
|
||||
/// lazy fields.
|
||||
Offset,
|
||||
|
||||
/// Nothing.
|
||||
@ -275,6 +292,7 @@ impl TypeSpec {
|
||||
TypeSpec::Boolean => Some(IsNullable::non_nullable(Primitive::Boolean)),
|
||||
TypeSpec::Void => Some(IsNullable::non_nullable(Primitive::Void)),
|
||||
TypeSpec::Number => Some(IsNullable::non_nullable(Primitive::Number)),
|
||||
TypeSpec::UnsignedLong => Some(IsNullable::non_nullable(Primitive::UnsignedLong)),
|
||||
TypeSpec::String => Some(IsNullable::non_nullable(Primitive::String)),
|
||||
TypeSpec::Offset => Some(IsNullable::non_nullable(Primitive::Offset)),
|
||||
TypeSpec::NamedType(ref name) => {
|
||||
@ -311,6 +329,7 @@ pub enum Primitive {
|
||||
Boolean,
|
||||
Void,
|
||||
Number,
|
||||
UnsignedLong,
|
||||
Offset,
|
||||
Interface(Rc<Interface>),
|
||||
}
|
||||
@ -365,6 +384,9 @@ impl Type {
|
||||
pub fn number() -> TypeSpec {
|
||||
TypeSpec::Number
|
||||
}
|
||||
pub fn unsigned_long() -> TypeSpec {
|
||||
TypeSpec::UnsignedLong
|
||||
}
|
||||
pub fn bool() -> TypeSpec {
|
||||
TypeSpec::Boolean
|
||||
}
|
||||
@ -445,7 +467,8 @@ impl Obj {
|
||||
self
|
||||
}
|
||||
|
||||
fn with_field_aux(self, name: &FieldName, type_: Type, doc: Option<&str>) -> Self {
|
||||
fn with_field_aux(self, name: &FieldName, type_: Type, laziness: Laziness,
|
||||
doc: Option<&str>) -> Self {
|
||||
if self.field(name).is_some() {
|
||||
warn!("Field: attempting to overwrite {:?}", name);
|
||||
return self
|
||||
@ -455,6 +478,7 @@ impl Obj {
|
||||
name: name.clone(),
|
||||
type_,
|
||||
documentation: doc.map(str::to_string),
|
||||
laziness,
|
||||
});
|
||||
Obj {
|
||||
fields
|
||||
@ -463,12 +487,12 @@ impl Obj {
|
||||
}
|
||||
|
||||
/// Extend a structure with a field.
|
||||
pub fn with_field(self, name: &FieldName, type_: Type) -> Self {
|
||||
self.with_field_aux(name, type_, None)
|
||||
pub fn with_field(self, name: &FieldName, type_: Type, laziness: Laziness) -> Self {
|
||||
self.with_field_aux(name, type_, laziness, None)
|
||||
}
|
||||
|
||||
pub fn with_field_doc(self, name: &FieldName, type_: Type, doc: &str) -> Self {
|
||||
self.with_field_aux(name, type_, Some(doc))
|
||||
pub fn with_field_doc(self, name: &FieldName, type_: Type, laziness: Laziness, doc: &str) -> Self {
|
||||
self.with_field_aux(name, type_, laziness, Some(doc))
|
||||
}
|
||||
}
|
||||
|
||||
@ -505,9 +529,6 @@ pub struct InterfaceDeclaration {
|
||||
|
||||
/// The contents of this interface, excluding the contents of parent interfaces.
|
||||
contents: Obj,
|
||||
|
||||
/// If `true`, objects of this interface may be skipped during parsing.
|
||||
is_skippable: bool,
|
||||
}
|
||||
|
||||
impl InterfaceDeclaration {
|
||||
@ -515,25 +536,18 @@ impl InterfaceDeclaration {
|
||||
let _ = self.contents.with_full_field(contents);
|
||||
self
|
||||
}
|
||||
pub fn with_field(&mut self, name: &FieldName, type_: Type) -> &mut Self {
|
||||
self.with_field_aux(name, type_, None)
|
||||
pub fn with_field(&mut self, name: &FieldName, type_: Type, laziness: Laziness) -> &mut Self {
|
||||
self.with_field_aux(name, type_, laziness, None)
|
||||
}
|
||||
pub fn with_field_doc(&mut self, name: &FieldName, type_: Type, doc: &str) -> &mut Self {
|
||||
self.with_field_aux(name, type_, Some(doc))
|
||||
pub fn with_field_doc(&mut self, name: &FieldName, type_: Type, laziness: Laziness, doc: &str) -> &mut Self {
|
||||
self.with_field_aux(name, type_, laziness, Some(doc))
|
||||
}
|
||||
fn with_field_aux(&mut self, name: &FieldName, type_: Type, doc: Option<&str>) -> &mut Self {
|
||||
fn with_field_aux(&mut self, name: &FieldName, type_: Type, laziness: Laziness, doc: Option<&str>) -> &mut Self {
|
||||
let mut contents = Obj::new();
|
||||
std::mem::swap(&mut self.contents, &mut contents);
|
||||
self.contents = contents.with_field_aux(name, type_, doc);
|
||||
self.contents = contents.with_field_aux(name, type_, laziness, doc);
|
||||
self
|
||||
}
|
||||
pub fn with_skippable(&mut self, value: bool) -> &mut Self {
|
||||
self.is_skippable = value;
|
||||
self
|
||||
}
|
||||
pub fn is_skippable(&self) -> bool {
|
||||
self.is_skippable
|
||||
}
|
||||
}
|
||||
|
||||
/// A data structure used to progressively construct the `Spec`.
|
||||
@ -603,7 +617,6 @@ impl SpecBuilder {
|
||||
let result = RefCell::new(InterfaceDeclaration {
|
||||
name: name.clone(),
|
||||
contents: Obj::new(),
|
||||
is_skippable: false,
|
||||
});
|
||||
self.interfaces_by_name.insert(name.clone(), result);
|
||||
self.interfaces_by_name.get(name)
|
||||
@ -750,7 +763,7 @@ impl SpecBuilder {
|
||||
debug!(target: "spec", "classify_type => don't put me in an interface");
|
||||
TypeClassification::Array
|
||||
},
|
||||
TypeSpec::Boolean | TypeSpec::Number | TypeSpec::String | TypeSpec::Void | TypeSpec::Offset => {
|
||||
TypeSpec::Boolean | TypeSpec::Number | TypeSpec::UnsignedLong | TypeSpec::String | TypeSpec::Void | TypeSpec::Offset => {
|
||||
debug!(target: "spec", "classify_type => don't put me in an interface");
|
||||
TypeClassification::Primitive
|
||||
}
|
||||
@ -849,8 +862,7 @@ impl SpecBuilder {
|
||||
///
|
||||
/// Interfaces represent nodes in the AST. Each interface
|
||||
/// has a name, a type, defines properties (also known as
|
||||
/// `attribute` in webidl) which hold values. Interfaces
|
||||
/// may also have meta-properties, such as their skippability.
|
||||
/// `attribute` in webidl) which hold values.
|
||||
#[derive(Debug)]
|
||||
pub struct Interface {
|
||||
declaration: InterfaceDeclaration,
|
||||
@ -890,12 +902,6 @@ impl Interface {
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// `true` if parsers should have the ability to skip instances of this
|
||||
/// interface.
|
||||
pub fn is_skippable(&self) -> bool {
|
||||
self.declaration.is_skippable
|
||||
}
|
||||
}
|
||||
|
||||
/// Immutable representation of the spec.
|
||||
|
Loading…
Reference in New Issue
Block a user