Source code
Revision control
Copy as Markdown
Other Tools
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: set ts=8 sts=2 et sw=2 tw=80:
* 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
#ifndef frontend_ParserAtom_h
#define frontend_ParserAtom_h
#include "mozilla/MemoryReporting.h" // mozilla::MallocSizeOf
#include "mozilla/Range.h" // mozilla::Range
#include "mozilla/Span.h" // mozilla::Span
#include "mozilla/TextUtils.h"
#include <stddef.h>
#include <stdint.h>
#include "jstypes.h"
#include "NamespaceImports.h"
#include "frontend/TypedIndex.h" // TypedIndex
#include "js/HashTable.h" // HashMap
#include "js/ProtoKey.h" // JS_FOR_EACH_PROTOTYPE
#include "js/Symbol.h" // JS_FOR_EACH_WELL_KNOWN_SYMBOL
#include "js/TypeDecls.h" // Latin1Char
#include "js/Utility.h" // UniqueChars
#include "js/Vector.h" // Vector
#include "threading/Mutex.h" // Mutex
#include "util/Text.h" // InflatedChar16Sequence
#include "vm/CommonPropertyNames.h"
#include "vm/StaticStrings.h"
#include "vm/WellKnownAtom.h" // WellKnownAtomId, WellKnownAtomInfo
struct JS_PUBLIC_API JSContext;
class JSAtom;
class JSString;
namespace mozilla {
union Utf8Unit;
}
namespace js {
class AtomSet;
class JS_PUBLIC_API GenericPrinter;
class LifoAlloc;
class StringBuilder;
namespace frontend {
struct CompilationAtomCache;
struct CompilationStencil;
template <typename CharT>
class SpecificParserAtomLookup;
// These types correspond into indices in the StaticStrings arrays.
enum class Length1StaticParserString : uint8_t;
enum class Length2StaticParserString : uint16_t;
enum class Length3StaticParserString : uint8_t;
class ParserAtom;
using ParserAtomIndex = TypedIndex<ParserAtom>;
// ParserAtomIndex, WellKnownAtomId, Length1StaticParserString,
// Length2StaticParserString, Length3StaticParserString, or null.
//
// 0x0000_0000 Null atom
//
// 0x1YYY_YYYY 28-bit ParserAtom
//
// 0x2000_YYYY Well-known atom ID
// 0x2001_YYYY Static length-1 atom : whole Latin1 range
// 0x2002_YYYY Static length-2 atom : `[A-Za-z0-9$_]{2}`
// 0x2003_YYYY Static length-3 atom : decimal "100" to "255"
class TaggedParserAtomIndex {
uint32_t data_;
public:
static constexpr size_t IndexBit = 28;
static constexpr size_t IndexMask = BitMask(IndexBit);
static constexpr size_t TagShift = IndexBit;
static constexpr size_t TagBit = 4;
static constexpr size_t TagMask = BitMask(TagBit) << TagShift;
enum class Kind : uint32_t {
Null = 0,
ParserAtomIndex,
WellKnown,
};
private:
static constexpr size_t SmallIndexBit = 16;
static constexpr size_t SmallIndexMask = BitMask(SmallIndexBit);
static constexpr size_t SubTagShift = SmallIndexBit;
static constexpr size_t SubTagBit = 2;
static constexpr size_t SubTagMask = BitMask(SubTagBit) << SubTagShift;
public:
static constexpr uint32_t NullTag = uint32_t(Kind::Null) << TagShift;
static constexpr uint32_t ParserAtomIndexTag = uint32_t(Kind::ParserAtomIndex)
<< TagShift;
static constexpr uint32_t WellKnownTag = uint32_t(Kind::WellKnown)
<< TagShift;
private:
static constexpr uint32_t WellKnownSubTag = 0 << SubTagShift;
static constexpr uint32_t Length1StaticSubTag = 1 << SubTagShift;
static constexpr uint32_t Length2StaticSubTag = 2 << SubTagShift;
static constexpr uint32_t Length3StaticSubTag = 3 << SubTagShift;
public:
static constexpr uint32_t IndexLimit = Bit(IndexBit);
static constexpr uint32_t SmallIndexLimit = Bit(SmallIndexBit);
static constexpr size_t Length1StaticLimit = 256U;
static constexpr size_t Length2StaticLimit =
StaticStrings::NUM_LENGTH2_ENTRIES;
static constexpr size_t Length3StaticLimit = 256U;
private:
explicit TaggedParserAtomIndex(uint32_t data) : data_(data) {}
public:
constexpr TaggedParserAtomIndex() : data_(NullTag) {}
explicit constexpr TaggedParserAtomIndex(ParserAtomIndex index)
: data_(index.index | ParserAtomIndexTag) {
MOZ_ASSERT(index.index < IndexLimit);
}
explicit constexpr TaggedParserAtomIndex(WellKnownAtomId index)
: data_(uint32_t(index) | WellKnownTag | WellKnownSubTag) {
MOZ_ASSERT(uint32_t(index) < SmallIndexLimit);
// Length1Static/Length2Static string shouldn't use WellKnownAtomId.
#define CHECK_(NAME, _) MOZ_ASSERT(index != WellKnownAtomId::NAME);
FOR_EACH_NON_EMPTY_TINY_PROPERTYNAME(CHECK_)
#undef CHECK_
}
explicit constexpr TaggedParserAtomIndex(Length1StaticParserString index)
: data_(uint32_t(index) | WellKnownTag | Length1StaticSubTag) {}
explicit constexpr TaggedParserAtomIndex(Length2StaticParserString index)
: data_(uint32_t(index) | WellKnownTag | Length2StaticSubTag) {}
explicit constexpr TaggedParserAtomIndex(Length3StaticParserString index)
: data_(uint32_t(index) | WellKnownTag | Length3StaticSubTag) {}
class WellKnown {
public:
#define METHOD_(NAME, _) \
static constexpr TaggedParserAtomIndex NAME() { \
return TaggedParserAtomIndex(WellKnownAtomId::NAME); \
}
FOR_EACH_NONTINY_COMMON_PROPERTYNAME(METHOD_)
#undef METHOD_
#define METHOD_(NAME, _) \
static constexpr TaggedParserAtomIndex NAME() { \
return TaggedParserAtomIndex(WellKnownAtomId::NAME); \
}
JS_FOR_EACH_PROTOTYPE(METHOD_)
#undef METHOD_
#define METHOD_(NAME) \
static constexpr TaggedParserAtomIndex NAME() { \
return TaggedParserAtomIndex(WellKnownAtomId::NAME); \
}
JS_FOR_EACH_WELL_KNOWN_SYMBOL(METHOD_)
#undef METHOD_
#define METHOD_(NAME, STR) \
static constexpr TaggedParserAtomIndex NAME() { \
return TaggedParserAtomIndex(Length1StaticParserString((STR)[0])); \
}
FOR_EACH_LENGTH1_PROPERTYNAME(METHOD_)
#undef METHOD_
#define METHOD_(NAME, STR) \
static constexpr TaggedParserAtomIndex NAME() { \
return TaggedParserAtomIndex(Length2StaticParserString( \
(StaticStrings::getLength2IndexStatic((STR)[0], (STR)[1])))); \
}
FOR_EACH_LENGTH2_PROPERTYNAME(METHOD_)
#undef METHOD_
static constexpr TaggedParserAtomIndex empty() {
return TaggedParserAtomIndex(WellKnownAtomId::empty_);
}
};
// The value of rawData() for WellKnown TaggedParserAtomIndex.
// For using in switch-case.
class WellKnownRawData {
public:
#define METHOD_(NAME, _) \
static constexpr uint32_t NAME() { \
return uint32_t(WellKnownAtomId::NAME) | WellKnownTag | WellKnownSubTag; \
}