mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-22 01:35:35 +00:00
Bug 1552435 - Reading Huffman tables of interfaces, optional interfaces;r=arai
Depends on D32725 Differential Revision: https://phabricator.services.mozilla.com/D32807 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
a88c4dd096
commit
063d63dc55
@ -511,8 +511,11 @@ class HuffmanPreludeReader {
|
||||
struct Boolean : EntryBase {
|
||||
// The C++ type of values for this grammar type.
|
||||
using Type = bool;
|
||||
|
||||
Boolean(const NormalizedInterfaceAndField identity) : EntryBase(identity) {}
|
||||
size_t maxMumberOfSymbols() {
|
||||
|
||||
// The max number of symbols in a table for this type.
|
||||
size_t maxMumberOfSymbols() const {
|
||||
// Sadly, to this day, there are only two known booleans.
|
||||
return 2;
|
||||
}
|
||||
@ -543,11 +546,18 @@ class HuffmanPreludeReader {
|
||||
|
||||
// An optional value of a given interface.
|
||||
struct MaybeInterface : EntryBase {
|
||||
// The C++ type of values for this grammar type.
|
||||
using Type = Nullable;
|
||||
|
||||
// The kind of the interface.
|
||||
const BinASTKind kind;
|
||||
|
||||
MaybeInterface(const NormalizedInterfaceAndField identity, BinASTKind kind)
|
||||
: EntryBase(identity), kind(kind) {}
|
||||
|
||||
// The max number of symbols in a table for this type.
|
||||
size_t maxMumberOfSymbols() const { return 2; }
|
||||
|
||||
// Utility struct, used in macros to call the constructor as
|
||||
// `MaybeInterface::Maker(kind)(identity)`.
|
||||
struct Maker {
|
||||
@ -803,9 +813,13 @@ class HuffmanPreludeReader {
|
||||
MOZ_TRY_VAR(headerByte, reader.readByte());
|
||||
switch (headerByte) {
|
||||
case TableHeader::SingleValue: {
|
||||
// The table contains a single value.
|
||||
// Construct in-place.
|
||||
table = {mozilla::VariantType<Table>{}, cx_};
|
||||
return readSingleValueTable<Table, Entry>(table.as<Table>(), entry);
|
||||
auto& tableRef = table.as<Table>();
|
||||
|
||||
// The table contains a single value.
|
||||
MOZ_TRY((readSingleValueTable<Table, Entry>(tableRef, entry)));
|
||||
return Ok();
|
||||
}
|
||||
case TableHeader::MultipleValues: {
|
||||
// Table contains multiple values.
|
||||
@ -814,8 +828,12 @@ class HuffmanPreludeReader {
|
||||
if (numberOfSymbols > entry.maxMumberOfSymbols()) {
|
||||
return raiseInvalidTableData(entry.identity);
|
||||
}
|
||||
return readMultipleValuesTable<Table, Entry>(table.as<Table>(), entry,
|
||||
numberOfSymbols);
|
||||
// Construct in-place.
|
||||
table = {mozilla::VariantType<Table>{}, cx_};
|
||||
auto& tableRef = table.as<Table>();
|
||||
MOZ_TRY((readMultipleValuesTable<Table, Entry>(tableRef, entry,
|
||||
numberOfSymbols)));
|
||||
return Ok();
|
||||
}
|
||||
case TableHeader::Unreachable:
|
||||
// Table is unreachable, nothing to do.
|
||||
@ -825,6 +843,15 @@ class HuffmanPreludeReader {
|
||||
}
|
||||
}
|
||||
|
||||
// Reading a single boolean.
|
||||
// 0 -> False
|
||||
// _ -> True
|
||||
template <>
|
||||
MOZ_MUST_USE JS::Result<bool> readSymbol<Boolean>() {
|
||||
BINJS_MOZ_TRY_DECL(symbol, reader.readByte());
|
||||
return symbol != 0;
|
||||
}
|
||||
|
||||
// Reading tables of booleans
|
||||
// 0 -> False
|
||||
// _ -> True
|
||||
@ -842,13 +869,31 @@ class HuffmanPreludeReader {
|
||||
return Ok();
|
||||
}
|
||||
|
||||
// Reading a single boolean.
|
||||
// 0 -> False
|
||||
// _ -> True
|
||||
// Reading a single `Foo?` where `Foo` is an interface.
|
||||
// 0 -> null
|
||||
// 1 -> Foo
|
||||
template <>
|
||||
MOZ_MUST_USE JS::Result<bool> readSymbol<Boolean>() {
|
||||
MOZ_MUST_USE JS::Result<Nullable> readSymbol<MaybeInterface>() {
|
||||
BINJS_MOZ_TRY_DECL(symbol, reader.readByte());
|
||||
return symbol != 0;
|
||||
return symbol == 0 ? Nullable::Null : Nullable::NonNull;
|
||||
}
|
||||
|
||||
// Reading a table for `Foo?` where `Foo` is an interface.
|
||||
// 0 -> null
|
||||
// 1 -> Foo
|
||||
template <>
|
||||
MOZ_MUST_USE JS::Result<Ok> readSingleValueTable<
|
||||
HuffmanTableIndexedSymbolsMaybeInterface, MaybeInterface>(
|
||||
HuffmanTableIndexedSymbolsMaybeInterface& table, MaybeInterface entry) {
|
||||
uint8_t indexByte;
|
||||
MOZ_TRY_VAR(indexByte, reader.readByte());
|
||||
if (indexByte >= 2) {
|
||||
return raiseInvalidTableData(entry.identity);
|
||||
}
|
||||
|
||||
MOZ_TRY(table.impl.initWithSingleValue(
|
||||
cx_, indexByte == 0 ? Nullable::Null : Nullable::NonNull));
|
||||
return Ok();
|
||||
}
|
||||
|
||||
private:
|
||||
@ -885,11 +930,26 @@ class HuffmanPreludeReader {
|
||||
return Ok();
|
||||
}
|
||||
|
||||
// Optional Interface.
|
||||
// Values: [null, non-null].
|
||||
MOZ_MUST_USE JS::Result<Ok> operator()(const MaybeInterface& entry) {
|
||||
// FIXME: Enqueue fields.
|
||||
// FIXME: Read table.
|
||||
// FIXME: Initialize table.
|
||||
MOZ_CRASH("Unimplemented");
|
||||
// First, we need a table to determine whether the value is `null`.
|
||||
MOZ_TRY((owner.readTable<HuffmanTableIndexedSymbolsMaybeInterface,
|
||||
MaybeInterface>(entry)));
|
||||
|
||||
// Then, if the table contains `true`, we need the fields of the
|
||||
// interface.
|
||||
// FIXME: readTable could return a reference to the table, eliminating an
|
||||
// array lookup.
|
||||
const auto& table = owner.dictionary.tableForField(entry.identity);
|
||||
if (table.is<HuffmanTableUnreachable>()) {
|
||||
return Ok();
|
||||
}
|
||||
const auto& tableRef =
|
||||
table.as<HuffmanTableIndexedSymbolsMaybeInterface>();
|
||||
if (!tableRef.isAlwaysNull()) {
|
||||
owner.pushFields(entry.kind);
|
||||
}
|
||||
return Ok();
|
||||
}
|
||||
|
||||
|
@ -417,8 +417,18 @@ struct HuffmanEntry {
|
||||
const T value;
|
||||
};
|
||||
|
||||
// The default inline buffer length for instances of HuffmanTable.
|
||||
// Specific type (e.g. booleans) will override this to provide something
|
||||
// more suited to their type.
|
||||
const size_t HUFFMAN_TABLE_DEFAULT_INLINE_BUFFER_LENGTH = 8;
|
||||
|
||||
// A flag that determines only whether a value is `null`.
|
||||
// Used for optional interface.
|
||||
enum class Nullable {
|
||||
Null,
|
||||
NonNull,
|
||||
};
|
||||
|
||||
template <typename T, int N = HUFFMAN_TABLE_DEFAULT_INLINE_BUFFER_LENGTH>
|
||||
class HuffmanTableImpl {
|
||||
public:
|
||||
@ -439,6 +449,10 @@ class HuffmanTableImpl {
|
||||
HuffmanTableImpl() = delete;
|
||||
HuffmanTableImpl(HuffmanTableImpl&) = delete;
|
||||
|
||||
size_t length() const { return values.length(); }
|
||||
const HuffmanEntry<T>* begin() const { return values.begin(); }
|
||||
const HuffmanEntry<T>* end() const { return values.end(); }
|
||||
|
||||
private:
|
||||
// The entries in this Huffman table.
|
||||
// Entries are always ranked by increasing bit_length, and within
|
||||
@ -475,6 +489,24 @@ struct HuffmanTableIndexedSymbolsBool {
|
||||
HuffmanTableIndexedSymbolsBool(JSContext* cx) : impl(cx) {}
|
||||
};
|
||||
|
||||
struct HuffmanTableIndexedSymbolsMaybeInterface {
|
||||
HuffmanTableImpl<Nullable, 2> impl;
|
||||
HuffmanTableIndexedSymbolsMaybeInterface(JSContext* cx) : impl(cx) {}
|
||||
|
||||
// `true` if this table only contains values for `null`.
|
||||
bool isAlwaysNull() const {
|
||||
MOZ_ASSERT(impl.length() > 0);
|
||||
|
||||
// By definition, we have either 1 or 2 values.
|
||||
// By definition, if we have 2 values, one of them is not null.
|
||||
if (impl.length() != 1) {
|
||||
return false;
|
||||
}
|
||||
// Otherwise, check the single value.
|
||||
return impl.begin()->value == Nullable::Null;
|
||||
}
|
||||
};
|
||||
|
||||
struct HuffmanTableIndexedSymbolsStringEnum {
|
||||
HuffmanTableImpl<uint8_t> impl;
|
||||
};
|
||||
@ -491,8 +523,8 @@ struct HuffmanTableIndexedSymbolsOptionalLiteralString {
|
||||
using HuffmanTable = mozilla::Variant<
|
||||
HuffmanTableUnreachable, // Default value.
|
||||
HuffmanTableExplicitSymbolsF64, HuffmanTableExplicitSymbolsU32,
|
||||
HuffmanTableIndexedSymbolsTag, HuffmanTableIndexedSymbolsBool,
|
||||
HuffmanTableIndexedSymbolsStringEnum,
|
||||
HuffmanTableIndexedSymbolsTag, HuffmanTableIndexedSymbolsMaybeInterface,
|
||||
HuffmanTableIndexedSymbolsBool, HuffmanTableIndexedSymbolsStringEnum,
|
||||
HuffmanTableIndexedSymbolsLiteralString,
|
||||
HuffmanTableIndexedSymbolsOptionalLiteralString>;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user