Backed out 2 changesets (bug 1660798) for causing memory leaks. CLOSED TREE

Backed out changeset 846f88debca6 (bug 1660798)
Backed out changeset 12d099efac67 (bug 1660798)
This commit is contained in:
Cosmin Sabou 2020-08-25 01:03:43 +03:00
Родитель 7b214fd81a
Коммит f66ec87fd8
85 изменённых файлов: 1662 добавлений и 2377 удалений

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

@ -78,6 +78,12 @@ set_define('JS_64BIT', depends(target)(lambda t: t.bitness == 64 or None))
set_define('JS_PUNBOX64', depends(target)(lambda t: t.bitness == 64 or None))
set_define('JS_NUNBOX32', depends(target)(lambda t: t.bitness == 32 or None))
# Bits of Stencil-related parser-atoms work are being landed before
# being enabled. This define controls that code, and will be removed,
# along with guard code in ParserAtoms.cpp, when the final transition
# to parser atoms lands.
set_define('JS_PARSER_ATOMS', None)
# SpiderMonkey as a shared library, and how its symbols are exported
# ==================================================================

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

@ -1234,7 +1234,7 @@ bool ModuleBuilder::buildTables(frontend::StencilModuleMetadata& metadata) {
return false;
}
} else {
if (importEntry->importName == cx_->parserNames().star) {
if (importEntry->importName == cx_->names().star) {
if (!metadata.localExportEntries.append(exp)) {
return false;
}
@ -1247,7 +1247,7 @@ bool ModuleBuilder::buildTables(frontend::StencilModuleMetadata& metadata) {
}
}
}
} else if (exp.importName == cx_->parserNames().star && !exp.exportName) {
} else if (exp.importName == cx_->names().star && !exp.exportName) {
if (!metadata.starExportEntries.append(exp)) {
return false;
}
@ -1273,8 +1273,7 @@ enum class ModuleArrayType {
};
static ArrayObject* ModuleBuilderInitArray(
JSContext* cx, frontend::CompilationInfo& compilationInfo,
ModuleArrayType arrayType,
JSContext* cx, ModuleArrayType arrayType,
const frontend::StencilModuleMetadata::EntryVector& vector) {
RootedArrayObject resultArray(
cx, NewDenseFullyAllocatedArray(cx, vector.length()));
@ -1292,34 +1291,10 @@ static ArrayObject* ModuleBuilderInitArray(
for (uint32_t i = 0; i < vector.length(); ++i) {
const frontend::StencilModuleEntry& entry = vector[i];
if (entry.specifier) {
specifier = compilationInfo.liftParserAtomToJSAtom(entry.specifier);
if (!specifier) {
return nullptr;
}
}
if (entry.localName) {
localName = compilationInfo.liftParserAtomToJSAtom(entry.localName);
if (!localName) {
return nullptr;
}
}
if (entry.importName) {
importName = compilationInfo.liftParserAtomToJSAtom(entry.importName);
if (!importName) {
return nullptr;
}
}
if (entry.exportName) {
exportName = compilationInfo.liftParserAtomToJSAtom(entry.exportName);
if (!exportName) {
return nullptr;
}
}
specifier = entry.specifier;
localName = entry.localName;
importName = entry.importName;
exportName = entry.exportName;
switch (arrayType) {
case ModuleArrayType::ImportEntryObject:
@ -1352,43 +1327,37 @@ static ArrayObject* ModuleBuilderInitArray(
// Use StencilModuleMetadata data to fill in ModuleObject
bool frontend::StencilModuleMetadata::initModule(
JSContext* cx, frontend::CompilationInfo& compilationInfo,
JS::Handle<ModuleObject*> module) {
JSContext* cx, JS::Handle<ModuleObject*> module) {
RootedArrayObject requestedModulesObject(
cx, ModuleBuilderInitArray(cx, compilationInfo,
ModuleArrayType::RequestedModuleObject,
cx, ModuleBuilderInitArray(cx, ModuleArrayType::RequestedModuleObject,
requestedModules));
if (!requestedModulesObject) {
return false;
}
RootedArrayObject importEntriesObject(
cx, ModuleBuilderInitArray(cx, compilationInfo,
ModuleArrayType::ImportEntryObject,
cx, ModuleBuilderInitArray(cx, ModuleArrayType::ImportEntryObject,
importEntries));
if (!importEntriesObject) {
return false;
}
RootedArrayObject localExportEntriesObject(
cx, ModuleBuilderInitArray(cx, compilationInfo,
ModuleArrayType::ExportEntryObject,
cx, ModuleBuilderInitArray(cx, ModuleArrayType::ExportEntryObject,
localExportEntries));
if (!localExportEntriesObject) {
return false;
}
RootedArrayObject indirectExportEntriesObject(
cx, ModuleBuilderInitArray(cx, compilationInfo,
ModuleArrayType::ExportEntryObject,
cx, ModuleBuilderInitArray(cx, ModuleArrayType::ExportEntryObject,
indirectExportEntries));
if (!indirectExportEntriesObject) {
return false;
}
RootedArrayObject starExportEntriesObject(
cx, ModuleBuilderInitArray(cx, compilationInfo,
ModuleArrayType::ExportEntryObject,
cx, ModuleBuilderInitArray(cx, ModuleArrayType::ExportEntryObject,
starExportEntries));
if (!starExportEntriesObject) {
return false;
@ -1415,20 +1384,23 @@ bool ModuleBuilder::processImport(frontend::BinaryNode* importNode) {
NameNode* moduleSpec = &importNode->right()->as<NameNode>();
MOZ_ASSERT(moduleSpec->isKind(ParseNodeKind::StringExpr));
const ParserAtom* module = moduleSpec->atom();
RootedAtom module(cx_, moduleSpec->atom());
if (!maybeAppendRequestedModule(module, moduleSpec)) {
return false;
}
RootedAtom importName(cx_);
RootedAtom localName(cx_);
for (ParseNode* item : specList->contents()) {
BinaryNode* spec = &item->as<BinaryNode>();
MOZ_ASSERT(spec->isKind(ParseNodeKind::ImportSpec));
NameNode* importNameNode = &spec->left()->as<NameNode>();
NameNode* localNameNode = &spec->right()->as<NameNode>();
const ParserAtom* importName = importNameNode->atom();
const ParserAtom* localName = localNameNode->atom();
importName = importNameNode->atom();
localName = localNameNode->atom();
uint32_t line;
uint32_t column;
@ -1457,24 +1429,24 @@ bool ModuleBuilder::processExport(frontend::ParseNode* exportNode) {
if (isDefault && exportNode->as<BinaryNode>().right()) {
// This is an export default containing an expression.
const ParserAtom* localName = cx_->parserNames().default_;
const ParserAtom* exportName = cx_->parserNames().default_;
HandlePropertyName localName = cx_->names().default_;
HandlePropertyName exportName = cx_->names().default_;
return appendExportEntry(exportName, localName);
}
switch (kid->getKind()) {
case ParseNodeKind::ExportSpecList: {
MOZ_ASSERT(!isDefault);
RootedAtom localName(cx_);
RootedAtom exportName(cx_);
for (ParseNode* item : kid->as<ListNode>().contents()) {
BinaryNode* spec = &item->as<BinaryNode>();
MOZ_ASSERT(spec->isKind(ParseNodeKind::ExportSpec));
NameNode* localNameNode = &spec->left()->as<NameNode>();
NameNode* exportNameNode = &spec->right()->as<NameNode>();
const ParserAtom* localName = localNameNode->atom();
const ParserAtom* exportName = exportNameNode->atom();
localName = localNameNode->atom();
exportName = exportNameNode->atom();
if (!appendExportEntry(exportName, localName, spec)) {
return false;
}
@ -1485,10 +1457,9 @@ bool ModuleBuilder::processExport(frontend::ParseNode* exportNode) {
case ParseNodeKind::ClassDecl: {
const ClassNode& cls = kid->as<ClassNode>();
MOZ_ASSERT(cls.names());
const frontend::ParserAtom* localName =
cls.names()->innerBinding()->atom();
const frontend::ParserAtom* exportName =
isDefault ? cx_->parserNames().default_ : localName;
RootedAtom localName(cx_, cls.names()->innerBinding()->atom());
RootedAtom exportName(
cx_, isDefault ? cx_->names().default_ : localName.get());
if (!appendExportEntry(exportName, localName)) {
return false;
}
@ -1498,6 +1469,8 @@ bool ModuleBuilder::processExport(frontend::ParseNode* exportNode) {
case ParseNodeKind::VarStmt:
case ParseNodeKind::ConstDecl:
case ParseNodeKind::LetDecl: {
RootedAtom localName(cx_);
RootedAtom exportName(cx_);
for (ParseNode* binding : kid->as<ListNode>().contents()) {
if (binding->isKind(ParseNodeKind::AssignExpr)) {
binding = binding->as<AssignmentNode>().left();
@ -1506,10 +1479,8 @@ bool ModuleBuilder::processExport(frontend::ParseNode* exportNode) {
}
if (binding->isKind(ParseNodeKind::Name)) {
const frontend::ParserAtom* localName =
binding->as<NameNode>().atom();
const frontend::ParserAtom* exportName =
isDefault ? cx_->parserNames().default_ : localName;
localName = binding->as<NameNode>().atom();
exportName = isDefault ? cx_->names().default_ : localName.get();
if (!appendExportEntry(exportName, localName)) {
return false;
}
@ -1530,9 +1501,10 @@ bool ModuleBuilder::processExport(frontend::ParseNode* exportNode) {
case ParseNodeKind::Function: {
FunctionBox* box = kid->as<FunctionNode>().funbox();
MOZ_ASSERT(!box->isArrow());
const frontend::ParserAtom* localName = box->explicitName();
const frontend::ParserAtom* exportName =
isDefault ? cx_->parserNames().default_ : localName;
RootedAtom localName(cx_, box->explicitName());
RootedAtom exportName(
cx_, isDefault ? cx_->names().default_ : localName.get());
MOZ_ASSERT_IF(isDefault, localName);
if (!appendExportEntry(exportName, localName)) {
return false;
}
@ -1550,7 +1522,7 @@ bool ModuleBuilder::processExportBinding(frontend::ParseNode* binding) {
using namespace js::frontend;
if (binding->isKind(ParseNodeKind::Name)) {
const frontend::ParserAtom* name = binding->as<NameNode>().atom();
RootedAtom name(cx_, binding->as<NameNode>().atom());
return appendExportEntry(name, name);
}
@ -1631,28 +1603,27 @@ bool ModuleBuilder::processExportFrom(frontend::BinaryNode* exportNode) {
NameNode* moduleSpec = &exportNode->right()->as<NameNode>();
MOZ_ASSERT(moduleSpec->isKind(ParseNodeKind::StringExpr));
const frontend::ParserAtom* module = moduleSpec->atom();
RootedAtom module(cx_, moduleSpec->atom());
if (!maybeAppendRequestedModule(module, moduleSpec)) {
return false;
}
RootedAtom bindingName(cx_);
RootedAtom exportName(cx_);
for (ParseNode* spec : specList->contents()) {
if (spec->isKind(ParseNodeKind::ExportSpec)) {
NameNode* localNameNode = &spec->as<BinaryNode>().left()->as<NameNode>();
NameNode* exportNameNode =
&spec->as<BinaryNode>().right()->as<NameNode>();
const frontend::ParserAtom* bindingName = localNameNode->atom();
const frontend::ParserAtom* exportName = exportNameNode->atom();
bindingName = localNameNode->atom();
exportName = exportNameNode->atom();
if (!appendExportFromEntry(exportName, module, bindingName,
localNameNode)) {
return false;
}
} else {
MOZ_ASSERT(spec->isKind(ParseNodeKind::ExportBatchSpecStmt));
const frontend::ParserAtom* exportName = cx_->parserNames().star;
exportName = cx_->names().star;
if (!appendExportFromEntry(nullptr, module, exportName, spec)) {
return false;
}
@ -1663,7 +1634,7 @@ bool ModuleBuilder::processExportFrom(frontend::BinaryNode* exportNode) {
}
frontend::StencilModuleEntry* ModuleBuilder::importEntryFor(
const frontend::ParserAtom* localName) const {
JSAtom* localName) const {
MOZ_ASSERT(localName);
auto ptr = importEntries_.lookup(localName);
if (!ptr) {
@ -1673,13 +1644,13 @@ frontend::StencilModuleEntry* ModuleBuilder::importEntryFor(
return &ptr->value();
}
bool ModuleBuilder::hasExportedName(const frontend::ParserAtom* name) const {
bool ModuleBuilder::hasExportedName(JSAtom* name) const {
MOZ_ASSERT(name);
return exportNames_.has(name);
}
bool ModuleBuilder::appendExportEntry(const frontend::ParserAtom* exportName,
const frontend::ParserAtom* localName,
bool ModuleBuilder::appendExportEntry(HandleAtom exportName,
HandleAtom localName,
frontend::ParseNode* node) {
uint32_t line = 0;
uint32_t column = 0;
@ -1702,10 +1673,10 @@ bool ModuleBuilder::appendExportEntry(const frontend::ParserAtom* exportName,
return true;
}
bool ModuleBuilder::appendExportFromEntry(
const frontend::ParserAtom* exportName,
const frontend::ParserAtom* moduleRequest,
const frontend::ParserAtom* importName, frontend::ParseNode* node) {
bool ModuleBuilder::appendExportFromEntry(HandleAtom exportName,
HandleAtom moduleRequest,
HandleAtom importName,
frontend::ParseNode* node) {
uint32_t line;
uint32_t column;
eitherParser_.computeLineAndColumn(node->pn_pos.begin, &line, &column);
@ -1719,8 +1690,8 @@ bool ModuleBuilder::appendExportFromEntry(
return !exportName || exportNames_.put(exportName);
}
bool ModuleBuilder::maybeAppendRequestedModule(
const frontend::ParserAtom* specifier, frontend::ParseNode* node) {
bool ModuleBuilder::maybeAppendRequestedModule(HandleAtom specifier,
frontend::ParseNode* node) {
if (requestedModuleSpecifiers_.has(specifier)) {
return true;
}

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

@ -2473,13 +2473,7 @@ bool ASTSerializer::statement(ParseNode* pn, MutableHandleValue dst) {
case ParseNodeKind::ContinueStmt: {
LoopControlStatement* node = &pn->as<LoopControlStatement>();
RootedValue label(cx);
RootedAtom pnAtom(cx);
if (node->label()) {
pnAtom.set(parser->liftParserAtomToJSAtom(node->label()));
if (!pnAtom) {
return false;
}
}
RootedAtom pnAtom(cx, node->label());
return optIdentifier(pnAtom, nullptr, &label) &&
(node->isKind(ParseNodeKind::BreakStmt)
? builder.breakStatement(label, &node->pn_pos, dst)
@ -2492,10 +2486,7 @@ bool ASTSerializer::statement(ParseNode* pn, MutableHandleValue dst) {
MOZ_ASSERT(labelNode->pn_pos.encloses(stmtNode->pn_pos));
RootedValue label(cx), stmt(cx);
RootedAtom pnAtom(cx, parser->liftParserAtomToJSAtom(labelNode->label()));
if (!pnAtom.get()) {
return false;
}
RootedAtom pnAtom(cx, labelNode->label());
return identifier(pnAtom, nullptr, &label) &&
statement(stmtNode, &stmt) &&
builder.labeledStatement(label, stmt, &labelNode->pn_pos, dst);
@ -2928,10 +2919,7 @@ bool ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst) {
RootedValue expr(cx);
RootedValue propname(cx);
RootedAtom pnAtom(cx, parser->liftParserAtomToJSAtom(prop->key().atom()));
if (!pnAtom.get()) {
return false;
}
RootedAtom pnAtom(cx, prop->key().atom());
if (isSuper) {
if (!builder.super(&prop->expression().pn_pos, &expr)) {
@ -2989,11 +2977,8 @@ bool ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst) {
NameNode* rawItem = &item->as<NameNode>();
MOZ_ASSERT(callSiteObj->pn_pos.encloses(rawItem->pn_pos));
JSAtom* exprAtom = parser->liftParserAtomToJSAtom(rawItem->atom());
if (!exprAtom) {
return false;
}
RootedValue expr(cx, StringValue(exprAtom));
RootedValue expr(cx);
expr.setString(rawItem->atom());
raw.infallibleAppend(expr);
}
@ -3011,12 +2996,7 @@ bool ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst) {
expr.setUndefined();
} else {
MOZ_ASSERT(cookedItem->isKind(ParseNodeKind::TemplateStringExpr));
JSAtom* exprAtom =
parser->liftParserAtomToJSAtom(cookedItem->as<NameNode>().atom());
if (!exprAtom) {
return false;
}
expr.setString(exprAtom);
expr.setString(cookedItem->as<NameNode>().atom());
}
cooked.infallibleAppend(expr);
}
@ -3270,15 +3250,9 @@ bool ASTSerializer::literal(ParseNode* pn, MutableHandleValue dst) {
RootedValue val(cx);
switch (pn->getKind()) {
case ParseNodeKind::TemplateStringExpr:
case ParseNodeKind::StringExpr: {
JSAtom* exprAtom =
parser->liftParserAtomToJSAtom(pn->as<NameNode>().atom());
if (!exprAtom) {
return false;
}
val.setString(exprAtom);
case ParseNodeKind::StringExpr:
val.setString(pn->as<NameNode>().atom());
break;
}
case ParseNodeKind::RegExpExpr: {
RegExpObject* re =
@ -3441,10 +3415,7 @@ bool ASTSerializer::identifier(HandleAtom atom, TokenPos* pos,
bool ASTSerializer::identifier(NameNode* id, MutableHandleValue dst) {
LOCAL_ASSERT(id->atom());
RootedAtom pnAtom(cx, parser->liftParserAtomToJSAtom(id->atom()));
if (!pnAtom.get()) {
return false;
}
RootedAtom pnAtom(cx, id->atom());
return identifier(pnAtom, &id->pn_pos, dst);
}
@ -3459,13 +3430,7 @@ bool ASTSerializer::function(FunctionNode* funNode, ASTType type,
bool isExpression = funbox->hasExprBody();
RootedValue id(cx);
RootedAtom funcAtom(cx);
if (funbox->explicitName()) {
funcAtom.set(parser->liftParserAtomToJSAtom(funbox->explicitName()));
if (!funcAtom) {
return false;
}
}
RootedAtom funcAtom(cx, funbox->explicitName());
if (!optIdentifier(funcAtom, nullptr, &id)) {
return false;
}

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

@ -10,7 +10,6 @@
#include "frontend/ErrorReporter.h"
#include "frontend/FullParseHandler.h"
#include "frontend/Parser.h"
#include "frontend/ParserAtom.h"
namespace js {
namespace frontend {

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

@ -107,7 +107,6 @@ namespace frontend {
class ErrorReporter;
class FunctionBox;
class ParseNode;
class ParserAtom;
// Compile a module of the given source using the given options.
ModuleObject* CompileModule(JSContext* cx,
@ -175,10 +174,8 @@ MOZ_MUST_USE JSFunction* CompileStandaloneAsyncGenerator(
* Defined in TokenStream.cpp.
*/
bool IsIdentifier(JSLinearString* str);
bool IsIdentifier(const ParserAtom* atom);
bool IsIdentifierNameOrPrivateName(JSLinearString* str);
bool IsIdentifierNameOrPrivateName(const ParserAtom* atom);
/*
* As above, but taking chars + length.
@ -190,7 +187,6 @@ bool IsIdentifierNameOrPrivateName(const Latin1Char* chars, size_t length);
bool IsIdentifierNameOrPrivateName(const char16_t* chars, size_t length);
/* True if str is a keyword. Defined in TokenStream.cpp. */
bool IsKeyword(const ParserAtom* atom);
bool IsKeyword(JSLinearString* str);
class MOZ_STACK_CLASS AutoFrontendTraceLog {

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

@ -29,10 +29,10 @@ bool BreakableControl::patchBreaks(BytecodeEmitter* bce) {
return bce->emitJumpTargetAndPatch(breaks);
}
LabelControl::LabelControl(BytecodeEmitter* bce, const ParserAtom* label,
LabelControl::LabelControl(BytecodeEmitter* bce, JSAtom* label,
BytecodeOffset startOffset)
: BreakableControl(bce, StatementKind::Label),
label_(label),
label_(bce->cx, label),
startOffset_(startOffset) {}
LoopControl::LoopControl(BytecodeEmitter* bce, StatementKind loopKind)

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

@ -16,10 +16,11 @@
#include "ds/Nestable.h" // Nestable
#include "frontend/BytecodeSection.h" // BytecodeOffset
#include "frontend/JumpList.h" // JumpList, JumpTarget
#include "frontend/ParserAtom.h" // ParserAtom
#include "frontend/SharedContext.h" // StatementKind, StatementKindIsLoop, StatementKindIsUnlabeledBreakTarget
#include "frontend/TDZCheckCache.h" // TDZCheckCache
#include "gc/Rooting.h" // RootedAtom, HandleAtom
#include "vm/StencilEnums.h" // TryNoteKind
#include "vm/StringType.h" // JSAtom
namespace js {
namespace frontend {
@ -70,16 +71,15 @@ inline bool NestableControl::is<BreakableControl>() const {
}
class LabelControl : public BreakableControl {
const ParserAtom* label_;
RootedAtom label_;
// The code offset when this was pushed. Used for effectfulness checking.
BytecodeOffset startOffset_;
public:
LabelControl(BytecodeEmitter* bce, const ParserAtom* label,
BytecodeOffset startOffset);
LabelControl(BytecodeEmitter* bce, JSAtom* label, BytecodeOffset startOffset);
const ParserAtom* label() const { return label_; }
HandleAtom label() const { return label_; }
BytecodeOffset startOffset() const { return startOffset_; }
};

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

@ -50,7 +50,6 @@
#include "frontend/OptionalEmitter.h" // OptionalEmitter
#include "frontend/ParseNode.h" // ParseNodeKind, ParseNode and subclasses
#include "frontend/Parser.h" // Parser
#include "frontend/ParserAtom.h" // ParserAtomsTable
#include "frontend/PropOpEmitter.h" // PropOpEmitter
#include "frontend/SourceNotes.h" // SrcNote, SrcNoteType, SrcNoteWriter
#include "frontend/SwitchEmitter.h" // SwitchEmitter
@ -173,17 +172,17 @@ T* BytecodeEmitter::findInnermostNestableControl(Predicate predicate) const {
return NestableControl::findNearest<T>(innermostNestableControl, predicate);
}
NameLocation BytecodeEmitter::lookupName(const ParserAtom* name) {
NameLocation BytecodeEmitter::lookupName(JSAtom* name) {
return innermostEmitterScope()->lookup(this, name);
}
Maybe<NameLocation> BytecodeEmitter::locationOfNameBoundInScope(
const ParserAtom* name, EmitterScope* target) {
JSAtom* name, EmitterScope* target) {
return innermostEmitterScope()->locationBoundInScope(name, target);
}
Maybe<NameLocation> BytecodeEmitter::locationOfNameBoundInFunctionScope(
const ParserAtom* name, EmitterScope* source) {
JSAtom* name, EmitterScope* source) {
EmitterScope* funScope = source;
while (!funScope->scope(this).is<FunctionScope>()) {
funScope = funScope->enclosingInFrame();
@ -904,7 +903,7 @@ bool BytecodeEmitter::emitGCIndexOp(JSOp op, GCThingIndex index) {
return true;
}
bool BytecodeEmitter::emitAtomOp(JSOp op, const ParserAtom* atom,
bool BytecodeEmitter::emitAtomOp(JSOp op, JSAtom* atom,
ShouldInstrument shouldInstrument) {
MOZ_ASSERT(atom);
@ -1657,9 +1656,8 @@ bool BytecodeEmitter::iteratorResultShape(GCThingIndex* shape) {
data.writer().beginObject(flags);
using WellKnownName = js::frontend::WellKnownParserAtoms;
for (auto name : {&WellKnownName::value, &WellKnownName::done}) {
const ParserAtom* propName = cx->parserNames().*name;
for (auto name : {&JSAtomState::value, &JSAtomState::done}) {
HandlePropertyName propName = cx->parserNames().*name;
uint32_t propNameIndex = 0;
if (!data.addAtom(propName, &propNameIndex)) {
@ -1696,7 +1694,7 @@ bool BytecodeEmitter::emitFinishIteratorResult(bool done) {
return true;
}
bool BytecodeEmitter::emitGetNameAtLocation(const ParserAtom* name,
bool BytecodeEmitter::emitGetNameAtLocation(Handle<JSAtom*> name,
const NameLocation& loc) {
NameOpEmitter noe(this, name, loc, NameOpEmitter::Kind::Get);
if (!noe.emitGet()) {
@ -1709,7 +1707,7 @@ bool BytecodeEmitter::emitGetNameAtLocation(const ParserAtom* name,
bool BytecodeEmitter::emitGetName(NameNode* name) {
MOZ_ASSERT(name->isKind(ParseNodeKind::Name));
const ParserAtom* nameAtom = name->name();
RootedAtom nameAtom(cx, name->name());
return emitGetName(nameAtom);
}
@ -1718,7 +1716,9 @@ bool BytecodeEmitter::emitGetPrivateName(NameNode* name) {
return emitGetPrivateName(name->name());
}
bool BytecodeEmitter::emitGetPrivateName(const ParserAtom* nameAtom) {
bool BytecodeEmitter::emitGetPrivateName(JSAtom* name) {
RootedAtom nameAtom(cx, name);
// The parser ensures the private name is present on the environment chain.
NameLocation location = lookupName(nameAtom);
MOZ_ASSERT(location.kind() == NameLocation::Kind::FrameSlot ||
@ -1728,7 +1728,7 @@ bool BytecodeEmitter::emitGetPrivateName(const ParserAtom* nameAtom) {
return emitGetNameAtLocation(nameAtom, location);
}
bool BytecodeEmitter::emitTDZCheckIfNeeded(const ParserAtom* name,
bool BytecodeEmitter::emitTDZCheckIfNeeded(HandleAtom name,
const NameLocation& loc,
ValueIsOnStack isOnStack) {
// Dynamic accesses have TDZ checks built into their VM code and should
@ -1876,7 +1876,7 @@ bool BytecodeEmitter::emitNameIncDec(UnaryNode* incDec) {
ParseNodeKind kind = incDec->getKind();
NameNode* name = &incDec->kid()->as<NameNode>();
const ParserAtom* nameAtom = name->atom();
RootedAtom nameAtom(cx, name->atom());
NameOpEmitter noe(this, nameAtom,
kind == ParseNodeKind::PostIncrementExpr
? NameOpEmitter::Kind::PostIncrement
@ -2306,7 +2306,7 @@ bool BytecodeEmitter::emitSetThis(BinaryNode* setThisNode) {
MOZ_ASSERT(setThisNode->isKind(ParseNodeKind::SetThis));
MOZ_ASSERT(setThisNode->left()->isKind(ParseNodeKind::Name));
const ParserAtom* name = setThisNode->left()->as<NameNode>().name();
RootedAtom name(cx, setThisNode->left()->as<NameNode>().name());
// The 'this' binding is not lexical, but due to super() semantics this
// initialization needs to be treated as a lexical one.
@ -2473,12 +2473,12 @@ bool BytecodeEmitter::emitScript(ParseNode* body) {
return false;
}
if (!NameFunctions(cx, compilationInfo, body)) {
if (!NameFunctions(cx, body)) {
return false;
}
// Create a Stencil and convert it into a JSScript.
return intoScriptStencil(&compilationInfo.topLevel.get());
return intoScriptStencil(compilationInfo.topLevel.address());
}
js::UniquePtr<ImmutableScriptData> BytecodeEmitter::createImmutableScriptData(
@ -2552,7 +2552,7 @@ bool BytecodeEmitter::emitFunctionScript(FunctionNode* funNode,
}
if (isTopLevel == TopLevelFunction::Yes) {
if (!NameFunctions(cx, compilationInfo, funNode)) {
if (!NameFunctions(cx, funNode)) {
return false;
}
}
@ -2691,7 +2691,7 @@ bool BytecodeEmitter::emitSetOrInitializeDestructuring(
} else {
switch (target->getKind()) {
case ParseNodeKind::Name: {
const ParserAtom* name = target->as<NameNode>().name();
RootedAtom name(cx, target->as<NameNode>().name());
NameLocation loc = lookupName(name);
NameOpEmitter::Kind kind;
switch (flav) {
@ -3095,7 +3095,7 @@ bool BytecodeEmitter::emitDefault(ParseNode* defaultExpr, ParseNode* pattern) {
}
bool BytecodeEmitter::emitAnonymousFunctionWithName(ParseNode* node,
const ParserAtom* name) {
HandleAtom name) {
MOZ_ASSERT(node->isDirectRHSAnonFunction());
if (node->is<FunctionNode>()) {
@ -3139,7 +3139,7 @@ bool BytecodeEmitter::emitAnonymousFunctionWithComputedName(
return emitClass(&node->as<ClassNode>(), ClassNameKind::ComputedName);
}
bool BytecodeEmitter::setFunName(FunctionBox* funbox, const ParserAtom* name) {
bool BytecodeEmitter::setFunName(FunctionBox* funbox, JSAtom* name) {
// The inferred name may already be set if this function is an interpreted
// lazy function and we OOM'ed after we set the inferred name the first
// time.
@ -3158,7 +3158,7 @@ bool BytecodeEmitter::emitInitializer(ParseNode* initializer,
ParseNode* pattern) {
if (initializer->isDirectRHSAnonFunction()) {
MOZ_ASSERT(!pattern->isInParens());
const ParserAtom* name = pattern->as<NameNode>().name();
RootedAtom name(cx, pattern->as<NameNode>().name());
if (!emitAnonymousFunctionWithName(initializer, name)) {
return false;
}
@ -3836,7 +3836,7 @@ bool BytecodeEmitter::emitDestructuringObjRestExclusionSet(ListNode* pattern) {
}
}
const ParserAtom* pnatom = nullptr;
RootedAtom pnatom(cx);
for (ParseNode* member : pattern->contents()) {
if (member->isKind(ParseNodeKind::Spread)) {
MOZ_ASSERT(!member->pn_next, "unexpected trailing element after spread");
@ -3845,7 +3845,7 @@ bool BytecodeEmitter::emitDestructuringObjRestExclusionSet(ListNode* pattern) {
bool isIndex = false;
if (member->isKind(ParseNodeKind::MutateProto)) {
pnatom = cx->parserNames().proto;
pnatom.set(cx->parserNames().proto);
} else {
ParseNode* key = member->as<BinaryNode>().left();
if (key->isKind(ParseNodeKind::NumberExpr)) {
@ -3860,7 +3860,7 @@ bool BytecodeEmitter::emitDestructuringObjRestExclusionSet(ListNode* pattern) {
isIndex = true;
} else if (key->isKind(ParseNodeKind::ObjectPropertyName) ||
key->isKind(ParseNodeKind::StringExpr)) {
pnatom = key->as<NameNode>().atom();
pnatom.set(key->as<NameNode>().atom());
} else {
// Otherwise this is a computed property name which needs to
// be added dynamically.
@ -3906,7 +3906,7 @@ bool BytecodeEmitter::emitTemplateString(ListNode* templateString) {
// Skip empty strings. These are very common: a template string like
// `${a}${b}` has three empty strings and without this optimization
// we'd emit four JSOp::Add operations instead of just one.
if (isString && item->as<NameNode>().atom()->length() == 0) {
if (isString && item->as<NameNode>().atom()->empty()) {
continue;
}
@ -4006,7 +4006,7 @@ bool BytecodeEmitter::emitSingleDeclaration(ListNode* declList, NameNode* decl,
return true;
}
const ParserAtom* nameAtom = decl->name();
RootedAtom nameAtom(cx, decl->name());
NameOpEmitter noe(this, nameAtom, NameOpEmitter::Kind::Initialize);
if (!noe.prepareForRhs()) {
// [stack] ENV?
@ -4049,7 +4049,7 @@ bool BytecodeEmitter::emitSingleDeclaration(ListNode* declList, NameNode* decl,
}
bool BytecodeEmitter::emitAssignmentRhs(ParseNode* rhs,
const ParserAtom* anonFunctionName) {
HandleAtom anonFunctionName) {
if (rhs->isDirectRHSAnonFunction()) {
if (anonFunctionName) {
return emitAnonymousFunctionWithName(rhs, anonFunctionName);
@ -4121,7 +4121,7 @@ bool BytecodeEmitter::emitAssignmentOrInit(ParseNodeKind kind, ParseNode* lhs,
lhs->isKind(ParseNodeKind::ElemExpr));
// |name| is used within NameOpEmitter, so its lifetime must surpass |noe|.
const ParserAtom* name = nullptr;
RootedAtom name(cx);
Maybe<NameOpEmitter> noe;
Maybe<PropOpEmitter> poe;
@ -4142,7 +4142,7 @@ bool BytecodeEmitter::emitAssignmentOrInit(ParseNodeKind kind, ParseNode* lhs,
// implemented via a property or elem assignment (where we are now), and
// rhs->isDirectRHSAnonFunction() is set - so we'll assign the name of the
// function.
const ParserAtom* anonFunctionName = nullptr;
RootedAtom anonFunctionName(cx);
switch (lhs->getKind()) {
case ParseNodeKind::Name: {
@ -4165,7 +4165,7 @@ bool BytecodeEmitter::emitAssignmentOrInit(ParseNodeKind kind, ParseNode* lhs,
if (!poe->prepareForObj()) {
return false;
}
anonFunctionName = prop->name();
anonFunctionName = &prop->name();
if (isSuper) {
UnaryNode* base = &prop->expression().as<UnaryNode>();
if (!emitGetThisForSuperBase(base)) {
@ -4388,7 +4388,7 @@ bool BytecodeEmitter::emitShortCircuitAssignment(AssignmentNode* node) {
ParseNode* rhs = node->right();
// |name| is used within NameOpEmitter, so its lifetime must surpass |noe|.
const ParserAtom* name = nullptr;
RootedAtom name(cx);
// Select the appropriate emitter based on the left-hand side.
Maybe<NameOpEmitter> noe;
@ -5338,7 +5338,7 @@ bool BytecodeEmitter::emitInitializeForInOrOfTarget(TernaryNode* forHead) {
}
if (nameNode) {
const ParserAtom* nameAtom = nameNode->name();
RootedAtom nameAtom(cx, nameNode->name());
NameOpEmitter noe(this, nameAtom, NameOpEmitter::Kind::Initialize);
if (!noe.prepareForRhs()) {
return false;
@ -5476,7 +5476,7 @@ bool BytecodeEmitter::emitForIn(ForNode* forInLoop,
return false;
}
const ParserAtom* nameAtom = nameNode->name();
RootedAtom nameAtom(cx, nameNode->name());
NameOpEmitter noe(this, nameAtom, NameOpEmitter::Kind::Initialize);
if (!noe.prepareForRhs()) {
return false;
@ -5853,7 +5853,7 @@ bool BytecodeEmitter::emitWhile(BinaryNode* whileNode) {
return true;
}
bool BytecodeEmitter::emitBreak(const ParserName* label) {
bool BytecodeEmitter::emitBreak(PropertyName* label) {
BreakableControl* target;
if (label) {
// Any statement with the matching label may be the break target.
@ -5871,7 +5871,7 @@ bool BytecodeEmitter::emitBreak(const ParserName* label) {
return emitGoto(target, &target->breaks, GotoKind::Break);
}
bool BytecodeEmitter::emitContinue(const ParserName* label) {
bool BytecodeEmitter::emitContinue(PropertyName* label) {
LoopControl* target = nullptr;
if (label) {
// Find the loop statement enclosed by the matching label.
@ -7054,8 +7054,7 @@ bool BytecodeEmitter::emitDeleteElementInOptChain(PropertyByValueBase* elemExpr,
return true;
}
static const char* SelfHostedCallFunctionName(const ParserAtom* name,
JSContext* cx) {
static const char* SelfHostedCallFunctionName(JSAtom* name, JSContext* cx) {
if (name == cx->parserNames().callFunction) {
return "callFunction";
}
@ -7176,7 +7175,7 @@ bool BytecodeEmitter::emitSelfHostedResumeGenerator(BinaryNode* callNode) {
ParseNode* kindNode = valNode->pn_next;
MOZ_ASSERT(kindNode->isKind(ParseNodeKind::StringExpr));
GeneratorResumeKind kind =
ParserAtomToResumeKind(compilationInfo, kindNode->as<NameNode>().atom());
AtomToResumeKind(cx, kindNode->as<NameNode>().atom());
MOZ_ASSERT(!kindNode->pn_next);
if (!emitPushResumeKind(kind)) {
@ -7347,7 +7346,7 @@ bool BytecodeEmitter::emitSelfHostedGetBuiltinConstructorOrPrototype(
return false;
}
const ParserAtom* name = argNode->as<NameNode>().atom();
JSAtom* name = argNode->as<NameNode>().atom();
BuiltinObjectKind kind;
if (isConstructor) {
@ -7440,14 +7439,14 @@ bool BytecodeEmitter::isRestParameter(ParseNode* expr) {
expr->as<BinaryNode>().right()->as<ListNode>().head());
}
const ParserAtom* name = expr->as<NameNode>().name();
JSAtom* name = expr->as<NameNode>().name();
Maybe<NameLocation> paramLoc = locationOfNameBoundInFunctionScope(name);
if (paramLoc && lookupName(name) == *paramLoc) {
ParserFunctionScopeData* bindings = funbox->functionScopeBindings();
FunctionScope::Data* bindings = funbox->functionScopeBindings();
if (bindings->nonPositionalFormalStart > 0) {
// |paramName| can be nullptr when the rest destructuring syntax is
// used: `function f(...[]) {}`.
const ParserAtom* paramName =
JSAtom* paramName =
bindings->trailingNames[bindings->nonPositionalFormalStart - 1]
.name();
return paramName && name == paramName;
@ -7475,7 +7474,7 @@ bool BytecodeEmitter::emitOptionalCalleeAndThis(ParseNode* callee,
switch (ParseNodeKind kind = callee->getKind()) {
case ParseNodeKind::Name: {
const ParserAtom* nameAtom = callee->as<NameNode>().name();
RootedAtom nameAtom(cx, callee->as<NameNode>().name());
if (!cone.emitNameCallee(nameAtom)) {
// [stack] CALLEE THIS
return false;
@ -7571,7 +7570,7 @@ bool BytecodeEmitter::emitCalleeAndThis(ParseNode* callee, ParseNode* call,
CallOrNewEmitter& cone) {
switch (callee->getKind()) {
case ParseNodeKind::Name: {
const ParserAtom* nameAtom = callee->as<NameNode>().name();
RootedAtom nameAtom(cx, callee->as<NameNode>().name());
if (!cone.emitNameCallee(nameAtom)) {
// [stack] CALLEE THIS
return false;
@ -7866,7 +7865,7 @@ bool BytecodeEmitter::emitCallOrNew(
// Calls to "forceInterpreter", "callFunction",
// "callContentFunction", or "resumeGenerator" in self-hosted
// code generate inline bytecode.
const ParserName* calleeName = calleeNode->as<NameNode>().name();
RootedPropertyName calleeName(cx, calleeNode->as<NameNode>().name());
if (calleeName == cx->parserNames().callFunction ||
calleeName == cx->parserNames().callContentFunction ||
calleeName == cx->parserNames().constructContentFunction) {
@ -8378,7 +8377,7 @@ MOZ_NEVER_INLINE bool BytecodeEmitter::emitIncOrDec(UnaryNode* incDec) {
// the comment on emitSwitch.
MOZ_NEVER_INLINE bool BytecodeEmitter::emitLabeledStatement(
const LabeledStatement* labeledStmt) {
const ParserAtom* name = labeledStmt->label();
RootedAtom name(cx, labeledStmt->label());
LabelEmitter label(this);
label.emitLabel(name);
@ -8528,9 +8527,10 @@ bool BytecodeEmitter::emitPropertyList(ListNode* obj, PropertyEmitter& pe,
// is created elsewhere.
ClassField* field = &propdef->as<ClassField>();
if (field->name().getKind() == ParseNodeKind::ComputedName) {
const ParserName* fieldKeys = field->isStatic()
? cx->parserNames().dotStaticFieldKeys
: cx->parserNames().dotFieldKeys;
auto fieldKeysName = field->isStatic()
? &JSAtomState::dotStaticFieldKeys
: &JSAtomState::dotFieldKeys;
HandlePropertyName fieldKeys = cx->parserNames().*fieldKeysName;
if (!emitGetName(fieldKeys)) {
// [stack] CTOR? OBJ ARRAY
return false;
@ -8642,8 +8642,7 @@ bool BytecodeEmitter::emitPropertyList(ListNode* obj, PropertyEmitter& pe,
if (key->isKind(ParseNodeKind::NumberExpr)) {
MOZ_ASSERT(accessorType == AccessorType::None);
const ParserAtom* keyAtom =
key->as<NumericLiteral>().toAtom(compilationInfo);
RootedAtom keyAtom(cx, key->as<NumericLiteral>().toAtom(cx));
if (!keyAtom) {
return false;
}
@ -8655,7 +8654,7 @@ bool BytecodeEmitter::emitPropertyList(ListNode* obj, PropertyEmitter& pe,
key->isKind(ParseNodeKind::StringExpr)) {
MOZ_ASSERT(accessorType == AccessorType::None);
const ParserAtom* keyAtom = key->as<NameNode>().atom();
RootedAtom keyAtom(cx, key->as<NameNode>().atom());
if (!emitAnonymousFunctionWithName(propVal, keyAtom)) {
// [stack] CTOR? OBJ CTOR? VAL
return false;
@ -8760,7 +8759,7 @@ bool BytecodeEmitter::emitPropertyList(ListNode* obj, PropertyEmitter& pe,
return false;
}
const ParserAtom* keyAtom = key->as<NameNode>().atom();
RootedAtom keyAtom(cx, key->as<NameNode>().atom());
if (!pe.emitInit(accessorType, keyAtom)) {
return false;
@ -8906,7 +8905,7 @@ bool BytecodeEmitter::emitDestructuringRestExclusionSetObjLiteral(
break;
}
const ParserAtom* atom = nullptr;
JSAtom* atom;
if (member->isKind(ParseNodeKind::MutateProto)) {
atom = cx->parserNames().proto;
} else {
@ -9095,8 +9094,9 @@ bool BytecodeEmitter::emitCreateFieldKeys(ListNode* obj,
return true;
}
const ParserName* fieldKeys = isStatic ? cx->parserNames().dotStaticFieldKeys
: cx->parserNames().dotFieldKeys;
auto fieldKeysName =
isStatic ? &JSAtomState::dotStaticFieldKeys : &JSAtomState::dotFieldKeys;
HandlePropertyName fieldKeys = cx->parserNames().*fieldKeysName;
NameOpEmitter noe(this, fieldKeys, NameOpEmitter::Kind::Initialize);
if (!noe.prepareForRhs()) {
return false;
@ -9246,8 +9246,7 @@ bool BytecodeEmitter::emitPrivateMethodInitializers(ClassEmitter& ce,
default:
MOZ_CRASH("Invalid private method accessor type");
}
const ParserAtom* storedMethodAtom =
storedMethodName.finishParserAtom(compilationInfo);
RootedAtom storedMethodAtom(cx, storedMethodName.finishAtom());
// Emit the private method body and store it as a lexical var.
if (!emitFunction(&propdef->as<ClassMethod>().method())) {
@ -9297,9 +9296,11 @@ bool BytecodeEmitter::emitPrivateMethodInitializers(ClassEmitter& ce,
return true;
}
bool BytecodeEmitter::emitPrivateMethodInitializer(
ClassEmitter& ce, ParseNode* prop, ParseNode* propName,
const ParserAtom* storedMethodAtom, AccessorType accessorType) {
bool BytecodeEmitter::emitPrivateMethodInitializer(ClassEmitter& ce,
ParseNode* prop,
ParseNode* propName,
HandleAtom storedMethodAtom,
AccessorType accessorType) {
// Emit the synthesized initializer function.
FunctionNode* funNode = prop->as<ClassMethod>().initializerIfPrivate();
if (!funNode) {
@ -9548,7 +9549,7 @@ bool BytecodeEmitter::emitInitializeStaticFields(ListNode* classMembers) {
// Overwrite |.staticInitializers| and |.staticFieldKeys| with undefined to
// avoid keeping the arrays alive indefinitely.
auto clearStaticFieldSlot = [&](const ParserName* name) {
auto clearStaticFieldSlot = [&](HandlePropertyName name) {
NameOpEmitter noe(this, name, NameOpEmitter::Kind::SimpleAssignment);
if (!noe.prepareForRhs()) {
// [stack] ENV? VAL?
@ -9953,7 +9954,7 @@ bool BytecodeEmitter::emitFunctionFormalParameters(ListNode* paramsBody) {
return false;
}
} else {
const ParserName* paramName = bindingElement->as<NameNode>().name();
RootedAtom paramName(cx, bindingElement->as<NameNode>().name());
if (!fpe.emitRest(paramName)) {
// [stack]
return false;
@ -10012,7 +10013,7 @@ bool BytecodeEmitter::emitFunctionFormalParameters(ListNode* paramsBody) {
// [stack]
return false;
}
const ParserAtom* paramName = bindingElement->as<NameNode>().name();
RootedAtom paramName(cx, bindingElement->as<NameNode>().name());
if (!fpe.emitDefaultEnd(paramName)) {
// [stack]
return false;
@ -10021,7 +10022,7 @@ bool BytecodeEmitter::emitFunctionFormalParameters(ListNode* paramsBody) {
continue;
}
const ParserAtom* paramName = bindingElement->as<NameNode>().name();
RootedAtom paramName(cx, bindingElement->as<NameNode>().name());
if (!fpe.emitSimple(paramName)) {
// [stack]
return false;
@ -10036,8 +10037,8 @@ bool BytecodeEmitter::emitInitializeFunctionSpecialNames() {
// [stack]
auto emitInitializeFunctionSpecialName = [](BytecodeEmitter* bce,
const ParserName* name, JSOp op) {
auto emitInitializeFunctionSpecialName =
[](BytecodeEmitter* bce, HandlePropertyName name, JSOp op) {
// A special name must be slotful, either on the frame or on the
// call environment.
MOZ_ASSERT(bce->lookupName(name).hasKnownSlot());
@ -10094,10 +10095,11 @@ bool BytecodeEmitter::emitInitializeFunctionSpecialNames() {
}
bool BytecodeEmitter::emitLexicalInitialization(NameNode* name) {
return emitLexicalInitialization(name->name());
RootedAtom nameAtom(cx, name->name());
return emitLexicalInitialization(nameAtom);
}
bool BytecodeEmitter::emitLexicalInitialization(const ParserAtom* name) {
bool BytecodeEmitter::emitLexicalInitialization(Handle<JSAtom*> name) {
NameOpEmitter noe(this, name, NameOpEmitter::Kind::Initialize);
if (!noe.prepareForRhs()) {
return false;
@ -10148,7 +10150,7 @@ bool BytecodeEmitter::emitNewPrivateNames(ListNode* classMembers) {
continue;
}
const ParserAtom* privateName = elementName->as<NameNode>().name();
RootedAtom privateName(cx, elementName->as<NameNode>().name());
// TODO: Add a new bytecode to create private names.
if (!emitAtomOp(JSOp::GetIntrinsic, cx->parserNames().NewPrivateName)) {
@ -10193,9 +10195,9 @@ bool BytecodeEmitter::emitNewPrivateNames(ListNode* classMembers) {
bool BytecodeEmitter::emitClass(
ClassNode* classNode,
ClassNameKind nameKind /* = ClassNameKind::BindingName */,
const ParserAtom* nameForAnonymousClass /* = nullptr */) {
HandleAtom nameForAnonymousClass /* = nullptr */) {
MOZ_ASSERT((nameKind == ClassNameKind::InferredName) ==
bool(nameForAnonymousClass));
(nameForAnonymousClass != nullptr));
ParseNode* heritageExpression = classNode->heritage();
ListNode* classMembers = classNode->memberList();
@ -10207,7 +10209,7 @@ bool BytecodeEmitter::emitClass(
// [stack] NAME
ClassEmitter ce(this);
const ParserAtom* innerName = nullptr;
RootedAtom innerName(cx);
ClassEmitter::Kind kind = ClassEmitter::Kind::Expression;
if (ClassNames* names = classNode->names()) {
MOZ_ASSERT(nameKind == ClassNameKind::BindingName);
@ -10394,7 +10396,8 @@ bool BytecodeEmitter::emitExportDefault(BinaryNode* exportNode) {
if (valueNode->isDirectRHSAnonFunction()) {
MOZ_ASSERT(exportNode->right());
if (!emitAnonymousFunctionWithName(valueNode, cx->parserNames().default_)) {
HandlePropertyName name = cx->parserNames().default_;
if (!emitAnonymousFunctionWithName(valueNode, name)) {
return false;
}
} else {
@ -10458,8 +10461,7 @@ MOZ_NEVER_INLINE bool BytecodeEmitter::emitInstrumentationSlow(
}
// [stack] CALLBACK UNDEFINED
const ParserAtom* atom =
RealmInstrumentation::getInstrumentationKindName(compilationInfo, kind);
JSAtom* atom = RealmInstrumentation::getInstrumentationKindName(cx, kind);
if (!atom) {
return false;
}

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

@ -209,22 +209,22 @@ struct MOZ_STACK_CLASS BytecodeEmitter {
template <typename T, typename Predicate /* (T*) -> bool */>
T* findInnermostNestableControl(Predicate predicate) const;
NameLocation lookupName(const ParserAtom* name);
NameLocation lookupName(JSAtom* name);
// To implement Annex B and the formal parameter defaults scope semantics
// requires accessing names that would otherwise be shadowed. This method
// returns the access location of a name that is known to be bound in a
// target scope.
mozilla::Maybe<NameLocation> locationOfNameBoundInScope(
const ParserAtom* name, EmitterScope* target);
mozilla::Maybe<NameLocation> locationOfNameBoundInScope(JSAtom* name,
EmitterScope* target);
// Get the location of a name known to be bound in the function scope,
// starting at the source scope.
mozilla::Maybe<NameLocation> locationOfNameBoundInFunctionScope(
const ParserAtom* name, EmitterScope* source);
JSAtom* name, EmitterScope* source);
mozilla::Maybe<NameLocation> locationOfNameBoundInFunctionScope(
const ParserAtom* name) {
JSAtom* name) {
return locationOfNameBoundInFunctionScope(name, innermostEmitterScope());
}
@ -240,8 +240,8 @@ struct MOZ_STACK_CLASS BytecodeEmitter {
AbstractScopePtr innermostScope() const;
ScopeIndex innermostScopeIndex() const;
MOZ_ALWAYS_INLINE MOZ_MUST_USE bool makeAtomIndex(const ParserAtom* atom,
GCThingIndex* indexp) {
MOZ_ALWAYS_INLINE
MOZ_MUST_USE bool makeAtomIndex(JSAtom* atom, GCThingIndex* indexp) {
MOZ_ASSERT(perScriptData().atomIndices());
AtomIndexMap::AddPtr p = perScriptData().atomIndices()->lookupForAdd(atom);
if (p) {
@ -456,7 +456,7 @@ struct MOZ_STACK_CLASS BytecodeEmitter {
MOZ_MUST_USE bool emitGCIndexOp(JSOp op, GCThingIndex index);
MOZ_MUST_USE bool emitAtomOp(
JSOp op, const ParserAtom* atom,
JSOp op, JSAtom* atom,
ShouldInstrument shouldInstrument = ShouldInstrument::No);
MOZ_MUST_USE bool emitAtomOp(
JSOp op, GCThingIndex atomIndex,
@ -518,9 +518,11 @@ struct MOZ_STACK_CLASS BytecodeEmitter {
MOZ_MUST_USE bool emitPrivateMethodInitializers(ClassEmitter& ce,
ListNode* obj);
MOZ_MUST_USE bool emitPrivateMethodInitializer(
ClassEmitter& ce, ParseNode* prop, ParseNode* propName,
const ParserAtom* storedMethodAtom, AccessorType accessorType);
MOZ_MUST_USE bool emitPrivateMethodInitializer(ClassEmitter& ce,
ParseNode* prop,
ParseNode* propName,
HandleAtom storedMethodAtom,
AccessorType accessorType);
// To catch accidental misuse, emitUint16Operand/emit3 assert that they are
// not used to unconditionally emit JSOp::GetLocal. Variable access should
@ -532,16 +534,23 @@ struct MOZ_STACK_CLASS BytecodeEmitter {
MOZ_MUST_USE bool emitArgOp(JSOp op, uint16_t slot);
MOZ_MUST_USE bool emitEnvCoordOp(JSOp op, EnvironmentCoordinate ec);
MOZ_MUST_USE bool emitGetNameAtLocation(const ParserAtom* name,
MOZ_MUST_USE bool emitGetNameAtLocation(Handle<JSAtom*> name,
const NameLocation& loc);
MOZ_MUST_USE bool emitGetName(const ParserAtom* name) {
MOZ_MUST_USE bool emitGetNameAtLocation(ImmutablePropertyNamePtr name,
const NameLocation& loc) {
return emitGetNameAtLocation(name.toHandle(), loc);
}
MOZ_MUST_USE bool emitGetName(Handle<JSAtom*> name) {
return emitGetNameAtLocation(name, lookupName(name));
}
MOZ_MUST_USE bool emitGetName(ImmutablePropertyNamePtr name) {
return emitGetNameAtLocation(name, lookupName(name));
}
MOZ_MUST_USE bool emitGetName(NameNode* name);
MOZ_MUST_USE bool emitGetPrivateName(NameNode* name);
MOZ_MUST_USE bool emitGetPrivateName(const ParserAtom* name);
MOZ_MUST_USE bool emitGetPrivateName(JSAtom* name);
MOZ_MUST_USE bool emitTDZCheckIfNeeded(const ParserAtom* name,
MOZ_MUST_USE bool emitTDZCheckIfNeeded(HandleAtom name,
const NameLocation& loc,
ValueIsOnStack isOnStack);
@ -551,7 +560,7 @@ struct MOZ_STACK_CLASS BytecodeEmitter {
MOZ_MUST_USE bool emitSingleDeclaration(ListNode* declList, NameNode* decl,
ParseNode* initializer);
MOZ_MUST_USE bool emitAssignmentRhs(ParseNode* rhs,
const ParserAtom* anonFunctionName);
HandleAtom anonFunctionName);
MOZ_MUST_USE bool emitAssignmentRhs(uint8_t offset);
MOZ_MUST_USE bool emitPrepareIteratorResult();
@ -686,12 +695,12 @@ struct MOZ_STACK_CLASS BytecodeEmitter {
MOZ_MUST_USE bool emitDefault(ParseNode* defaultExpr, ParseNode* pattern);
MOZ_MUST_USE bool emitAnonymousFunctionWithName(ParseNode* node,
const ParserAtom* name);
JS::Handle<JSAtom*> name);
MOZ_MUST_USE bool emitAnonymousFunctionWithComputedName(
ParseNode* node, FunctionPrefixKind prefixKind);
MOZ_MUST_USE bool setFunName(FunctionBox* fun, const ParserAtom* name);
MOZ_MUST_USE bool setFunName(FunctionBox* fun, JSAtom* name);
MOZ_MUST_USE bool emitInitializer(ParseNode* initializer, ParseNode* pattern);
MOZ_MUST_USE bool emitCallSiteObjectArray(ListNode* cookedOrRaw,
@ -789,13 +798,13 @@ struct MOZ_STACK_CLASS BytecodeEmitter {
MOZ_MUST_USE bool emitInitializeForInOrOfTarget(TernaryNode* forHead);
MOZ_MUST_USE bool emitBreak(const ParserName* label);
MOZ_MUST_USE bool emitContinue(const ParserName* label);
MOZ_MUST_USE bool emitBreak(PropertyName* label);
MOZ_MUST_USE bool emitContinue(PropertyName* label);
MOZ_MUST_USE bool emitFunctionFormalParameters(ListNode* paramsBody);
MOZ_MUST_USE bool emitInitializeFunctionSpecialNames();
MOZ_MUST_USE bool emitLexicalInitialization(NameNode* name);
MOZ_MUST_USE bool emitLexicalInitialization(const ParserAtom* name);
MOZ_MUST_USE bool emitLexicalInitialization(Handle<JSAtom*> name);
// Emit bytecode for the spread operator.
//
@ -820,8 +829,7 @@ struct MOZ_STACK_CLASS BytecodeEmitter {
MOZ_MUST_USE bool emitClass(
ClassNode* classNode, ClassNameKind nameKind = ClassNameKind::BindingName,
const ParserAtom* nameForAnonymousClass = nullptr);
JS::Handle<JSAtom*> nameForAnonymousClass = nullptr);
MOZ_MUST_USE bool emitSuperElemOperands(
PropertyByValue* elem, EmitElemOption opts = EmitElemOption::Get);
MOZ_MUST_USE bool emitSuperGetElem(PropertyByValue* elem,

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

@ -58,12 +58,8 @@ bool js::frontend::EmitScriptThingsVector(JSContext* cx,
mozilla::Span<JS::GCCellPtr>& output;
bool operator()(const ScriptAtom& data) {
auto maybeAtom = data->toJSAtom(cx);
if (maybeAtom.isErr()) {
return false;
}
MOZ_ASSERT(maybeAtom.unwrap());
output[i] = JS::GCCellPtr(maybeAtom.unwrap());
JSAtom* atom = data;
output[i] = JS::GCCellPtr(atom);
return true;
}
@ -94,7 +90,7 @@ bool js::frontend::EmitScriptThingsVector(JSContext* cx,
bool operator()(const ObjLiteralIndex& index) {
ObjLiteralStencil& data = compilationInfo.objLiteralData[index];
JSObject* obj = data.create(cx, compilationInfo);
JSObject* obj = data.create(cx);
if (!obj) {
return false;
}
@ -167,9 +163,8 @@ void CGScopeNoteList::recordEndImpl(uint32_t index, uint32_t offset) {
list[index].length = offset - list[index].start;
}
JSObject* ObjLiteralStencil::create(JSContext* cx,
CompilationInfo& compilationInfo) const {
return InterpretObjLiteral(cx, compilationInfo, atoms_, writer_);
JSObject* ObjLiteralStencil::create(JSContext* cx) const {
return InterpretObjLiteral(cx, atoms_, writer_);
}
BytecodeSection::BytecodeSection(JSContext* cx, uint32_t lineNum)

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

@ -55,7 +55,7 @@ struct MOZ_STACK_CLASS GCThingList {
explicit GCThingList(JSContext* cx, CompilationInfo& compilationInfo)
: compilationInfo(compilationInfo), vector(cx) {}
MOZ_MUST_USE bool append(const ParserAtom* atom, GCThingIndex* index) {
MOZ_MUST_USE bool append(JSAtom* atom, GCThingIndex* index) {
*index = GCThingIndex(vector.length());
return vector.append(mozilla::AsVariant(std::move(atom)));
}

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

@ -38,7 +38,7 @@ CallOrNewEmitter::CallOrNewEmitter(BytecodeEmitter* bce, JSOp op,
MOZ_ASSERT(isCall() || isNew() || isSuperCall());
}
bool CallOrNewEmitter::emitNameCallee(const ParserAtom* name) {
bool CallOrNewEmitter::emitNameCallee(Handle<JSAtom*> name) {
MOZ_ASSERT(state_ == State::Start);
NameOpEmitter noe(

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

@ -290,7 +290,7 @@ class MOZ_STACK_CLASS CallOrNewEmitter {
}
public:
MOZ_MUST_USE bool emitNameCallee(const ParserAtom* name);
MOZ_MUST_USE bool emitNameCallee(Handle<JSAtom*> name);
MOZ_MUST_USE PropOpEmitter& prepareForPropCallee(bool isSuperProp);
MOZ_MUST_USE ElemOpEmitter& prepareForElemCallee(bool isSuperElem,
bool isPrivateElem);

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

@ -290,14 +290,6 @@ struct MOZ_RAII CompilationInfo : public JS::CustomAutoRooter {
void trace(JSTracer* trc) final;
JSAtom* liftParserAtomToJSAtom(const ParserAtom* parserAtom) {
return parserAtom->toJSAtom(cx).unwrapOr(nullptr);
}
const ParserAtom* lowerJSAtomToParserAtom(JSAtom* atom) {
auto result = parserAtoms.internJSAtom(cx, atom);
return result.unwrapOr(nullptr);
}
// To avoid any misuses, make sure this is neither copyable,
// movable or assignable.
CompilationInfo(const CompilationInfo&) = delete;

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

@ -149,15 +149,6 @@ class EitherParser : public BCEParserHandle {
matcher{offset, line, column};
return parser.match(std::move(matcher));
}
JSAtom* liftParserAtomToJSAtom(const ParserAtom* parserAtom) {
ParserSharedBase& base = parser.match(detail::ParserSharedBaseMatcher());
return base.liftParserAtomToJSAtom(parserAtom);
}
const ParserAtom* lowerJSAtomToParserAtom(JSAtom* atom) {
ParserSharedBase& base = parser.match(detail::ParserSharedBaseMatcher());
return base.lowerJSAtomToParserAtom(atom);
}
};
} /* namespace frontend */

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

@ -34,7 +34,7 @@ bool EmitterScope::ensureCache(BytecodeEmitter* bce) {
}
bool EmitterScope::checkSlotLimits(BytecodeEmitter* bce,
const ParserBindingIter& bi) {
const BindingIter& bi) {
if (bi.nextFrameSlot() >= LOCALNO_LIMIT ||
bi.nextEnvironmentSlot() >= ENVCOORD_SLOT_LIMIT) {
bce->reportError(nullptr, JSMSG_TOO_MANY_LOCALS);
@ -61,7 +61,7 @@ bool EmitterScope::checkEnvironmentChainLength(BytecodeEmitter* bce) {
}
void EmitterScope::updateFrameFixedSlots(BytecodeEmitter* bce,
const ParserBindingIter& bi) {
const BindingIter& bi) {
nextFrameSlot_ = bi.nextFrameSlot();
if (nextFrameSlot_ > bce->maxFixedSlots) {
bce->maxFixedSlots = nextFrameSlot_;
@ -72,7 +72,7 @@ void EmitterScope::updateFrameFixedSlots(BytecodeEmitter* bce,
bce->maxFixedSlots == 0);
}
bool EmitterScope::putNameInCache(BytecodeEmitter* bce, const ParserAtom* name,
bool EmitterScope::putNameInCache(BytecodeEmitter* bce, JSAtom* name,
NameLocation loc) {
NameLocationMap& cache = *nameCache_;
NameLocationMap::AddPtr p = cache.lookupForAdd(name);
@ -85,7 +85,7 @@ bool EmitterScope::putNameInCache(BytecodeEmitter* bce, const ParserAtom* name,
}
Maybe<NameLocation> EmitterScope::lookupInCache(BytecodeEmitter* bce,
const ParserAtom* name) {
JSAtom* name) {
if (NameLocationMap::Ptr p = nameCache_->lookup(name)) {
return Some(p->value().wrapped);
}
@ -128,7 +128,7 @@ mozilla::Maybe<ScopeIndex> EmitterScope::enclosingScopeIndex(
}
/* static */
bool EmitterScope::nameCanBeFree(BytecodeEmitter* bce, const ParserAtom* name) {
bool EmitterScope::nameCanBeFree(BytecodeEmitter* bce, JSAtom* name) {
// '.generator' cannot be accessed by name.
return name != bce->cx->parserNames().dotGenerator;
}
@ -168,9 +168,6 @@ static bool NameIsOnEnvironment(Scope* scope, JSAtom* name) {
/* static */
NameLocation EmitterScope::searchInEnclosingScope(JSAtom* name, Scope* scope,
uint8_t hops) {
// TODO-Stencil
// This needs to be handled properly by snapshotting enclosing scopes.
for (ScopeIter si(scope); si; si++) {
MOZ_ASSERT(NameIsOnEnvironment(si.scope(), name));
@ -287,8 +284,7 @@ NameLocation EmitterScope::searchInEnclosingScope(JSAtom* name, Scope* scope,
MOZ_CRASH("Malformed scope chain");
}
NameLocation EmitterScope::searchAndCache(BytecodeEmitter* bce,
const ParserAtom* name) {
NameLocation EmitterScope::searchAndCache(BytecodeEmitter* bce, JSAtom* name) {
Maybe<NameLocation> loc;
uint8_t hops = hasEnvironment() ? 1 : 0;
DebugOnly<bool> inCurrentScript = enclosingInFrame();
@ -317,25 +313,9 @@ NameLocation EmitterScope::searchAndCache(BytecodeEmitter* bce,
// If the name is not found in the current compilation, walk the Scope
// chain encompassing the compilation.
if (!loc) {
// TODO-Stencil
// Here, we convert our name into a JSAtom*, and hard-crash on failure
// to allocate. This conversion should not be required as we should be
// able to iterate up snapshotted scope chains that use parser atoms.
//
// This will be fixed when parser scopes are snapshotted, and
// `searchInEnclosingScope` changes to accepting a `const ParserAtom*`
// instead of a `JSAtom*`.
//
// See bug 1660275.
AutoEnterOOMUnsafeRegion oomUnsafe;
JSAtom* jsname = bce->compilationInfo.liftParserAtomToJSAtom(name);
if (!jsname) {
oomUnsafe.crash("EmitterScope::searchAndCache");
}
inCurrentScript = false;
loc = Some(searchInEnclosingScope(
jsname, bce->compilationInfo.enclosingScope, hops));
loc = Some(searchInEnclosingScope(name, bce->compilationInfo.enclosingScope,
hops));
}
// Each script has its own frame. A free name that is accessed
@ -433,7 +413,7 @@ void EmitterScope::dump(BytecodeEmitter* bce) {
for (NameLocationMap::Range r = nameCache_->all(); !r.empty(); r.popFront()) {
const NameLocation& l = r.front().value();
UniqueChars bytes = ParserAtomToPrintableString(bce->cx, r.front().key());
UniqueChars bytes = AtomToPrintableString(bce->cx, r.front().key());
if (!bytes) {
return;
}
@ -481,7 +461,7 @@ void EmitterScope::dump(BytecodeEmitter* bce) {
}
bool EmitterScope::enterLexical(BytecodeEmitter* bce, ScopeKind kind,
ParserLexicalScopeData* bindings) {
Handle<LexicalScope::Data*> bindings) {
MOZ_ASSERT(kind != ScopeKind::NamedLambda &&
kind != ScopeKind::StrictNamedLambda);
MOZ_ASSERT(this == bce->innermostEmitterScopeNoCheck());
@ -493,7 +473,7 @@ bool EmitterScope::enterLexical(BytecodeEmitter* bce, ScopeKind kind,
// Resolve bindings.
TDZCheckCache* tdzCache = bce->innermostTDZCheckCache;
uint32_t firstFrameSlot = frameSlotStart();
ParserBindingIter bi(*bindings, firstFrameSlot, /* isNamedLambda = */ false);
BindingIter bi(*bindings, firstFrameSlot, /* isNamedLambda = */ false);
for (; bi; bi++) {
if (!checkSlotLimits(bce, bi)) {
return false;
@ -554,7 +534,7 @@ bool EmitterScope::enterNamedLambda(BytecodeEmitter* bce, FunctionBox* funbox) {
return false;
}
ParserBindingIter bi(*funbox->namedLambdaBindings(), LOCALNO_LIMIT,
BindingIter bi(*funbox->namedLambdaBindings(), LOCALNO_LIMIT,
/* isNamedLambda = */ true);
MOZ_ASSERT(bi.kind() == BindingKind::NamedLambdaCallee);
@ -602,7 +582,7 @@ bool EmitterScope::enterFunction(BytecodeEmitter* bce, FunctionBox* funbox) {
if (bindings) {
NameLocationMap& cache = *nameCache_;
ParserBindingIter bi(*bindings, funbox->hasParameterExprs);
BindingIter bi(*bindings, funbox->hasParameterExprs);
for (; bi; bi++) {
if (!checkSlotLimits(bce, bi)) {
return false;
@ -644,7 +624,7 @@ bool EmitterScope::enterFunction(BytecodeEmitter* bce, FunctionBox* funbox) {
// bindings and have TDZ.
if (funbox->hasParameterExprs && nextFrameSlot_) {
uint32_t paramFrameSlotEnd = 0;
for (ParserBindingIter bi(*bindings, true); bi; bi++) {
for (BindingIter bi(*bindings, true); bi; bi++) {
if (!BindingKindIsLexical(bi.kind())) {
break;
}
@ -695,7 +675,7 @@ bool EmitterScope::enterFunctionExtraBodyVar(BytecodeEmitter* bce,
// Resolve body-level bindings, if there are any.
uint32_t firstFrameSlot = frameSlotStart();
if (auto bindings = funbox->extraVarScopeBindings()) {
ParserBindingIter bi(*bindings, firstFrameSlot);
BindingIter bi(*bindings, firstFrameSlot);
for (; bi; bi++) {
if (!checkSlotLimits(bce, bi)) {
return false;
@ -748,13 +728,13 @@ bool EmitterScope::enterFunctionExtraBodyVar(BytecodeEmitter* bce,
return checkEnvironmentChainLength(bce);
}
class DynamicBindingIter : public ParserBindingIter {
class DynamicBindingIter : public BindingIter {
public:
explicit DynamicBindingIter(GlobalSharedContext* sc)
: ParserBindingIter(*sc->bindings) {}
: BindingIter(*sc->bindings) {}
explicit DynamicBindingIter(EvalSharedContext* sc)
: ParserBindingIter(*sc->bindings, /* strict = */ false) {
: BindingIter(*sc->bindings, /* strict = */ false) {
MOZ_ASSERT(!sc->strict());
}
@ -776,11 +756,6 @@ bool EmitterScope::enterGlobal(BytecodeEmitter* bce,
GlobalSharedContext* globalsc) {
MOZ_ASSERT(this == bce->innermostEmitterScopeNoCheck());
// TODO-Stencil
// This is another snapshot-sensitive location.
// The incoming atoms from the global scope object should be snapshotted.
// For now, converting them to ParserAtoms here individually.
bce->setVarEmitterScope(this);
if (!ensureCache(bce)) {
@ -825,7 +800,7 @@ bool EmitterScope::enterGlobal(BytecodeEmitter* bce,
for (DynamicBindingIter bi(globalsc); bi; bi++) {
NameLocation loc = NameLocation::fromBinding(bi.kind(), bi.location());
const ParserAtom* name = bi.name();
JSAtom* name = bi.name();
if (!putNameInCache(bce, name, loc)) {
return false;
}
@ -935,8 +910,8 @@ bool EmitterScope::enterModule(BytecodeEmitter* bce,
// Resolve body-level bindings, if there are any.
TDZCheckCache* tdzCache = bce->innermostTDZCheckCache;
Maybe<uint32_t> firstLexicalFrameSlot;
if (ParserModuleScopeData* bindings = modulesc->bindings) {
ParserBindingIter bi(*bindings);
if (ModuleScope::Data* bindings = modulesc->bindings) {
BindingIter bi(*bindings);
for (; bi; bi++) {
if (!checkSlotLimits(bce, bi)) {
return false;
@ -1092,15 +1067,14 @@ mozilla::Maybe<ScopeIndex> EmitterScope::scopeIndex(
return bce->perScriptData().gcThingList().getScopeIndex(index());
}
NameLocation EmitterScope::lookup(BytecodeEmitter* bce,
const ParserAtom* name) {
NameLocation EmitterScope::lookup(BytecodeEmitter* bce, JSAtom* name) {
if (Maybe<NameLocation> loc = lookupInCache(bce, name)) {
return *loc;
}
return searchAndCache(bce, name);
}
Maybe<NameLocation> EmitterScope::locationBoundInScope(const ParserAtom* name,
Maybe<NameLocation> EmitterScope::locationBoundInScope(JSAtom* name,
EmitterScope* target) {
// The target scope must be an intra-frame enclosing scope of this
// one. Count the number of extra hops to reach it.

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

@ -66,27 +66,27 @@ class EmitterScope : public Nestable<EmitterScope> {
MOZ_MUST_USE bool ensureCache(BytecodeEmitter* bce);
MOZ_MUST_USE bool checkSlotLimits(BytecodeEmitter* bce,
const ParserBindingIter& bi);
const BindingIter& bi);
MOZ_MUST_USE bool checkEnvironmentChainLength(BytecodeEmitter* bce);
void updateFrameFixedSlots(BytecodeEmitter* bce, const ParserBindingIter& bi);
void updateFrameFixedSlots(BytecodeEmitter* bce, const BindingIter& bi);
MOZ_MUST_USE bool putNameInCache(BytecodeEmitter* bce, const ParserAtom* name,
MOZ_MUST_USE bool putNameInCache(BytecodeEmitter* bce, JSAtom* name,
NameLocation loc);
mozilla::Maybe<NameLocation> lookupInCache(BytecodeEmitter* bce,
const ParserAtom* name);
JSAtom* name);
EmitterScope* enclosing(BytecodeEmitter** bce) const;
mozilla::Maybe<ScopeIndex> enclosingScopeIndex(BytecodeEmitter* bce) const;
static bool nameCanBeFree(BytecodeEmitter* bce, const ParserAtom* name);
static bool nameCanBeFree(BytecodeEmitter* bce, JSAtom* name);
static NameLocation searchInEnclosingScope(JSAtom* name, Scope* scope,
uint8_t hops);
NameLocation searchAndCache(BytecodeEmitter* bce, const ParserAtom* name);
NameLocation searchAndCache(BytecodeEmitter* bce, JSAtom* name);
MOZ_MUST_USE bool internEmptyGlobalScopeAsBody(BytecodeEmitter* bce);
@ -109,7 +109,7 @@ class EmitterScope : public Nestable<EmitterScope> {
void dump(BytecodeEmitter* bce);
MOZ_MUST_USE bool enterLexical(BytecodeEmitter* bce, ScopeKind kind,
ParserLexicalScopeData* bindings);
Handle<LexicalScope::Data*> bindings);
MOZ_MUST_USE bool enterNamedLambda(BytecodeEmitter* bce, FunctionBox* funbox);
MOZ_MUST_USE bool enterFunction(BytecodeEmitter* bce, FunctionBox* funbox);
MOZ_MUST_USE bool enterFunctionExtraBodyVar(BytecodeEmitter* bce,
@ -152,9 +152,9 @@ class EmitterScope : public Nestable<EmitterScope> {
return Nestable<EmitterScope>::enclosing();
}
NameLocation lookup(BytecodeEmitter* bce, const ParserAtom* name);
NameLocation lookup(BytecodeEmitter* bce, JSAtom* name);
mozilla::Maybe<NameLocation> locationBoundInScope(const ParserAtom* name,
mozilla::Maybe<NameLocation> locationBoundInScope(JSAtom* name,
EmitterScope* target);
};

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

@ -7,7 +7,6 @@
#include "frontend/FoldConstants.h"
#include "mozilla/FloatingPoint.h"
#include "mozilla/Range.h"
#include "jslibmath.h"
#include "jsnum.h"
@ -17,7 +16,6 @@
#include "frontend/Parser.h"
#include "js/Conversions.h"
#include "js/friend/StackLimits.h" // js::CheckRecursionLimit
#include "js/Vector.h"
#include "vm/StringType.h"
using namespace js;
@ -464,7 +462,7 @@ static bool FoldType(FoldInfo info, ParseNode** pnp, ParseNodeKind kind) {
case ParseNodeKind::NumberExpr:
if (pn->isKind(ParseNodeKind::StringExpr)) {
double d;
if (!pn->as<NameNode>().atom()->toNumber(info.cx(), &d)) {
if (!StringToNumber(info.cx(), pn->as<NameNode>().atom(), &d)) {
return false;
}
if (!TryReplaceNode(
@ -476,8 +474,7 @@ static bool FoldType(FoldInfo info, ParseNode** pnp, ParseNodeKind kind) {
case ParseNodeKind::StringExpr:
if (pn->isKind(ParseNodeKind::NumberExpr)) {
const ParserAtom* atom =
pn->as<NumericLiteral>().toAtom(info.compilationInfo);
JSAtom* atom = pn->as<NumericLiteral>().toAtom(info.cx());
if (!atom) {
return false;
}
@ -579,21 +576,21 @@ static bool FoldTypeOfExpr(FoldInfo info, ParseNode** nodePtr) {
ParseNode* expr = node->kid();
// Constant-fold the entire |typeof| if given a constant with known type.
const ParserName* result = nullptr;
RootedPropertyName result(info.cx());
if (expr->isKind(ParseNodeKind::StringExpr) ||
expr->isKind(ParseNodeKind::TemplateStringExpr)) {
result = info.cx()->parserNames().string;
result = info.cx()->names().string;
} else if (expr->isKind(ParseNodeKind::NumberExpr)) {
result = info.cx()->parserNames().number;
result = info.cx()->names().number;
} else if (expr->isKind(ParseNodeKind::BigIntExpr)) {
result = info.cx()->parserNames().bigint;
result = info.cx()->names().bigint;
} else if (expr->isKind(ParseNodeKind::NullExpr)) {
result = info.cx()->parserNames().object;
result = info.cx()->names().object;
} else if (expr->isKind(ParseNodeKind::TrueExpr) ||
expr->isKind(ParseNodeKind::FalseExpr)) {
result = info.cx()->parserNames().boolean;
result = info.cx()->names().boolean;
} else if (expr->is<FunctionNode>()) {
result = info.cx()->parserNames().function;
result = info.cx()->names().function;
}
if (result) {
@ -1084,9 +1081,9 @@ static bool FoldElement(FoldInfo info, ParseNode** nodePtr) {
ParseNode* expr = &elem->expression();
ParseNode* key = &elem->key();
const ParserName* name = nullptr;
PropertyName* name = nullptr;
if (key->isKind(ParseNodeKind::StringExpr)) {
const ParserAtom* atom = key->as<NameNode>().atom();
JSAtom* atom = key->as<NameNode>().atom();
uint32_t index;
if (atom->isIndex(&index)) {
@ -1099,7 +1096,7 @@ static bool FoldElement(FoldInfo info, ParseNode** nodePtr) {
}
key = &elem->key();
} else {
name = atom->asName();
name = atom->asPropertyName();
}
} else if (key->isKind(ParseNodeKind::NumberExpr)) {
auto* numeric = &key->as<NumericLiteral>();
@ -1108,11 +1105,11 @@ static bool FoldElement(FoldInfo info, ParseNode** nodePtr) {
// Optimization 2: We have something like expr[3.14]. The number
// isn't an array index, so it converts to a string ("3.14"),
// enabling optimization 3 below.
const ParserAtom* atom = numeric->toAtom(info.compilationInfo);
JSAtom* atom = numeric->toAtom(info.cx());
if (!atom) {
return false;
}
name = atom->asName();
name = atom->asPropertyName();
}
}
@ -1205,16 +1202,15 @@ static bool FoldAdd(FoldInfo info, ParseNode** nodePtr) {
break;
}
Vector<const ParserAtom*, 8> accum(info.cx());
RootedString combination(info.cx());
RootedString tmp(info.cx());
do {
// Create a vector of all the folded strings and concatenate them.
// Create a rope of the current string and all succeeding
// constants that we can convert to strings, then atomize it
// and replace them all with that fresh string.
MOZ_ASSERT((*current)->isKind(ParseNodeKind::StringExpr));
accum.clear();
const ParserAtom* atom = (*current)->as<NameNode>().atom();
if (!accum.append(atom)) {
return false;
}
combination = (*current)->as<NameNode>().atom();
do {
// Try folding the next operand to a string.
@ -1227,9 +1223,10 @@ static bool FoldAdd(FoldInfo info, ParseNode** nodePtr) {
break;
}
// Add this string to the accumulator and remove the node.
const ParserAtom* nextAtom = (*next)->as<NameNode>().atom();
if (!accum.append(nextAtom)) {
// Add this string to the combination and remove the node.
tmp = (*next)->as<NameNode>().atom();
combination = ConcatStrings<CanGC>(info.cx(), combination, tmp);
if (!combination) {
return false;
}
@ -1239,19 +1236,13 @@ static bool FoldAdd(FoldInfo info, ParseNode** nodePtr) {
node->unsafeDecrementCount();
} while (*next);
// Construct the concatenated atom.
const ParserAtom* combination =
info.compilationInfo.parserAtoms
.concatAtoms(info.cx(),
mozilla::Range(accum.begin(), accum.length()))
.unwrapOr(nullptr);
// Replace |current|'s string with the entire combination.
MOZ_ASSERT((*current)->isKind(ParseNodeKind::StringExpr));
combination = AtomizeString(info.cx(), combination);
if (!combination) {
return false;
}
// Replace |current|'s string with the entire combination.
MOZ_ASSERT((*current)->isKind(ParseNodeKind::StringExpr));
(*current)->as<NameNode>().setAtom(combination);
(*current)->as<NameNode>().setAtom(&combination->asAtom());
// If we're out of nodes, we're done.
if (!*next) {

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

@ -21,22 +21,27 @@
#include "frontend/BytecodeSection.h" // EmitScriptThingsVector
#include "frontend/CompilationInfo.h" // CompilationInfo
#include "frontend/Parser.h" // NewEmptyLexicalScopeData, NewEmptyGlobalScopeData, NewEmptyVarScopeData, NewEmptyFunctionScopeData
#include "frontend/ParserAtom.h" // ParserAtomsTable
#include "frontend/smoosh_generated.h" // CVec, Smoosh*, smoosh_*
#include "frontend/SourceNotes.h" // SrcNote
#include "frontend/Stencil.h" // ScopeStencil, RegExpIndex, FunctionIndex, NullScriptThing
#include "frontend/TokenStream.h" // TokenStreamAnyChars
#include "gc/Rooting.h" // RootedScriptSourceObject
#include "irregexp/RegExpAPI.h" // irregexp::CheckPatternSyntax
#include "js/CharacterEncoding.h" // JS::UTF8Chars, UTF8CharsToNewTwoByteCharsZ
#include "js/GCAPI.h" // JS::AutoCheckCannotGC
#include "js/GCVector.h" // JS::RootedVector
#include "js/HeapAPI.h" // JS::GCCellPtr
#include "js/RegExpFlags.h" // JS::RegExpFlag, JS::RegExpFlags
#include "js/RootingAPI.h" // JS::MutableHandle
#include "js/RootingAPI.h" // JS::Handle, JS::Rooted
#include "js/TypeDecls.h" // Rooted{Script,Value,String,Object}, JS*:HandleVector, JS::MutableHandleVector
#include "js/UniquePtr.h" // js::UniquePtr
#include "js/Utility.h" // JS::UniqueTwoByteChars, StringBufferArena
#include "vm/JSAtom.h" // AtomizeUTF8Chars
#include "vm/JSScript.h" // JSScript
#include "vm/Scope.h" // BindingName
#include "vm/ScopeKind.h" // ScopeKind
#include "vm/SharedStencil.h" // ImmutableScriptData, ScopeNote, TryNote, GCThingIndex
#include "vm/StringType.h" // JSAtom
#include "vm/JSContext-inl.h" // AutoKeepAtoms (used by BytecodeCompiler)
@ -51,10 +56,10 @@ namespace js {
namespace frontend {
// Given the result of SmooshMonkey's parser, Convert the list of atoms into
// the list of ParserAtoms.
// the list of JSAtoms.
bool ConvertAtoms(JSContext* cx, const SmooshResult& result,
CompilationInfo& compilationInfo,
Vector<const ParserAtom*>& allAtoms) {
JS::MutableHandleVector<JSAtom*> allAtoms) {
size_t numAtoms = result.all_atoms_len;
if (!allAtoms.reserve(numAtoms)) {
@ -62,11 +67,9 @@ bool ConvertAtoms(JSContext* cx, const SmooshResult& result,
}
for (size_t i = 0; i < numAtoms; i++) {
auto s = reinterpret_cast<const mozilla::Utf8Unit*>(
smoosh_get_atom_at(result, i));
auto s = smoosh_get_atom_at(result, i);
auto len = smoosh_get_atom_len_at(result, i);
const ParserAtom* atom =
compilationInfo.parserAtoms.internUtf8(cx, s, len).unwrapOr(nullptr);
JSAtom* atom = AtomizeUTF8Chars(cx, s, len);
if (!atom) {
return false;
}
@ -77,22 +80,20 @@ bool ConvertAtoms(JSContext* cx, const SmooshResult& result,
}
void CopyBindingNames(JSContext* cx, CVec<SmooshBindingName>& from,
Vector<const ParserAtom*>& allAtoms,
ParserBindingName* to) {
JS::HandleVector<JSAtom*> allAtoms, BindingName* to) {
// We're setting trailing array's content before setting its length.
JS::AutoCheckCannotGC nogc(cx);
size_t numBindings = from.len;
for (size_t i = 0; i < numBindings; i++) {
SmooshBindingName& name = from.data[i];
new (mozilla::KnownNotNull, &to[i]) ParserBindingName(
new (mozilla::KnownNotNull, &to[i]) BindingName(
allAtoms[name.name], name.is_closed_over, name.is_top_level_function);
}
}
void CopyBindingNames(JSContext* cx, CVec<COption<SmooshBindingName>>& from,
Vector<const ParserAtom*>& allAtoms,
ParserBindingName* to) {
JS::HandleVector<JSAtom*> allAtoms, BindingName* to) {
// We're setting trailing array's content before setting its length.
JS::AutoCheckCannotGC nogc(cx);
@ -101,11 +102,10 @@ void CopyBindingNames(JSContext* cx, CVec<COption<SmooshBindingName>>& from,
COption<SmooshBindingName>& maybeName = from.data[i];
if (maybeName.IsSome()) {
SmooshBindingName& name = maybeName.AsSome();
new (mozilla::KnownNotNull, &to[i]) ParserBindingName(
new (mozilla::KnownNotNull, &to[i]) BindingName(
allAtoms[name.name], name.is_closed_over, name.is_top_level_function);
} else {
new (mozilla::KnownNotNull, &to[i])
ParserBindingName(nullptr, false, false);
new (mozilla::KnownNotNull, &to[i]) BindingName(nullptr, false, false);
}
}
}
@ -113,7 +113,7 @@ void CopyBindingNames(JSContext* cx, CVec<COption<SmooshBindingName>>& from,
// Given the result of SmooshMonkey's parser, convert a list of scope data
// into a list of ScopeStencil.
bool ConvertScopeStencil(JSContext* cx, const SmooshResult& result,
Vector<const ParserAtom*>& allAtoms,
JS::HandleVector<JSAtom*> allAtoms,
CompilationInfo& compilationInfo) {
auto& alloc = compilationInfo.allocScope.alloc();
@ -126,8 +126,8 @@ bool ConvertScopeStencil(JSContext* cx, const SmooshResult& result,
auto& global = scopeData.AsGlobal();
size_t numBindings = global.bindings.len;
ParserGlobalScopeData* data =
NewEmptyGlobalScopeData(cx, alloc, numBindings);
JS::Rooted<GlobalScope::Data*> data(
cx, NewEmptyGlobalScopeData(cx, alloc, numBindings));
if (!data) {
return false;
}
@ -150,8 +150,8 @@ bool ConvertScopeStencil(JSContext* cx, const SmooshResult& result,
size_t numBindings = var.bindings.len;
ParserVarScopeData* data = NewEmptyVarScopeData(cx, alloc, numBindings);
;
JS::Rooted<VarScope::Data*> data(
cx, NewEmptyVarScopeData(cx, alloc, numBindings));
if (!data) {
return false;
}
@ -177,8 +177,8 @@ bool ConvertScopeStencil(JSContext* cx, const SmooshResult& result,
auto& lexical = scopeData.AsLexical();
size_t numBindings = lexical.bindings.len;
ParserLexicalScopeData* data =
NewEmptyLexicalScopeData(cx, alloc, numBindings);
JS::Rooted<LexicalScope::Data*> data(
cx, NewEmptyLexicalScopeData(cx, alloc, numBindings));
if (!data) {
return false;
}
@ -205,8 +205,8 @@ bool ConvertScopeStencil(JSContext* cx, const SmooshResult& result,
auto& function = scopeData.AsFunction();
size_t numBindings = function.bindings.len;
ParserFunctionScopeData* data =
NewEmptyFunctionScopeData(cx, alloc, numBindings);
JS::Rooted<FunctionScope::Data*> data(
cx, NewEmptyFunctionScopeData(cx, alloc, numBindings));
if (!data) {
return false;
}
@ -343,7 +343,7 @@ UniquePtr<ImmutableScriptData> ConvertImmutableScriptData(
// used by a script into ScriptThingsVector.
bool ConvertGCThings(JSContext* cx, const SmooshResult& result,
const SmooshScriptStencil& smooshStencil,
Vector<const ParserAtom*>& allAtoms,
JS::HandleVector<JSAtom*> allAtoms,
MutableHandle<ScriptStencil> stencil) {
auto& gcThings = stencil.get().gcThings;
@ -361,7 +361,8 @@ bool ConvertGCThings(JSContext* cx, const SmooshResult& result,
break;
}
case SmooshGCThing::Tag::Atom: {
gcThings.infallibleAppend(mozilla::AsVariant(allAtoms[item.AsAtom()]));
gcThings.infallibleAppend(
mozilla::AsVariant(allAtoms[item.AsAtom()].get()));
break;
}
case SmooshGCThing::Tag::Function: {
@ -392,7 +393,7 @@ bool ConvertGCThings(JSContext* cx, const SmooshResult& result,
// (until GC things gets removed from stencil) tracing API of the GC.
bool ConvertScriptStencil(JSContext* cx, const SmooshResult& result,
const SmooshScriptStencil& smooshStencil,
Vector<const ParserAtom*>& allAtoms,
JS::HandleVector<JSAtom*> allAtoms,
CompilationInfo& compilationInfo,
MutableHandle<ScriptStencil> stencil) {
using ImmutableFlags = js::ImmutableScriptFlagsEnum;
@ -539,8 +540,8 @@ bool Smoosh::compileGlobalScriptToStencil(CompilationInfo& compilationInfo,
*unimplemented = false;
Vector<const ParserAtom*> allAtoms(cx);
if (!ConvertAtoms(cx, result, compilationInfo, allAtoms)) {
JS::RootedVector<JSAtom*> allAtoms(cx);
if (!ConvertAtoms(cx, result, compilationInfo, &allAtoms)) {
return false;
}

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

@ -51,9 +51,6 @@ class FullParseHandler {
* - lazyOuterFunction_ holds the lazyScript for this current parse
* - lazyInnerFunctionIndex is used as we skip over inner functions
* (see skipLazyInnerFunction),
*
* TODO-Stencil: We probably need to snapshot the atoms from the
* lazyOuterFunction here.
*/
const Rooted<BaseScript*> lazyOuterFunction_;
size_t lazyInnerFunctionIndex;
@ -143,8 +140,7 @@ class FullParseHandler {
// these assumptions.
SourceKind sourceKind() const { return sourceKind_; }
NameNodeType newName(const ParserName* name, const TokenPos& pos,
JSContext* cx) {
NameNodeType newName(PropertyName* name, const TokenPos& pos, JSContext* cx) {
return new_<NameNode>(ParseNodeKind::Name, name, pos);
}
@ -153,12 +149,11 @@ class FullParseHandler {
return new_<UnaryNode>(ParseNodeKind::ComputedName, pos, expr);
}
NameNodeType newObjectLiteralPropertyName(const ParserAtom* atom,
const TokenPos& pos) {
NameNodeType newObjectLiteralPropertyName(JSAtom* atom, const TokenPos& pos) {
return new_<NameNode>(ParseNodeKind::ObjectPropertyName, atom, pos);
}
NameNodeType newPrivateName(const ParserAtom* atom, const TokenPos& pos) {
NameNodeType newPrivateName(JSAtom* atom, const TokenPos& pos) {
return new_<NameNode>(ParseNodeKind::PrivateName, atom, pos);
}
@ -177,12 +172,11 @@ class FullParseHandler {
return new_<BooleanLiteral>(cond, pos);
}
NameNodeType newStringLiteral(const ParserAtom* atom, const TokenPos& pos) {
NameNodeType newStringLiteral(JSAtom* atom, const TokenPos& pos) {
return new_<NameNode>(ParseNodeKind::StringExpr, atom, pos);
}
NameNodeType newTemplateStringLiteral(const ParserAtom* atom,
const TokenPos& pos) {
NameNodeType newTemplateStringLiteral(JSAtom* atom, const TokenPos& pos) {
return new_<NameNode>(ParseNodeKind::TemplateStringExpr, atom, pos);
}
@ -732,12 +726,12 @@ class FullParseHandler {
return new_<CaseClause>(expr, body, begin);
}
ContinueStatementType newContinueStatement(const ParserName* label,
ContinueStatementType newContinueStatement(PropertyName* label,
const TokenPos& pos) {
return new_<ContinueStatement>(label, pos);
}
BreakStatementType newBreakStatement(const ParserName* label,
BreakStatementType newBreakStatement(PropertyName* label,
const TokenPos& pos) {
return new_<BreakStatement>(label, pos);
}
@ -757,7 +751,7 @@ class FullParseHandler {
TokenPos(begin, body->pn_pos.end), expr, body);
}
LabeledStatementType newLabeledStatement(const ParserName* label, Node stmt,
LabeledStatementType newLabeledStatement(PropertyName* label, Node stmt,
uint32_t begin) {
return new_<LabeledStatement>(label, stmt, begin);
}
@ -777,7 +771,7 @@ class FullParseHandler {
return new_<DebuggerStatement>(pos);
}
NameNodeType newPropertyName(const ParserName* name, const TokenPos& pos) {
NameNodeType newPropertyName(PropertyName* name, const TokenPos& pos) {
return new_<NameNode>(ParseNodeKind::PropertyNameExpr, name, pos);
}
@ -869,8 +863,7 @@ class FullParseHandler {
return new_<ModuleNode>(pos);
}
LexicalScopeNodeType newLexicalScope(ParserLexicalScopeData* bindings,
Node body,
LexicalScopeNodeType newLexicalScope(LexicalScope::Data* bindings, Node body,
ScopeKind kind = ScopeKind::Lexical) {
return new_<LexicalScopeNode>(bindings, body, kind);
}
@ -1061,14 +1054,14 @@ class FullParseHandler {
return false;
}
const ParserName* maybeDottedProperty(Node pn) {
return pn->is<PropertyAccessBase>() ? pn->as<PropertyAccessBase>().name()
PropertyName* maybeDottedProperty(Node pn) {
return pn->is<PropertyAccessBase>() ? &pn->as<PropertyAccessBase>().name()
: nullptr;
}
const ParserAtom* isStringExprStatement(Node pn, TokenPos* pos) {
JSAtom* isStringExprStatement(Node pn, TokenPos* pos) {
if (pn->is<UnaryNode>()) {
UnaryNode* unary = &pn->as<UnaryNode>();
if (const ParserAtom* atom = unary->isStringExprStatement()) {
if (JSAtom* atom = unary->isStringExprStatement()) {
*pos = unary->kid()->pn_pos;
return atom;
}

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

@ -35,7 +35,7 @@ FunctionEmitter::FunctionEmitter(BytecodeEmitter* bce, FunctionBox* funbox,
IsHoisted isHoisted)
: bce_(bce),
funbox_(funbox),
name_(funbox_->explicitName()),
name_(bce_->cx, funbox_->explicitName()),
syntaxKind_(syntaxKind),
isHoisted_(isHoisted) {}
@ -515,9 +515,8 @@ bool FunctionScriptEmitter::emitExtraBodyVarScope() {
//
// function f(x, y = 42) { var y; }
//
const ParserAtom* name = nullptr;
for (ParserBindingIter bi(*funbox_->functionScopeBindings(), true); bi;
bi++) {
JS::Rooted<JSAtom*> name(bce_->cx);
for (BindingIter bi(*funbox_->functionScopeBindings(), true); bi; bi++) {
name = bi.name();
// There may not be a var binding of the same name.
@ -699,7 +698,7 @@ bool FunctionScriptEmitter::emitEndBody() {
bool FunctionScriptEmitter::intoStencil() {
MOZ_ASSERT(state_ == State::EndBody);
if (!bce_->intoScriptStencil(&funbox_->functionStencil().get())) {
if (!bce_->intoScriptStencil(funbox_->functionStencil().address())) {
return false;
}
@ -716,7 +715,7 @@ FunctionParamsEmitter::FunctionParamsEmitter(BytecodeEmitter* bce,
funbox_(funbox),
functionEmitterScope_(bce_->innermostEmitterScope()) {}
bool FunctionParamsEmitter::emitSimple(const ParserAtom* paramName) {
bool FunctionParamsEmitter::emitSimple(JS::Handle<JSAtom*> paramName) {
MOZ_ASSERT(state_ == State::Start);
// [stack]
@ -753,7 +752,7 @@ bool FunctionParamsEmitter::prepareForDefault() {
return true;
}
bool FunctionParamsEmitter::emitDefaultEnd(const ParserAtom* paramName) {
bool FunctionParamsEmitter::emitDefaultEnd(JS::Handle<JSAtom*> paramName) {
MOZ_ASSERT(state_ == State::Default);
// [stack] DEFAULT
@ -859,7 +858,7 @@ bool FunctionParamsEmitter::emitDestructuringDefaultEnd() {
return true;
}
bool FunctionParamsEmitter::emitRest(const ParserAtom* paramName) {
bool FunctionParamsEmitter::emitRest(JS::Handle<JSAtom*> paramName) {
MOZ_ASSERT(state_ == State::Start);
// [stack]
@ -950,7 +949,7 @@ bool FunctionParamsEmitter::emitRestArray() {
return true;
}
bool FunctionParamsEmitter::emitAssignment(const ParserAtom* paramName) {
bool FunctionParamsEmitter::emitAssignment(JS::Handle<JSAtom*> paramName) {
// [stack] ARG
NameLocation paramLoc =

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

@ -72,7 +72,7 @@ class MOZ_STACK_CLASS FunctionEmitter {
FunctionBox* funbox_;
// Function's explicit name.
const ParserAtom* name_;
JS::Rooted<JSAtom*> name_;
FunctionSyntaxKind syntaxKind_;
IsHoisted isHoisted_;
@ -410,10 +410,10 @@ class MOZ_STACK_CLASS FunctionParamsEmitter {
// paramName is used only when there's at least one expression in the
// paramerters (funbox_->hasParameterExprs == true).
MOZ_MUST_USE bool emitSimple(const ParserAtom* paramName);
MOZ_MUST_USE bool emitSimple(JS::Handle<JSAtom*> paramName);
MOZ_MUST_USE bool prepareForDefault();
MOZ_MUST_USE bool emitDefaultEnd(const ParserAtom* paramName);
MOZ_MUST_USE bool emitDefaultEnd(JS::Handle<JSAtom*> paramName);
MOZ_MUST_USE bool prepareForDestructuring();
MOZ_MUST_USE bool emitDestructuringEnd();
@ -422,7 +422,7 @@ class MOZ_STACK_CLASS FunctionParamsEmitter {
MOZ_MUST_USE bool prepareForDestructuringDefault();
MOZ_MUST_USE bool emitDestructuringDefaultEnd();
MOZ_MUST_USE bool emitRest(const ParserAtom* paramName);
MOZ_MUST_USE bool emitRest(JS::Handle<JSAtom*> paramName);
MOZ_MUST_USE bool prepareForDestructuringRest();
MOZ_MUST_USE bool emitDestructuringRestEnd();
@ -433,7 +433,7 @@ class MOZ_STACK_CLASS FunctionParamsEmitter {
MOZ_MUST_USE bool emitRestArray();
MOZ_MUST_USE bool emitAssignment(const ParserAtom* paramName);
MOZ_MUST_USE bool emitAssignment(JS::Handle<JSAtom*> paramName);
};
} /* namespace frontend */

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

@ -13,7 +13,7 @@
using namespace js;
using namespace js::frontend;
void LabelEmitter::emitLabel(const ParserAtom* name) {
void LabelEmitter::emitLabel(HandleAtom name) {
MOZ_ASSERT(state_ == State::Start);
controlInfo_.emplace(bce_, name, bce_->bytecodeSection().offset());

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

@ -57,7 +57,7 @@ class MOZ_STACK_CLASS LabelEmitter {
public:
explicit LabelEmitter(BytecodeEmitter* bce) : bce_(bce) {}
void emitLabel(const ParserAtom* name);
void emitLabel(HandleAtom name);
MOZ_MUST_USE bool emitEnd();
};

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

@ -14,7 +14,7 @@ using namespace js::frontend;
LexicalScopeEmitter::LexicalScopeEmitter(BytecodeEmitter* bce) : bce_(bce) {}
bool LexicalScopeEmitter::emitScope(ScopeKind kind,
ParserLexicalScopeData* bindings) {
JS::Handle<LexicalScope::Data*> bindings) {
MOZ_ASSERT(state_ == State::Start);
MOZ_ASSERT(bindings);

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

@ -83,7 +83,8 @@ class MOZ_STACK_CLASS LexicalScopeEmitter {
// Returns the scope object for non-empty scope.
const EmitterScope& emitterScope() const { return *emitterScope_; }
MOZ_MUST_USE bool emitScope(ScopeKind kind, ParserLexicalScopeData* bindings);
MOZ_MUST_USE bool emitScope(ScopeKind kind,
JS::Handle<LexicalScope::Data*> bindings);
MOZ_MUST_USE bool emitEmptyScope();
MOZ_MUST_USE bool emitEnd();

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

@ -23,7 +23,7 @@ namespace frontend {
class MOZ_STACK_CLASS ModuleSharedContext : public SharedContext {
public:
ParserModuleScopeData* bindings;
JS::Rooted<ModuleScope::Data*> bindings;
ModuleBuilder& builder;
ModuleSharedContext(JSContext* cx, CompilationInfo& compilationInfo,

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

@ -9,7 +9,6 @@
#include <type_traits>
#include "frontend/ParserAtom.h"
#include "vm/BytecodeUtil.h"
#include "vm/Scope.h"
@ -354,7 +353,7 @@ class NameLocation {
};
// These types are declared here for BaseScript::CreateLazy.
using AtomVector = Vector<const ParserAtom*, 24, SystemAllocPolicy>;
using AtomVector = Vector<JSAtom*, 24, SystemAllocPolicy>;
class FunctionBox;
// FunctionBoxes stored in this type are required to be rooted

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

@ -134,7 +134,7 @@ struct RecyclableAtomMapValueWrapper {
const Wrapped* operator->() const { return &wrapped; }
};
struct NameMapHasher : public DefaultHasher<const ParserAtom*> {
struct NameMapHasher : public DefaultHasher<JSAtom*> {
static inline HashNumber hash(const Lookup& l) {
// Name maps use the atom's precomputed hash code, which is based on
// the atom's contents rather than its pointer value. This is necessary
@ -147,7 +147,7 @@ struct NameMapHasher : public DefaultHasher<const ParserAtom*> {
template <typename MapValue>
using RecyclableNameMap =
InlineMap<const ParserAtom*, RecyclableAtomMapValueWrapper<MapValue>, 24,
InlineMap<JSAtom*, RecyclableAtomMapValueWrapper<MapValue>, 24,
NameMapHasher, SystemAllocPolicy>;
using DeclaredNameMap = RecyclableNameMap<DeclaredNameInfo>;

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

@ -11,7 +11,6 @@
#include "mozilla/Sprintf.h"
#include "frontend/BytecodeCompiler.h"
#include "frontend/CompilationInfo.h"
#include "frontend/ParseNode.h"
#include "frontend/ParseNodeVisitor.h"
#include "frontend/SharedContext.h"
@ -29,8 +28,7 @@ class NameResolver : public ParseNodeVisitor<NameResolver> {
static const size_t MaxParents = 100;
CompilationInfo& compilationInfo_;
const ParserAtom* prefix_;
RootedAtom prefix_;
// Number of nodes in the parents array.
size_t nparents_;
@ -59,7 +57,7 @@ class NameResolver : public ParseNodeVisitor<NameResolver> {
* given code like a["b c"], the front end will produce a ParseNodeKind::Dot
* with a ParseNodeKind::Name child whose name contains spaces.
*/
bool appendPropertyReference(const ParserAtom* name) {
bool appendPropertyReference(JSAtom* name) {
if (IsIdentifier(name)) {
return buf_.append('.') && buf_.append(name);
}
@ -220,32 +218,31 @@ class NameResolver : public ParseNodeVisitor<NameResolver> {
* assign to the function's displayAtom field.
*/
MOZ_MUST_USE bool resolveFun(FunctionNode* funNode,
const ParserAtom** retId) {
MutableHandleAtom retAtom) {
MOZ_ASSERT(funNode != nullptr);
FunctionBox* funbox = funNode->funbox();
MOZ_ASSERT(buf_.empty());
auto resetBuf = mozilla::MakeScopeExit([&] { buf_.clear(); });
*retId = nullptr;
retAtom.set(nullptr);
// If the function already has a name, use that.
if (funbox->displayAtom()) {
if (!prefix_) {
*retId = funbox->displayAtom();
if (funbox->displayAtom() != nullptr) {
if (prefix_ == nullptr) {
retAtom.set(funbox->displayAtom());
return true;
}
if (!buf_.append(prefix_) || !buf_.append('/') ||
!buf_.append(funbox->displayAtom())) {
return false;
}
*retId = buf_.finishParserAtom(compilationInfo_);
return !!*retId;
retAtom.set(buf_.finishAtom());
return !!retAtom;
}
// If a prefix is specified, then it is a form of namespace.
if (prefix_) {
if (prefix_ != nullptr) {
if (!buf_.append(prefix_) || !buf_.append('/')) {
return false;
}
@ -315,15 +312,15 @@ class NameResolver : public ParseNodeVisitor<NameResolver> {
return true;
}
*retId = buf_.finishParserAtom(compilationInfo_);
if (!*retId) {
retAtom.set(buf_.finishAtom());
if (!retAtom) {
return false;
}
// Skip assigning the guessed name if the function has a (dynamically)
// computed inferred name.
if (!funNode->isDirectRHSAnonFunction()) {
funbox->setGuessedAtom(*retId);
funbox->setGuessedAtom(retAtom);
}
return true;
}
@ -340,8 +337,8 @@ class NameResolver : public ParseNodeVisitor<NameResolver> {
public:
MOZ_MUST_USE bool visitFunction(FunctionNode* pn) {
const ParserAtom* savedPrefix = prefix_;
const ParserAtom* newPrefix = nullptr;
RootedAtom savedPrefix(cx_, prefix_);
RootedAtom newPrefix(cx_);
if (!resolveFun(pn, &newPrefix)) {
return false;
}
@ -440,12 +437,8 @@ class NameResolver : public ParseNodeVisitor<NameResolver> {
return internalVisitSpecList(pn);
}
explicit NameResolver(JSContext* cx, CompilationInfo& compilationInfo)
: ParseNodeVisitor(cx),
compilationInfo_(compilationInfo),
prefix_(nullptr),
nparents_(0),
buf_(cx) {}
explicit NameResolver(JSContext* cx)
: ParseNodeVisitor(cx), prefix_(cx), nparents_(0), buf_(cx) {}
/*
* Resolve names for all anonymous functions in the given ParseNode tree.
@ -476,10 +469,9 @@ class NameResolver : public ParseNodeVisitor<NameResolver> {
} /* anonymous namespace */
bool frontend::NameFunctions(JSContext* cx, CompilationInfo& compilationInfo,
ParseNode* pn) {
bool frontend::NameFunctions(JSContext* cx, ParseNode* pn) {
AutoTraceLog traceLog(TraceLoggerForCurrentThread(cx),
TraceLogger_BytecodeNameFunctions);
NameResolver nr(cx, compilationInfo);
NameResolver nr(cx);
return nr.visit(pn);
}

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

@ -15,10 +15,8 @@ namespace js {
namespace frontend {
class ParseNode;
struct CompilationInfo;
MOZ_MUST_USE bool NameFunctions(JSContext* cx, CompilationInfo& compilationInfo,
ParseNode* pn);
MOZ_MUST_USE bool NameFunctions(JSContext* cx, ParseNode* pn);
} /* namespace frontend */
} /* namespace js */

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

@ -17,11 +17,11 @@
using namespace js;
using namespace js::frontend;
NameOpEmitter::NameOpEmitter(BytecodeEmitter* bce, const ParserAtom* name,
NameOpEmitter::NameOpEmitter(BytecodeEmitter* bce, Handle<JSAtom*> name,
Kind kind)
: bce_(bce), kind_(kind), name_(name), loc_(bce_->lookupName(name_)) {}
NameOpEmitter::NameOpEmitter(BytecodeEmitter* bce, const ParserAtom* name,
NameOpEmitter::NameOpEmitter(BytecodeEmitter* bce, Handle<JSAtom*> name,
const NameLocation& loc, Kind kind)
: bce_(bce), kind_(kind), name_(name), loc_(loc) {}

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

@ -80,7 +80,7 @@ class MOZ_STACK_CLASS NameOpEmitter {
bool emittedBindOp_ = false;
const ParserAtom* name_;
Handle<JSAtom*> name_;
GCThingIndex atomIndex_;
@ -133,8 +133,8 @@ class MOZ_STACK_CLASS NameOpEmitter {
#endif
public:
NameOpEmitter(BytecodeEmitter* bce, const ParserAtom* name, Kind kind);
NameOpEmitter(BytecodeEmitter* bce, const ParserAtom* name,
NameOpEmitter(BytecodeEmitter* bce, Handle<JSAtom*> name, Kind kind);
NameOpEmitter(BytecodeEmitter* bce, Handle<JSAtom*> name,
const NameLocation& loc, Kind kind);
private:

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

@ -6,11 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "frontend/ObjLiteral.h"
#include "mozilla/DebugOnly.h"
#include "frontend/CompilationInfo.h" // frontend::CompilationInfo
#include "frontend/ParserAtom.h" // frontend::ParserAtom, frontend::ParserAtomTable
#include "js/RootingAPI.h"
#include "vm/JSAtom.h"
#include "vm/JSObject.h"
@ -24,47 +20,30 @@
namespace js {
static bool InterpretObjLiteralValue(const ObjLiteralAtomVector& atoms,
frontend::CompilationInfo& compilationInfo,
const ObjLiteralInsn& insn,
JS::Value* valOut) {
static JS::Value InterpretObjLiteralValue(const ObjLiteralAtomVector& atoms,
const ObjLiteralInsn& insn) {
switch (insn.getOp()) {
case ObjLiteralOpcode::ConstValue:
*valOut = insn.getConstValue();
return true;
return insn.getConstValue();
case ObjLiteralOpcode::ConstAtom: {
uint32_t index = insn.getAtomIndex();
// TODO-Stencil
// This needs to be coalesced to wherever jsatom creation is eventually
// Seems like InterpretLiteralObj would be called from main-thread
// stencil instantiation.
JSAtom* jsatom = compilationInfo.liftParserAtomToJSAtom(atoms[index]);
if (!jsatom) {
return false;
}
*valOut = StringValue(jsatom);
return true;
return StringValue(atoms[index]);
}
case ObjLiteralOpcode::Null:
*valOut = NullValue();
return true;
return NullValue();
case ObjLiteralOpcode::Undefined:
*valOut = UndefinedValue();
return true;
return UndefinedValue();
case ObjLiteralOpcode::True:
*valOut = BooleanValue(true);
return true;
return BooleanValue(true);
case ObjLiteralOpcode::False:
*valOut = BooleanValue(false);
return true;
return BooleanValue(false);
default:
MOZ_CRASH("Unexpected object-literal instruction opcode");
}
}
static JSObject* InterpretObjLiteralObj(
JSContext* cx, frontend::CompilationInfo& compilationInfo,
const ObjLiteralAtomVector& atoms,
JSContext* cx, const ObjLiteralAtomVector& atoms,
const mozilla::Span<const uint8_t> literalInsns, ObjLiteralFlags flags) {
bool specificGroup = flags.contains(ObjLiteralFlag::SpecificGroup);
bool singleton = flags.contains(ObjLiteralFlag::Singleton);
@ -83,23 +62,12 @@ static JSObject* InterpretObjLiteralObj(
if (insn.getKey().isArrayIndex()) {
propId = INT_TO_JSID(insn.getKey().getArrayIndex());
} else {
// TODO-Stencil
// Just a note, but it seems like this is an OK place to convert atoms
// since the other GC allocations in the function (properties vector,
// etc.) would need to be addressed.
const frontend::ParserAtom* atom = atoms[insn.getKey().getAtomIndex()];
JSAtom* jsatom = compilationInfo.liftParserAtomToJSAtom(atom);
if (!jsatom) {
return nullptr;
}
propId = AtomToId(compilationInfo.liftParserAtomToJSAtom(atom));
propId = AtomToId(atoms[insn.getKey().getAtomIndex()]);
}
JS::Value propVal;
if (!noValues) {
if (!InterpretObjLiteralValue(atoms, compilationInfo, insn, &propVal)) {
return nullptr;
}
propVal = InterpretObjLiteralValue(atoms, insn);
}
if (!properties.emplaceBack(propId, propVal)) {
@ -118,8 +86,7 @@ static JSObject* InterpretObjLiteralObj(
}
static JSObject* InterpretObjLiteralArray(
JSContext* cx, frontend::CompilationInfo& compilationInfo,
const ObjLiteralAtomVector& atoms,
JSContext* cx, const ObjLiteralAtomVector& atoms,
const mozilla::Span<const uint8_t> literalInsns, ObjLiteralFlags flags) {
bool isCow = flags.contains(ObjLiteralFlag::ArrayCOW);
ObjLiteralReader reader(literalInsns);
@ -130,10 +97,7 @@ static JSObject* InterpretObjLiteralArray(
while (reader.readInsn(&insn)) {
MOZ_ASSERT(insn.isValid());
JS::Value propVal;
if (!InterpretObjLiteralValue(atoms, compilationInfo, insn, &propVal)) {
return nullptr;
}
JS::Value propVal = InterpretObjLiteralValue(atoms, insn);
if (!elements.append(propVal)) {
return nullptr;
}
@ -152,16 +116,12 @@ static JSObject* InterpretObjLiteralArray(
return result;
}
JSObject* InterpretObjLiteral(JSContext* cx,
frontend::CompilationInfo& compilationInfo,
const ObjLiteralAtomVector& atoms,
JSObject* InterpretObjLiteral(JSContext* cx, const ObjLiteralAtomVector& atoms,
const mozilla::Span<const uint8_t> literalInsns,
ObjLiteralFlags flags) {
return flags.contains(ObjLiteralFlag::Array)
? InterpretObjLiteralArray(cx, compilationInfo, atoms,
literalInsns, flags)
: InterpretObjLiteralObj(cx, compilationInfo, atoms, literalInsns,
flags);
? InterpretObjLiteralArray(cx, atoms, literalInsns, flags)
: InterpretObjLiteralObj(cx, atoms, literalInsns, flags);
}
#if defined(DEBUG) || defined(JS_JITSPEW)

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

@ -12,7 +12,6 @@
#include "mozilla/EnumSet.h"
#include "mozilla/Span.h"
#include "frontend/ParserAtom.h"
#include "js/AllocPolicy.h"
#include "js/GCPolicyAPI.h"
#include "js/Value.h"
@ -142,10 +141,6 @@ namespace js {
class JSONPrinter;
namespace frontend {
struct CompilationInfo;
}
// Object-literal instruction opcodes. An object literal is constructed by a
// straight-line sequence of these ops, each adding one property to the
// object.
@ -549,20 +544,16 @@ struct ObjLiteralReader : private ObjLiteralReaderBase {
}
};
typedef Vector<const frontend::ParserAtom*, 4> ObjLiteralAtomVector;
typedef Vector<JSAtom*, 4> ObjLiteralAtomVector;
JSObject* InterpretObjLiteral(JSContext* cx,
frontend::CompilationInfo& compilationInfo,
const ObjLiteralAtomVector& atoms,
JSObject* InterpretObjLiteral(JSContext* cx, const ObjLiteralAtomVector& atoms,
const mozilla::Span<const uint8_t> insns,
ObjLiteralFlags flags);
inline JSObject* InterpretObjLiteral(JSContext* cx,
frontend::CompilationInfo& compilationInfo,
const ObjLiteralAtomVector& atoms,
const ObjLiteralWriter& writer) {
return InterpretObjLiteral(cx, compilationInfo, atoms, writer.getCode(),
writer.getFlags());
return InterpretObjLiteral(cx, atoms, writer.getCode(), writer.getFlags());
}
class ObjLiteralStencil {
@ -575,12 +566,12 @@ class ObjLiteralStencil {
ObjLiteralWriter& writer() { return writer_; }
bool addAtom(const frontend::ParserAtom* atom, uint32_t* index) {
bool addAtom(JSAtom* atom, uint32_t* index) {
*index = atoms_.length();
return atoms_.append(atom);
}
JSObject* create(JSContext* cx, frontend::CompilationInfo& info) const;
JSObject* create(JSContext* cx) const;
#if defined(DEBUG) || defined(JS_JITSPEW)
void dump();

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

@ -21,7 +21,7 @@
#include "vm/NativeObject.h" // NativeDefineDataProperty
#include "vm/ObjectGroup.h" // TenuredObject
#include "vm/Opcodes.h" // JSOp
#include "vm/Runtime.h" // cx->parserNames()
#include "vm/Runtime.h" // JSAtomState (cx->parserNames())
#include "vm/SharedStencil.h" // GCThingIndex
#include "gc/ObjectKind-inl.h" // GetGCObjectKind
@ -263,8 +263,7 @@ bool PropertyEmitter::emitInitHomeObject() {
return true;
}
bool PropertyEmitter::emitInit(AccessorType accessorType,
const ParserAtom* key) {
bool PropertyEmitter::emitInit(AccessorType accessorType, HandleAtom key) {
switch (accessorType) {
case AccessorType::None:
return emitInit(isClass_ ? JSOp::InitHiddenProp : JSOp::InitProp, key);
@ -295,7 +294,7 @@ bool PropertyEmitter::emitInitIndexOrComputed(AccessorType accessorType) {
}
}
bool PropertyEmitter::emitInit(JSOp op, const ParserAtom* key) {
bool PropertyEmitter::emitInit(JSOp op, JS::Handle<JSAtom*> key) {
MOZ_ASSERT(propertyState_ == PropertyState::PropValue ||
propertyState_ == PropertyState::InitHomeObj);
@ -423,12 +422,12 @@ void AutoSaveLocalStrictMode::restore() {
ClassEmitter::ClassEmitter(BytecodeEmitter* bce)
: PropertyEmitter(bce),
strictMode_(bce->sc),
name_(nullptr),
nameForAnonymousClass_(nullptr) {
name_(bce->cx),
nameForAnonymousClass_(bce->cx) {
isClass_ = true;
}
bool ClassEmitter::emitScope(ParserLexicalScopeData* scopeBindings) {
bool ClassEmitter::emitScope(JS::Handle<LexicalScope::Data*> scopeBindings) {
MOZ_ASSERT(propertyState_ == PropertyState::Start);
MOZ_ASSERT(classState_ == ClassState::Start);
@ -446,7 +445,8 @@ bool ClassEmitter::emitScope(ParserLexicalScopeData* scopeBindings) {
return true;
}
bool ClassEmitter::emitBodyScope(ParserLexicalScopeData* scopeBindings) {
bool ClassEmitter::emitBodyScope(
JS::Handle<LexicalScope::Data*> scopeBindings) {
MOZ_ASSERT(propertyState_ == PropertyState::Start);
MOZ_ASSERT(classState_ == ClassState::Start ||
classState_ == ClassState::Scope);
@ -465,8 +465,8 @@ bool ClassEmitter::emitBodyScope(ParserLexicalScopeData* scopeBindings) {
return true;
}
bool ClassEmitter::emitClass(const ParserAtom* name,
const ParserAtom* nameForAnonymousClass,
bool ClassEmitter::emitClass(JS::Handle<JSAtom*> name,
JS::Handle<JSAtom*> nameForAnonymousClass,
bool hasNameOnStack) {
MOZ_ASSERT(propertyState_ == PropertyState::Start);
MOZ_ASSERT(classState_ == ClassState::Start ||
@ -493,8 +493,8 @@ bool ClassEmitter::emitClass(const ParserAtom* name,
return true;
}
bool ClassEmitter::emitDerivedClass(const ParserAtom* name,
const ParserAtom* nameForAnonymousClass,
bool ClassEmitter::emitDerivedClass(JS::Handle<JSAtom*> name,
JS::Handle<JSAtom*> nameForAnonymousClass,
bool hasNameOnStack) {
MOZ_ASSERT(propertyState_ == PropertyState::Start);
MOZ_ASSERT(classState_ == ClassState::Start ||
@ -616,7 +616,7 @@ bool ClassEmitter::emitInitDefaultConstructor(uint32_t classStart,
MOZ_ASSERT(propertyState_ == PropertyState::Start);
MOZ_ASSERT(classState_ == ClassState::Class);
const ParserAtom* className = name_;
RootedAtom className(bce_->cx, name_);
if (!className) {
if (nameForAnonymousClass_) {
className = nameForAnonymousClass_;
@ -707,9 +707,9 @@ bool ClassEmitter::prepareForMemberInitializers(size_t numInitializers,
// .initializers is a variable that stores an array of lambdas containing
// code (the initializer) for each field. Upon an object's construction,
// these lambdas will be called, defining the values.
const ParserName* initializers =
isStatic ? bce_->cx->parserNames().dotStaticInitializers
: bce_->cx->parserNames().dotInitializers;
auto initializersName = isStatic ? &JSAtomState::dotStaticInitializers
: &JSAtomState::dotInitializers;
HandlePropertyName initializers = bce_->cx->parserNames().*initializersName;
initializersAssignment_.emplace(bce_, initializers,
NameOpEmitter::Kind::Initialize);
if (!initializersAssignment_->prepareForRhs()) {

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

@ -18,7 +18,9 @@
#include "frontend/NameOpEmitter.h" // NameOpEmitter
#include "frontend/ParseNode.h" // AccessorType
#include "frontend/TDZCheckCache.h" // TDZCheckCache
#include "js/RootingAPI.h" // JS::Handle, JS::Rooted
#include "vm/BytecodeUtil.h" // JSOp
#include "vm/JSAtom.h" // JSAtom
#include "vm/NativeObject.h" // PlainObject
#include "vm/Scope.h" // LexicalScope
@ -233,7 +235,7 @@ class MOZ_STACK_CLASS PropertyEmitter {
// @param key
// Property key
MOZ_MUST_USE bool emitInit(AccessorType accessorType, const ParserAtom* key);
MOZ_MUST_USE bool emitInit(AccessorType accessorType, HandleAtom key);
MOZ_MUST_USE bool emitInitIndexOrComputed(AccessorType accessorType);
@ -245,7 +247,7 @@ class MOZ_STACK_CLASS PropertyEmitter {
// Opcode for initializing property
// @param key
// Atom of the property if the property key is not computed
MOZ_MUST_USE bool emitInit(JSOp op, const ParserAtom* key);
MOZ_MUST_USE bool emitInit(JSOp op, JS::Handle<JSAtom*> key);
MOZ_MUST_USE bool emitInitIndexOrComputed(JSOp op);
MOZ_MUST_USE bool emitPopClassConstructor();
@ -753,8 +755,8 @@ class MOZ_STACK_CLASS ClassEmitter : public PropertyEmitter {
size_t numInitializers_ = 0;
#endif
const ParserAtom* name_;
const ParserAtom* nameForAnonymousClass_;
JS::Rooted<JSAtom*> name_;
JS::Rooted<JSAtom*> nameForAnonymousClass_;
bool hasNameOnStack_ = false;
mozilla::Maybe<NameOpEmitter> initializersAssignment_;
size_t initializerIndex_ = 0;
@ -762,8 +764,9 @@ class MOZ_STACK_CLASS ClassEmitter : public PropertyEmitter {
public:
explicit ClassEmitter(BytecodeEmitter* bce);
bool emitScope(ParserLexicalScopeData* scopeBindings);
bool emitBodyScope(ParserLexicalScopeData* scopeBindings);
bool emitScope(JS::Handle<LexicalScope::Data*> scopeBindings);
bool emitBodyScope(JS::Handle<LexicalScope::Data*> scopeBindings);
// @param name
// Name of the class (nullptr if this is anonymous class)
@ -771,11 +774,11 @@ class MOZ_STACK_CLASS ClassEmitter : public PropertyEmitter {
// Statically inferred name of the class (only for anonymous classes)
// @param hasNameOnStack
// If true the name is on the stack (only for anonymous classes)
MOZ_MUST_USE bool emitClass(const ParserAtom* name,
const ParserAtom* nameForAnonymousClass,
MOZ_MUST_USE bool emitClass(JS::Handle<JSAtom*> name,
JS::Handle<JSAtom*> nameForAnonymousClass,
bool hasNameOnStack);
MOZ_MUST_USE bool emitDerivedClass(const ParserAtom* name,
const ParserAtom* nameForAnonymousClass,
MOZ_MUST_USE bool emitDerivedClass(JS::Handle<JSAtom*> name,
JS::Handle<JSAtom*> nameForAnonymousClass,
bool hasNameOnStack);
// @param needsHomeObject

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

@ -63,7 +63,7 @@ inline ParseContext::VarScope::VarScope(JSContext* cx, ParseContext* pc,
}
inline JS::Result<Ok, ParseContext::BreakStatementError>
ParseContext::checkBreakStatement(const ParserName* label) {
ParseContext::checkBreakStatement(PropertyName* label) {
// Labeled 'break' statements target the nearest labeled statements (could
// be any kind) with the same label. Unlabeled 'break' statements target
// the innermost loop or switch statement.
@ -91,7 +91,7 @@ ParseContext::checkBreakStatement(const ParserName* label) {
}
inline JS::Result<Ok, ParseContext::ContinueStatementError>
ParseContext::checkContinueStatement(const ParserName* label) {
ParseContext::checkContinueStatement(PropertyName* label) {
// Labeled 'continue' statements target the nearest labeled loop
// statements with the same label. Unlabeled 'continue' statements target
// the innermost loop statement.

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

@ -62,7 +62,7 @@ bool DeclarationKindIsParameter(DeclarationKind kind) {
kind == DeclarationKind::FormalParameter;
}
bool UsedNameTracker::noteUse(JSContext* cx, const ParserAtom* name,
bool UsedNameTracker::noteUse(JSContext* cx, JSAtom* name,
NameVisibility visibility, uint32_t scriptId,
uint32_t scopeId,
mozilla::Maybe<TokenPos> tokenPosition) {
@ -161,7 +161,7 @@ void ParseContext::Scope::dump(ParseContext* pc) {
fprintf(stdout, "\n decls:\n");
for (DeclaredNameMap::Range r = declared_->all(); !r.empty(); r.popFront()) {
UniqueChars bytes = QuoteString(cx, r.front().key());
UniqueChars bytes = AtomToPrintableString(cx, r.front().key());
if (!bytes) {
return;
}
@ -195,11 +195,12 @@ bool ParseContext::Scope::propagateAndMarkAnnexBFunctionBoxes(
if (this == &pc->varScope()) {
// Base case: actually declare the Annex B vars and mark applicable
// function boxes as Annex B.
RootedPropertyName name(pc->sc()->cx_);
Maybe<DeclarationKind> redeclaredKind;
uint32_t unused;
for (FunctionBox* funbox : *possibleAnnexBFunctionBoxes_) {
if (pc->annexBAppliesToLexicalFunctionInInnermostScope(funbox)) {
const ParserName* name = funbox->explicitName()->asName();
name = funbox->explicitName()->asPropertyName();
if (!pc->tryDeclareVar(
name, DeclarationKind::VarForAnnexBLexicalFunction,
DeclaredNameInfo::npos, &redeclaredKind, &unused)) {
@ -241,7 +242,7 @@ bool ParseContext::Scope::addCatchParameters(ParseContext* pc,
DeclarationKind kind = r.front().value()->kind();
uint32_t pos = r.front().value()->pos();
MOZ_ASSERT(DeclarationKindIsCatchParameter(kind));
const ParserAtom* name = r.front().key();
JSAtom* name = r.front().key();
AddDeclaredNamePtr p = lookupDeclaredNameForAdd(name);
MOZ_ASSERT(!p);
if (!addDeclaredName(pc, p, name, kind, pos)) {
@ -347,7 +348,7 @@ bool ParseContext::annexBAppliesToLexicalFunctionInInnermostScope(
FunctionBox* funbox) {
MOZ_ASSERT(!sc()->strict());
const ParserName* name = funbox->explicitName()->asName();
RootedPropertyName name(sc()->cx_, funbox->explicitName()->asPropertyName());
Maybe<DeclarationKind> redeclaredKind = isVarRedeclaredInInnermostScope(
name, DeclarationKind::VarForAnnexBLexicalFunction);
@ -376,7 +377,7 @@ bool ParseContext::annexBAppliesToLexicalFunctionInInnermostScope(
}
Maybe<DeclarationKind> ParseContext::isVarRedeclaredInInnermostScope(
const ParserName* name, DeclarationKind kind) {
HandlePropertyName name, DeclarationKind kind) {
Maybe<DeclarationKind> redeclaredKind;
uint32_t unused;
MOZ_ALWAYS_TRUE(tryDeclareVarHelper<DryRunInnermostScopeOnly>(
@ -384,20 +385,11 @@ Maybe<DeclarationKind> ParseContext::isVarRedeclaredInInnermostScope(
return redeclaredKind;
}
bool ParseContext::isVarRedeclaredInEval(const ParserName* name,
DeclarationKind kind,
Maybe<DeclarationKind>* out) {
MOZ_ASSERT(out);
Maybe<DeclarationKind> ParseContext::isVarRedeclaredInEval(
HandlePropertyName name, DeclarationKind kind) {
MOZ_ASSERT(DeclarationKindIsVar(kind));
MOZ_ASSERT(sc()->isEvalContext());
// TODO-Stencil: After scope snapshotting, this can be done away with.
auto mbNameAtom = name->toJSAtom(sc()->cx_);
if (mbNameAtom.isErr()) {
return false;
}
JSAtom* nameAtom = mbNameAtom.unwrap();
// In the case of eval, we also need to check enclosing VM scopes to see
// if the var declaration is allowed in the context.
js::Scope* enclosingScope = sc()->compilationInfo().enclosingScope;
@ -405,7 +397,7 @@ bool ParseContext::isVarRedeclaredInEval(const ParserName* name,
MOZ_ASSERT(varScope);
for (ScopeIter si(enclosingScope); si; si++) {
for (js::BindingIter bi(si.scope()); bi; bi++) {
if (bi.name() != nameAtom) {
if (bi.name() != name) {
continue;
}
@ -415,17 +407,15 @@ bool ParseContext::isVarRedeclaredInEval(const ParserName* name,
// catch parameters with var declarations.
bool annexB35Allowance = si.kind() == ScopeKind::SimpleCatch;
if (!annexB35Allowance) {
*out = Some(ScopeKindIsCatch(si.kind())
return Some(ScopeKindIsCatch(si.kind())
? DeclarationKind::CatchParameter
: DeclarationKind::Let);
return true;
}
break;
}
case BindingKind::Const:
*out = Some(DeclarationKind::Const);
return true;
return Some(DeclarationKind::Const);
case BindingKind::Import:
case BindingKind::FormalParameter:
@ -440,11 +430,10 @@ bool ParseContext::isVarRedeclaredInEval(const ParserName* name,
}
}
*out = Nothing();
return true;
return Nothing();
}
bool ParseContext::tryDeclareVar(const ParserName* name, DeclarationKind kind,
bool ParseContext::tryDeclareVar(HandlePropertyName name, DeclarationKind kind,
uint32_t beginPos,
Maybe<DeclarationKind>* redeclaredKind,
uint32_t* prevPos) {
@ -453,7 +442,7 @@ bool ParseContext::tryDeclareVar(const ParserName* name, DeclarationKind kind,
}
template <ParseContext::DryRunOption dryRunOption>
bool ParseContext::tryDeclareVarHelper(const ParserName* name,
bool ParseContext::tryDeclareVarHelper(HandlePropertyName name,
DeclarationKind kind, uint32_t beginPos,
Maybe<DeclarationKind>* redeclaredKind,
uint32_t* prevPos) {
@ -523,9 +512,7 @@ bool ParseContext::tryDeclareVarHelper(const ParserName* name,
if (!sc()->strict() && sc()->isEvalContext() &&
(dryRunOption == NotDryRun || innermostScope() == &varScope())) {
if (!isVarRedeclaredInEval(name, kind, redeclaredKind)) {
return false;
}
*redeclaredKind = isVarRedeclaredInEval(name, kind);
// We don't have position information at runtime.
*prevPos = DeclaredNameInfo::npos;
}
@ -534,7 +521,7 @@ bool ParseContext::tryDeclareVarHelper(const ParserName* name,
}
bool ParseContext::hasUsedName(const UsedNameTracker& usedNames,
const ParserName* name) {
HandlePropertyName name) {
if (auto p = usedNames.lookup(name)) {
return p->value().isUsedInScript(scriptId());
}
@ -542,7 +529,7 @@ bool ParseContext::hasUsedName(const UsedNameTracker& usedNames,
}
bool ParseContext::hasUsedFunctionSpecialName(const UsedNameTracker& usedNames,
const ParserName* name) {
HandlePropertyName name) {
MOZ_ASSERT(name == sc()->cx_->parserNames().arguments ||
name == sc()->cx_->parserNames().dotThis);
return hasUsedName(usedNames, name) ||
@ -560,7 +547,7 @@ bool ParseContext::declareFunctionThis(const UsedNameTracker& usedNames,
// Derived class constructors emit JSOp::CheckReturn, which requires
// '.this' to be bound.
FunctionBox* funbox = functionBox();
const ParserName* dotThis = sc()->cx_->parserNames().dotThis;
HandlePropertyName dotThis = sc()->cx_->parserNames().dotThis;
bool declareThis;
if (canSkipLazyClosedOverBindings) {
@ -594,7 +581,7 @@ bool ParseContext::declareFunctionArgumentsObject(
bool hasExtraBodyVarScope = &funScope != &_varScope;
// Time to implement the odd semantics of 'arguments'.
const ParserName* argumentsName = sc()->cx_->parserNames().arguments;
HandlePropertyName argumentsName = sc()->cx_->parserNames().arguments;
bool tryDeclareArguments;
if (canSkipLazyClosedOverBindings) {
@ -658,7 +645,7 @@ bool ParseContext::declareDotGeneratorName() {
// The special '.generator' binding must be on the function scope, as
// generators expect to find it on the CallObject.
ParseContext::Scope& funScope = functionScope();
const ParserName* dotGenerator = sc()->cx_->parserNames().dotGenerator;
HandlePropertyName dotGenerator = sc()->cx_->parserNames().dotGenerator;
AddDeclaredNamePtr p = funScope.lookupDeclaredNameForAdd(dotGenerator);
if (!p &&
!funScope.addDeclaredName(this, p, dotGenerator, DeclarationKind::Var,

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

@ -69,13 +69,13 @@ class ParseContext : public Nestable<ParseContext> {
};
class LabelStatement : public Statement {
const ParserAtom* label_;
RootedAtom label_;
public:
LabelStatement(ParseContext* pc, const ParserAtom* label)
: Statement(pc, StatementKind::Label), label_(label) {}
LabelStatement(ParseContext* pc, JSAtom* label)
: Statement(pc, StatementKind::Label), label_(pc->sc_->cx_, label) {}
const ParserAtom* label() const { return label_; }
HandleAtom label() const { return label_; }
};
struct ClassStatement : public Statement {
@ -140,17 +140,17 @@ class ParseContext : public Nestable<ParseContext> {
bool isEmpty() const { return declared_->all().empty(); }
DeclaredNamePtr lookupDeclaredName(const ParserAtom* name) {
DeclaredNamePtr lookupDeclaredName(JSAtom* name) {
return declared_->lookup(name);
}
AddDeclaredNamePtr lookupDeclaredNameForAdd(const ParserAtom* name) {
AddDeclaredNamePtr lookupDeclaredNameForAdd(JSAtom* name) {
return declared_->lookupForAdd(name);
}
MOZ_MUST_USE bool addDeclaredName(ParseContext* pc, AddDeclaredNamePtr& p,
const ParserAtom* name,
DeclarationKind kind, uint32_t pos) {
JSAtom* name, DeclarationKind kind,
uint32_t pos) {
return maybeReportOOM(
pc, declared_->add(p, name, DeclaredNameInfo(kind, pos)));
}
@ -212,7 +212,7 @@ class ParseContext : public Nestable<ParseContext> {
explicit operator bool() const { return !done(); }
const ParserAtom* name() {
JSAtom* name() {
MOZ_ASSERT(!done());
return declaredRange_.front().key();
}
@ -402,14 +402,14 @@ class ParseContext : public Nestable<ParseContext> {
// Return Err(true) if we have encountered at least one loop,
// Err(false) otherwise.
MOZ_MUST_USE inline JS::Result<Ok, BreakStatementError> checkBreakStatement(
const ParserName* label);
PropertyName* label);
enum class ContinueStatementError {
NotInALoop,
LabelNotFound,
};
MOZ_MUST_USE inline JS::Result<Ok, ContinueStatementError>
checkContinueStatement(const ParserName* label);
checkContinueStatement(PropertyName* label);
// True if we are at the topmost level of a entire script or function body.
// For example, while parsing this code we would encounter f1 and f2 at
@ -480,14 +480,14 @@ class ParseContext : public Nestable<ParseContext> {
bool annexBAppliesToLexicalFunctionInInnermostScope(FunctionBox* funbox);
bool tryDeclareVar(const ParserName* name, DeclarationKind kind,
bool tryDeclareVar(HandlePropertyName name, DeclarationKind kind,
uint32_t beginPos,
mozilla::Maybe<DeclarationKind>* redeclaredKind,
uint32_t* prevPos);
bool hasUsedName(const UsedNameTracker& usedNames, const ParserName* name);
bool hasUsedName(const UsedNameTracker& usedNames, HandlePropertyName name);
bool hasUsedFunctionSpecialName(const UsedNameTracker& usedNames,
const ParserName* name);
HandlePropertyName name);
bool declareFunctionThis(const UsedNameTracker& usedNames,
bool canSkipLazyClosedOverBindings);
@ -497,15 +497,13 @@ class ParseContext : public Nestable<ParseContext> {
private:
mozilla::Maybe<DeclarationKind> isVarRedeclaredInInnermostScope(
const ParserName* name, DeclarationKind kind);
MOZ_MUST_USE bool isVarRedeclaredInEval(const ParserName* name,
DeclarationKind kind,
mozilla::Maybe<DeclarationKind>* out);
HandlePropertyName name, DeclarationKind kind);
mozilla::Maybe<DeclarationKind> isVarRedeclaredInEval(HandlePropertyName name,
DeclarationKind kind);
enum DryRunOption { NotDryRun, DryRunInnermostScopeOnly };
template <DryRunOption dryRunOption>
bool tryDeclareVarHelper(const ParserName* name, DeclarationKind kind,
bool tryDeclareVarHelper(HandlePropertyName name, DeclarationKind kind,
uint32_t beginPos,
mozilla::Maybe<DeclarationKind>* redeclaredKind,
uint32_t* prevPos);

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

@ -199,23 +199,12 @@ void RegExpLiteral::dumpImpl(GenericPrinter& out, int indent) {
out.printf("(%s)", parseNodeNames[getKindAsIndex()]);
}
static void DumpCharsNoNewline(const ParserAtom* atom,
js::GenericPrinter& out) {
if (atom->hasLatin1Chars()) {
out.put("[Latin 1]");
JSString::dumpChars(atom->latin1Chars(), atom->length(), out);
} else {
out.put("[2 byte]");
JSString::dumpChars(atom->twoByteChars(), atom->length(), out);
}
}
void LoopControlStatement::dumpImpl(GenericPrinter& out, int indent) {
const char* name = parseNodeNames[getKindAsIndex()];
out.printf("(%s", name);
if (label()) {
out.printf(" ");
DumpCharsNoNewline(label(), out);
label()->dumpCharsNoNewline(out);
}
out.printf(")");
}
@ -319,7 +308,7 @@ void NameNode::dumpImpl(GenericPrinter& out, int indent) {
case ParseNodeKind::StringExpr:
case ParseNodeKind::TemplateStringExpr:
case ParseNodeKind::ObjectPropertyName:
DumpCharsNoNewline(atom(), out);
atom()->dumpCharsNoNewline(out);
return;
case ParseNodeKind::Name:
@ -329,10 +318,11 @@ void NameNode::dumpImpl(GenericPrinter& out, int indent) {
if (!atom()) {
out.put("#<null name>");
} else {
JS::AutoCheckCannotGC nogc;
if (atom()->hasLatin1Chars()) {
DumpName(out, atom()->latin1Chars(), atom()->length());
DumpName(out, atom()->latin1Chars(nogc), atom()->length());
} else {
DumpName(out, atom()->twoByteChars(), atom()->length());
DumpName(out, atom()->twoByteChars(nogc), atom()->length());
}
}
return;
@ -353,7 +343,7 @@ void NameNode::dumpImpl(GenericPrinter& out, int indent) {
void LabeledStatement::dumpImpl(GenericPrinter& out, int indent) {
const char* name = parseNodeNames[getKindAsIndex()];
out.printf("(%s ", name);
DumpCharsNoNewline(atom(), out);
atom()->dumpCharsNoNewline(out);
out.printf(" ");
indent += strlen(name) + atom()->length() + 3;
DumpParseTree(statement(), out, indent);
@ -365,13 +355,14 @@ void LexicalScopeNode::dumpImpl(GenericPrinter& out, int indent) {
out.printf("(%s [", name);
int nameIndent = indent + strlen(name) + 3;
if (!isEmptyScope()) {
ParserScopeData<LexicalScope>* bindings = scopeBindings();
LexicalScope::Data* bindings = scopeBindings();
for (uint32_t i = 0; i < bindings->length; i++) {
const ParserAtom* name = bindings->trailingNames[i].name();
JSAtom* name = bindings->trailingNames[i].name();
JS::AutoCheckCannotGC nogc;
if (name->hasLatin1Chars()) {
DumpName(out, name->latin1Chars(), name->length());
DumpName(out, name->latin1Chars(nogc), name->length());
} else {
DumpName(out, name->twoByteChars(), name->length());
DumpName(out, name->twoByteChars(nogc), name->length());
}
if (i < bindings->length - 1) {
IndentNewLine(out, nameIndent);
@ -394,9 +385,8 @@ bool BigIntLiteral::isZero() {
return compilationInfo_.bigIntData[index_].isZero();
}
const ParserAtom* NumericLiteral::toAtom(
CompilationInfo& compilationInfo) const {
return NumberToParserAtom(compilationInfo, value());
JSAtom* NumericLiteral::toAtom(JSContext* cx) const {
return NumberToAtom(cx, value());
}
RegExpObject* RegExpStencil::createRegExp(JSContext* cx) const {

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

@ -18,7 +18,6 @@
#include "frontend/FunctionSyntaxKind.h" // FunctionSyntaxKind
#include "frontend/NameAnalysisTypes.h" // PrivateNameKind
#include "frontend/ParserAtom.h"
#include "frontend/Stencil.h"
#include "frontend/Token.h"
#include "js/RootingAPI.h"
@ -39,9 +38,16 @@
//
// - This bulk-deallocation DOES NOT run destructors.
//
// - Instances of `ParserScopeData<LexicalScope>` MUST BE allocated as
// instances of `ParseNode`, in the same `LifoAlloc`. They are bulk-
// deallocated alongside the rest of the tree.
// - Instances of `LexicalScope::Data` MUST BE allocated as instances of
// `ParseNode`, in the same `LifoAlloc`. They are bulk-deallocated alongside
// the rest of the tree.
//
// - Instances of `JSAtom` used throughout the tree (including instances of
// `PropertyName`) MUST be kept alive by the parser. This is done through an
// instance of `AutoKeepAtoms` held by the parser.
//
// - Once the parser is deallocated, the `JSAtom` instances MAY be
// garbage-collected.
struct JSContext;
@ -61,15 +67,8 @@ class ParseContext;
struct CompilationInfo;
class ParserSharedBase;
class FullParseHandler;
class FunctionBox;
// This typedef unfortunately needs to be replicated here.
using ParserBindingName = AbstractBindingName<const ParserAtom>;
template <typename Scope>
using ParserScopeData = typename Scope::template AbstractData<const ParserAtom>;
#define FOR_EACH_PARSE_NODE_KIND(F) \
F(EmptyStmt, NullaryNode) \
F(ExpressionStmt, UnaryNode) \
@ -748,7 +747,7 @@ class ParseNode {
return ParseNodeKind::BinOpFirst <= kind &&
kind <= ParseNodeKind::BinOpLast;
}
inline bool isName(const ParserName* name) const;
inline bool isName(PropertyName* name) const;
/* Boolean attributes. */
bool isInParens() const { return pn_parens; }
@ -851,11 +850,11 @@ class NullaryNode : public ParseNode {
};
class NameNode : public ParseNode {
const ParserAtom* atom_; /* lexical name or label atom */
JSAtom* atom_; /* lexical name or label atom */
PrivateNameKind privateNameKind_ = PrivateNameKind::None;
public:
NameNode(ParseNodeKind kind, const ParserAtom* atom, const TokenPos& pos)
NameNode(ParseNodeKind kind, JSAtom* atom, const TokenPos& pos)
: ParseNode(kind, pos), atom_(atom) {
MOZ_ASSERT(is<NameNode>());
}
@ -875,15 +874,15 @@ class NameNode : public ParseNode {
void dumpImpl(GenericPrinter& out, int indent);
#endif
const ParserAtom* atom() const { return atom_; }
JSAtom* atom() const { return atom_; }
const ParserName* name() const {
PropertyName* name() const {
MOZ_ASSERT(isKind(ParseNodeKind::Name) ||
isKind(ParseNodeKind::PrivateName));
return atom()->asName();
return atom()->asPropertyName();
}
void setAtom(const ParserAtom* atom) { atom_ = atom; }
void setAtom(JSAtom* atom) { atom_ = atom; }
void setPrivateNameKind(PrivateNameKind privateNameKind) {
privateNameKind_ = privateNameKind;
@ -892,7 +891,7 @@ class NameNode : public ParseNode {
PrivateNameKind privateNameKind() { return privateNameKind_; }
};
inline bool ParseNode::isName(const ParserName* name) const {
inline bool ParseNode::isName(PropertyName* name) const {
return getKind() == ParseNodeKind::Name && as<NameNode>().name() == name;
}
@ -941,7 +940,7 @@ class UnaryNode : public ParseNode {
* or escaped newlines, say). This member function returns true for such
* nodes; we use it to determine the extent of the prologue.
*/
const ParserAtom* isStringExprStatement() const {
JSAtom* isStringExprStatement() const {
if (isKind(ParseNodeKind::ExpressionStmt)) {
if (kid()->isKind(ParseNodeKind::StringExpr) && !kid()->isInParens()) {
return kid()->as<NameNode>().atom();
@ -1553,7 +1552,7 @@ class NumericLiteral : public ParseNode {
void setDecimalPoint(DecimalPoint d) { decimalPoint_ = d; }
// Return the decimal string representation of this numeric literal.
const ParserAtom* toAtom(CompilationInfo& compilationInfo) const;
JSAtom* toAtom(JSContext* cx) const;
};
class BigIntLiteral : public ParseNode {
@ -1591,12 +1590,12 @@ class BigIntLiteral : public ParseNode {
};
class LexicalScopeNode : public ParseNode {
ParserScopeData<LexicalScope>* bindings;
LexicalScope::Data* bindings;
ParseNode* body;
ScopeKind kind_;
public:
LexicalScopeNode(ParserScopeData<LexicalScope>* bindings, ParseNode* body,
LexicalScopeNode(LexicalScope::Data* bindings, ParseNode* body,
ScopeKind kind = ScopeKind::Lexical)
: ParseNode(ParseNodeKind::LexicalScope, body->pn_pos),
bindings(bindings),
@ -1618,11 +1617,11 @@ class LexicalScopeNode : public ParseNode {
void dumpImpl(GenericPrinter& out, int indent);
#endif
ParserScopeData<LexicalScope>* scopeBindings() const {
Handle<LexicalScope::Data*> scopeBindings() const {
MOZ_ASSERT(!isEmptyScope());
// Bindings' GC safety depend on the presence of an AutoKeepAtoms that
// the rest of the frontend also depends on.
return bindings;
return Handle<LexicalScope::Data*>::fromMarkedLocation(&bindings);
}
ParseNode* scopeBody() const { return body; }
@ -1638,12 +1637,12 @@ class LabeledStatement : public NameNode {
ParseNode* statement_;
public:
LabeledStatement(const ParserName* label, ParseNode* stmt, uint32_t begin)
LabeledStatement(PropertyName* label, ParseNode* stmt, uint32_t begin)
: NameNode(ParseNodeKind::LabelStmt, label,
TokenPos(begin, stmt->pn_pos.end)),
statement_(stmt) {}
const ParserName* label() const { return atom()->asName(); }
PropertyName* label() const { return atom()->asPropertyName(); }
ParseNode* statement() const { return statement_; }
@ -1689,10 +1688,10 @@ class CaseClause : public BinaryNode {
};
class LoopControlStatement : public ParseNode {
const ParserName* label_; /* target of break/continue statement */
PropertyName* label_; /* target of break/continue statement */
protected:
LoopControlStatement(ParseNodeKind kind, const ParserName* label,
LoopControlStatement(ParseNodeKind kind, PropertyName* label,
const TokenPos& pos)
: ParseNode(kind, pos), label_(label) {
MOZ_ASSERT(kind == ParseNodeKind::BreakStmt ||
@ -1702,7 +1701,7 @@ class LoopControlStatement : public ParseNode {
public:
/* Label associated with this break/continue statement, if any. */
const ParserName* label() const { return label_; }
PropertyName* label() const { return label_; }
#ifdef DEBUG
void dumpImpl(GenericPrinter& out, int indent);
@ -1723,7 +1722,7 @@ class LoopControlStatement : public ParseNode {
class BreakStatement : public LoopControlStatement {
public:
BreakStatement(const ParserName* label, const TokenPos& pos)
BreakStatement(PropertyName* label, const TokenPos& pos)
: LoopControlStatement(ParseNodeKind::BreakStmt, label, pos) {}
static bool test(const ParseNode& node) {
@ -1735,7 +1734,7 @@ class BreakStatement : public LoopControlStatement {
class ContinueStatement : public LoopControlStatement {
public:
ContinueStatement(const ParserName* label, const TokenPos& pos)
ContinueStatement(PropertyName* label, const TokenPos& pos)
: LoopControlStatement(ParseNodeKind::ContinueStmt, label, pos) {}
static bool test(const ParseNode& node) {
@ -1923,8 +1922,8 @@ class PropertyAccessBase : public BinaryNode {
void setExpression(ParseNode* pn) { *unsafeLeftReference() = pn; }
const ParserName* name() const {
return right()->as<NameNode>().atom()->asName();
PropertyName& name() const {
return *right()->as<NameNode>().atom()->asPropertyName();
}
};

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

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

@ -266,13 +266,6 @@ class MOZ_STACK_CLASS ParserSharedBase : public JS::CustomAutoRooter {
public:
CompilationInfo& getCompilationInfo() { return compilationInfo_; }
JSAtom* liftParserAtomToJSAtom(const ParserAtom* parserAtom) {
return compilationInfo_.liftParserAtomToJSAtom(parserAtom);
}
const ParserAtom* lowerJSAtomToParserAtom(JSAtom* atom) {
return compilationInfo_.lowerJSAtomToParserAtom(atom);
}
};
class MOZ_STACK_CLASS ParserBase : public ParserSharedBase,
@ -368,7 +361,7 @@ class MOZ_STACK_CLASS ParserBase : public ParserSharedBase,
public:
bool isUnexpectedEOF() const { return isUnexpectedEOF_; }
bool isValidStrictBinding(const ParserName* name);
bool isValidStrictBinding(PropertyName* name);
bool hasValidSimpleStrictParameterNames();
@ -376,7 +369,7 @@ class MOZ_STACK_CLASS ParserBase : public ParserSharedBase,
* Create a new function object given a name (which is optional if this is
* a function expression).
*/
JSFunction* newFunction(const ParserAtom* atom, FunctionSyntaxKind kind,
JSFunction* newFunction(HandleAtom atom, FunctionSyntaxKind kind,
GeneratorKind generatorKind,
FunctionAsyncKind asyncKind);
@ -400,17 +393,15 @@ class MOZ_STACK_CLASS ParserBase : public ParserSharedBase,
}
public:
mozilla::Maybe<ParserGlobalScopeData*> newGlobalScopeData(
mozilla::Maybe<GlobalScope::Data*> newGlobalScopeData(
ParseContext::Scope& scope);
mozilla::Maybe<ParserModuleScopeData*> newModuleScopeData(
mozilla::Maybe<ModuleScope::Data*> newModuleScopeData(
ParseContext::Scope& scope);
mozilla::Maybe<ParserEvalScopeData*> newEvalScopeData(
ParseContext::Scope& scope);
mozilla::Maybe<ParserFunctionScopeData*> newFunctionScopeData(
mozilla::Maybe<EvalScope::Data*> newEvalScopeData(ParseContext::Scope& scope);
mozilla::Maybe<FunctionScope::Data*> newFunctionScopeData(
ParseContext::Scope& scope, bool hasParameterExprs);
mozilla::Maybe<ParserVarScopeData*> newVarScopeData(
ParseContext::Scope& scope);
mozilla::Maybe<ParserLexicalScopeData*> newLexicalScopeData(
mozilla::Maybe<VarScope::Data*> newVarScopeData(ParseContext::Scope& scope);
mozilla::Maybe<LexicalScope::Data*> newLexicalScopeData(
ParseContext::Scope& scope);
protected:
@ -422,15 +413,14 @@ class MOZ_STACK_CLASS ParserBase : public ParserSharedBase,
// modifier TokenStream::SlashIsDiv, continues a LexicalDeclaration.
bool nextTokenContinuesLetDeclaration(TokenKind next);
bool noteUsedNameInternal(const ParserName* name, NameVisibility visibility,
bool noteUsedNameInternal(HandlePropertyName name, NameVisibility visibility,
mozilla::Maybe<TokenPos> tokenPosition);
bool checkAndMarkSuperScope();
bool leaveInnerFunction(ParseContext* outerpc);
const ParserAtom* prefixAccessorName(PropertyType propType,
const ParserAtom* propAtom);
JSAtom* prefixAccessorName(PropertyType propType, HandleAtom propAtom);
MOZ_MUST_USE bool setSourceMapInfo();
@ -497,7 +487,7 @@ class MOZ_STACK_CLASS PerHandlerParser : public ParserBase {
Node destruct);
bool noteUsedName(
const ParserName* name,
HandlePropertyName name,
NameVisibility visibility = NameVisibility::Public,
mozilla::Maybe<TokenPos> tokenPosition = mozilla::Nothing()) {
// If the we are delazifying, the BaseScript already has all the closed-over
@ -519,18 +509,18 @@ class MOZ_STACK_CLASS PerHandlerParser : public ParserBase {
ScopeKind kind = ScopeKind::Lexical);
bool finishFunction(bool isStandaloneFunction = false);
inline NameNodeType newName(const ParserName* name);
inline NameNodeType newName(const ParserName* name, TokenPos pos);
inline NameNodeType newName(PropertyName* name);
inline NameNodeType newName(PropertyName* name, TokenPos pos);
inline NameNodeType newPrivateName(const ParserName* name);
inline NameNodeType newPrivateName(const ParserName* name, TokenPos pos);
inline NameNodeType newPrivateName(PropertyName* name);
inline NameNodeType newPrivateName(PropertyName* name, TokenPos pos);
NameNodeType newInternalDotName(const ParserName* name);
NameNodeType newInternalDotName(HandlePropertyName name);
NameNodeType newThisName();
NameNodeType newDotGeneratorName();
NameNodeType identifierReference(const ParserName* name);
NameNodeType privateNameReference(const ParserName* name);
NameNodeType identifierReference(Handle<PropertyName*> name);
NameNodeType privateNameReference(Handle<PropertyName*> name);
Node noSubstitutionTaggedTemplate();
@ -566,7 +556,7 @@ class MOZ_STACK_CLASS PerHandlerParser : public ParserBase {
inline void clearAbortedSyntaxParse();
public:
NameNodeType newPropertyName(const ParserName* key, const TokenPos& pos) {
NameNodeType newPropertyName(PropertyName* key, const TokenPos& pos) {
return handler_.newPropertyName(key, pos);
}
@ -574,8 +564,7 @@ class MOZ_STACK_CLASS PerHandlerParser : public ParserBase {
return handler_.newPropertyAccess(expr, key);
}
FunctionBox* newFunctionBox(FunctionNodeType funNode,
const ParserAtom* explicitName,
FunctionBox* newFunctionBox(FunctionNodeType funNode, JSAtom* explicitName,
FunctionFlags flags, uint32_t toStringStart,
Directives directives,
GeneratorKind generatorKind,
@ -993,8 +982,8 @@ class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser<ParseHandler> {
ListNodeType nodeList, TokenKind* ttp);
inline bool trySyntaxParseInnerFunction(
FunctionNodeType* funNode, const ParserAtom* explicitName,
FunctionFlags flags, uint32_t toStringStart, InHandling inHandling,
FunctionNodeType* funNode, HandleAtom explicitName, FunctionFlags flags,
uint32_t toStringStart, InHandling inHandling,
YieldHandling yieldHandling, FunctionSyntaxKind kind,
GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
Directives inheritedDirectives, Directives* newDirectives);
@ -1199,8 +1188,7 @@ class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser<ParseHandler> {
BinaryNodeType importExpr(YieldHandling yieldHandling, bool allowCallSyntax);
FunctionNodeType methodDefinition(uint32_t toStringStart,
PropertyType propType,
const ParserAtom* funName);
PropertyType propType, HandleAtom funName);
/*
* Additional JS parsers.
@ -1210,9 +1198,9 @@ class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser<ParseHandler> {
FunctionNodeType functionDefinition(
FunctionNodeType funNode, uint32_t toStringStart, InHandling inHandling,
YieldHandling yieldHandling, const ParserAtom* name,
FunctionSyntaxKind kind, GeneratorKind generatorKind,
FunctionAsyncKind asyncKind, bool tryAnnexB = false);
YieldHandling yieldHandling, HandleAtom name, FunctionSyntaxKind kind,
GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
bool tryAnnexB = false);
// Parse a function body. Pass StatementListBody if the body is a list of
// statements; pass ExpressionBody if the body is a single expression.
@ -1235,7 +1223,7 @@ class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser<ParseHandler> {
YieldHandling yieldHandling,
TokenKind tt);
inline bool checkExportedName(const ParserAtom* exportName);
inline bool checkExportedName(JSAtom* exportName);
inline bool checkExportedNamesForArrayBinding(ListNodeType array);
inline bool checkExportedNamesForObjectBinding(ListNodeType obj);
inline bool checkExportedNamesForDeclaration(Node node);
@ -1267,41 +1255,42 @@ class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser<ParseHandler> {
MOZ_MUST_USE bool classMember(
YieldHandling yieldHandling,
const ParseContext::ClassStatement& classStmt,
const ParserName* className, uint32_t classStartOffset,
HandlePropertyName className, uint32_t classStartOffset,
HasHeritage hasHeritage, ClassInitializedMembers& classInitializedMembers,
ListNodeType& classMembers, bool* done);
MOZ_MUST_USE bool finishClassConstructor(
const ParseContext::ClassStatement& classStmt,
const ParserName* className, HasHeritage hasHeritage,
HandlePropertyName className, HasHeritage hasHeritage,
uint32_t classStartOffset, uint32_t classEndOffset,
const ClassInitializedMembers& classInitializedMembers,
ListNodeType& classMembers);
FunctionNodeType privateMethodInitializer(const ParserAtom* propAtom,
const ParserAtom* storedMethodAtom);
FunctionNodeType privateMethodInitializer(HandleAtom propAtom,
HandleAtom storedMethodAtom);
FunctionNodeType fieldInitializerOpt(
Node name, const ParserAtom* atom,
Node name, HandleAtom atom,
ClassInitializedMembers& classInitializedMembers, bool isStatic,
HasHeritage hasHeritage);
FunctionNodeType synthesizeConstructor(const ParserAtom* className,
FunctionNodeType synthesizeConstructor(HandleAtom className,
uint32_t classNameOffset,
HasHeritage hasHeritage);
bool checkBindingIdentifier(const ParserName* ident, uint32_t offset,
bool checkBindingIdentifier(PropertyName* ident, uint32_t offset,
YieldHandling yieldHandling,
TokenKind hint = TokenKind::Limit);
const ParserName* labelOrIdentifierReference(YieldHandling yieldHandling);
PropertyName* labelOrIdentifierReference(YieldHandling yieldHandling);
const ParserName* labelIdentifier(YieldHandling yieldHandling) {
PropertyName* labelIdentifier(YieldHandling yieldHandling) {
return labelOrIdentifierReference(yieldHandling);
}
const ParserName* identifierReference(YieldHandling yieldHandling) {
PropertyName* identifierReference(YieldHandling yieldHandling) {
return labelOrIdentifierReference(yieldHandling);
}
bool matchLabel(YieldHandling yieldHandling, const ParserName** labelOut);
bool matchLabel(YieldHandling yieldHandling,
MutableHandle<PropertyName*> label);
// Indicate if the next token (tokenized with SlashIsRegExp) is |in| or |of|.
// If so, consume it.
@ -1314,10 +1303,10 @@ class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser<ParseHandler> {
void reportMissingClosing(unsigned errorNumber, unsigned noteNumber,
uint32_t openedPos);
void reportRedeclaration(const ParserName* name, DeclarationKind prevKind,
void reportRedeclaration(HandlePropertyName name, DeclarationKind prevKind,
TokenPos pos, uint32_t prevPos);
bool notePositionalFormalParameter(FunctionNodeType funNode,
const ParserName* name, uint32_t beginPos,
HandlePropertyName name, uint32_t beginPos,
bool disallowDuplicateParams,
bool* duplicatedParam);
@ -1329,12 +1318,12 @@ class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser<ParseHandler> {
Node propertyName(YieldHandling yieldHandling,
PropertyNameContext propertyNameContext,
const mozilla::Maybe<DeclarationKind>& maybeDecl,
ListNodeType propList, const ParserAtom** propAtomOut);
ListNodeType propList, MutableHandleAtom propAtom);
Node propertyOrMethodName(YieldHandling yieldHandling,
PropertyNameContext propertyNameContext,
const mozilla::Maybe<DeclarationKind>& maybeDecl,
ListNodeType propList, PropertyType* propType,
const ParserAtom** propAtomOut);
MutableHandleAtom propAtom);
UnaryNodeType computedPropertyName(
YieldHandling yieldHandling,
const mozilla::Maybe<DeclarationKind>& maybeDecl,
@ -1377,7 +1366,7 @@ class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser<ParseHandler> {
inline BigIntLiteralType newBigInt();
const ParserAtom* bigIntAtom();
JSAtom* bigIntAtom();
enum class OptionalKind {
NonOptional = 0,
@ -1398,18 +1387,17 @@ class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser<ParseHandler> {
// Match the current token against the BindingIdentifier production with
// the given Yield parameter. If there is no match, report a syntax
// error.
const ParserName* bindingIdentifier(YieldHandling yieldHandling);
PropertyName* bindingIdentifier(YieldHandling yieldHandling);
bool checkLabelOrIdentifierReference(const ParserName* ident, uint32_t offset,
bool checkLabelOrIdentifierReference(PropertyName* ident, uint32_t offset,
YieldHandling yieldHandling,
TokenKind hint = TokenKind::Limit);
ListNodeType statementList(YieldHandling yieldHandling);
MOZ_MUST_USE FunctionNodeType innerFunction(
FunctionNodeType funNode, ParseContext* outerpc,
const ParserAtom* explicitName, FunctionFlags flags,
uint32_t toStringStart, InHandling inHandling,
FunctionNodeType funNode, ParseContext* outerpc, HandleAtom explicitName,
FunctionFlags flags, uint32_t toStringStart, InHandling inHandling,
YieldHandling yieldHandling, FunctionSyntaxKind kind,
GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
Directives inheritedDirectives, Directives* newDirectives);
@ -1426,10 +1414,10 @@ class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser<ParseHandler> {
// next token could be a RegExp literal beginning a new ExpressionStatement.
bool matchOrInsertSemicolon(Modifier modifier = TokenStream::SlashIsRegExp);
bool noteDeclaredName(const ParserName* name, DeclarationKind kind,
bool noteDeclaredName(HandlePropertyName name, DeclarationKind kind,
TokenPos pos);
bool noteDeclaredPrivateName(Node nameNode, const ParserName* name,
bool noteDeclaredPrivateName(Node nameNode, HandlePropertyName name,
PropertyType propType, TokenPos pos);
private:
@ -1533,7 +1521,7 @@ class MOZ_STACK_CLASS Parser<SyntaxParseHandler, Unit> final
// |using| the whole thing into existence because of the visibility
// distinction, so we instead must manually delegate the required overload.
const ParserName* bindingIdentifier(YieldHandling yieldHandling) {
PropertyName* bindingIdentifier(YieldHandling yieldHandling) {
return Base::bindingIdentifier(yieldHandling);
}
@ -1550,7 +1538,7 @@ class MOZ_STACK_CLASS Parser<SyntaxParseHandler, Unit> final
inline BinaryNodeType importDeclaration();
inline bool checkLocalExportNames(ListNodeType node);
inline bool checkExportedName(const ParserAtom* exportName);
inline bool checkExportedName(JSAtom* exportName);
inline bool checkExportedNamesForArrayBinding(ListNodeType array);
inline bool checkExportedNamesForObjectBinding(ListNodeType obj);
inline bool checkExportedNamesForDeclaration(Node node);
@ -1560,8 +1548,8 @@ class MOZ_STACK_CLASS Parser<SyntaxParseHandler, Unit> final
inline bool checkExportedNameForClause(NameNodeType nameNode);
bool trySyntaxParseInnerFunction(
FunctionNodeType* funNode, const ParserAtom* explicitName,
FunctionFlags flags, uint32_t toStringStart, InHandling inHandling,
FunctionNodeType* funNode, HandleAtom explicitName, FunctionFlags flags,
uint32_t toStringStart, InHandling inHandling,
YieldHandling yieldHandling, FunctionSyntaxKind kind,
GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
Directives inheritedDirectives, Directives* newDirectives);
@ -1677,7 +1665,7 @@ class MOZ_STACK_CLASS Parser<FullParseHandler, Unit> final
// |using| the whole thing into existence because of the visibility
// distinction, so we instead must manually delegate the required overload.
const ParserName* bindingIdentifier(YieldHandling yieldHandling) {
PropertyName* bindingIdentifier(YieldHandling yieldHandling) {
return Base::bindingIdentifier(yieldHandling);
}
@ -1697,7 +1685,7 @@ class MOZ_STACK_CLASS Parser<FullParseHandler, Unit> final
BinaryNodeType importDeclaration();
bool checkLocalExportNames(ListNodeType node);
bool checkExportedName(const ParserAtom* exportName);
bool checkExportedName(JSAtom* exportName);
bool checkExportedNamesForArrayBinding(ListNodeType array);
bool checkExportedNamesForObjectBinding(ListNodeType obj);
bool checkExportedNamesForDeclaration(Node node);
@ -1707,8 +1695,8 @@ class MOZ_STACK_CLASS Parser<FullParseHandler, Unit> final
inline bool checkExportedNameForClause(NameNodeType nameNode);
bool trySyntaxParseInnerFunction(
FunctionNodeType* funNode, const ParserAtom* explicitName,
FunctionFlags flags, uint32_t toStringStart, InHandling inHandling,
FunctionNodeType* funNode, HandleAtom explicitName, FunctionFlags flags,
uint32_t toStringStart, InHandling inHandling,
YieldHandling yieldHandling, FunctionSyntaxKind kind,
GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
Directives inheritedDirectives, Directives* newDirectives);
@ -1750,9 +1738,9 @@ class MOZ_STACK_CLASS Parser<FullParseHandler, Unit> final
bool namedImportsOrNamespaceImport(TokenKind tt, ListNodeType importSpecSet);
const ParserName* importedBinding() { return bindingIdentifier(YieldIsName); }
PropertyName* importedBinding() { return bindingIdentifier(YieldIsName); }
bool checkLocalExportName(const ParserName* ident, uint32_t offset) {
bool checkLocalExportName(PropertyName* ident, uint32_t offset) {
return checkLabelOrIdentifierReference(ident, offset, YieldIsName);
}
@ -1849,38 +1837,33 @@ class MOZ_STACK_CLASS AutoInParametersOfAsyncFunction {
}
};
ParserGlobalScopeData* NewEmptyGlobalScopeData(JSContext* cx, LifoAlloc& alloc,
GlobalScope::Data* NewEmptyGlobalScopeData(JSContext* cx, LifoAlloc& alloc,
uint32_t numBindings);
ParserVarScopeData* NewEmptyVarScopeData(JSContext* cx, LifoAlloc& alloc,
VarScope::Data* NewEmptyVarScopeData(JSContext* cx, LifoAlloc& alloc,
uint32_t numBindings);
ParserLexicalScopeData* NewEmptyLexicalScopeData(JSContext* cx,
LifoAlloc& alloc,
LexicalScope::Data* NewEmptyLexicalScopeData(JSContext* cx, LifoAlloc& alloc,
uint32_t numBindings);
ParserFunctionScopeData* NewEmptyFunctionScopeData(JSContext* cx,
LifoAlloc& alloc,
FunctionScope::Data* NewEmptyFunctionScopeData(JSContext* cx, LifoAlloc& alloc,
uint32_t numBindings);
mozilla::Maybe<ParserGlobalScopeData*> NewGlobalScopeData(
mozilla::Maybe<GlobalScope::Data*> NewGlobalScopeData(
JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc,
ParseContext* pc);
mozilla::Maybe<ParserEvalScopeData*> NewEvalScopeData(
JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc,
ParseContext* pc);
mozilla::Maybe<ParserFunctionScopeData*> NewFunctionScopeData(
JSContext* context, ParseContext::Scope& scope, bool hasParameterExprs,
LifoAlloc& alloc, ParseContext* pc);
mozilla::Maybe<ParserVarScopeData*> NewVarScopeData(JSContext* context,
mozilla::Maybe<EvalScope::Data*> NewEvalScopeData(JSContext* context,
ParseContext::Scope& scope,
LifoAlloc& alloc,
ParseContext* pc);
mozilla::Maybe<ParserLexicalScopeData*> NewLexicalScopeData(
mozilla::Maybe<FunctionScope::Data*> NewFunctionScopeData(
JSContext* context, ParseContext::Scope& scope, bool hasParameterExprs,
LifoAlloc& alloc, ParseContext* pc);
mozilla::Maybe<VarScope::Data*> NewVarScopeData(JSContext* context,
ParseContext::Scope& scope,
LifoAlloc& alloc,
ParseContext* pc);
mozilla::Maybe<LexicalScope::Data*> NewLexicalScopeData(
JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc,
ParseContext* pc);

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

@ -16,6 +16,15 @@
#include "vm/Runtime.h"
#include "vm/StringType.h"
//
// Parser-Atoms should be disabled for now. This check ensures that.
// NOTE: This will be removed when the final transition patches from
// JS-atoms to parser-atoms lands.
//
#ifdef JS_PARSER_ATOMS
# error "Parser atoms define should remain disabled until this is removed."
#endif
using namespace js;
using namespace js::frontend;
@ -326,28 +335,18 @@ static void FillChar16Buffer(char16_t* buf, const ParserAtomEntry* ent) {
}
JS::Result<const ParserAtom*, OOM&> ParserAtomsTable::concatAtoms(
JSContext* cx, mozilla::Range<const ParserAtom*> atoms) {
bool latin1 = true;
uint32_t catLen = 0;
for (const ParserAtom* atom : atoms) {
if (!atom->hasLatin1Chars()) {
latin1 = false;
}
// Overflow check here, length
if (atom->length() >= (ParserAtomEntry::MAX_LENGTH - catLen)) {
return RaiseParserAtomsOOMError(cx);
}
catLen += atom->length();
}
JSContext* cx, const ParserAtom* prefix, const ParserAtom* suffix) {
bool latin1 = prefix->hasLatin1Chars() && suffix->hasLatin1Chars();
size_t prefixLength = prefix->length();
size_t suffixLength = suffix->length();
size_t catLen = prefixLength + suffixLength;
if (latin1) {
if (catLen <= ParserAtomEntry::MaxInline<Latin1Char>()) {
Latin1Char buf[ParserAtomEntry::MaxInline<Latin1Char>()];
size_t offset = 0;
for (const ParserAtom* atom : atoms) {
mozilla::PodCopy(buf + offset, atom->latin1Chars(), atom->length());
offset += atom->length();
}
mozilla::PodCopy(buf, prefix->latin1Chars(), prefixLength);
mozilla::PodCopy(buf + prefixLength, suffix->latin1Chars(), suffixLength);
return internLatin1(cx, buf, catLen);
}
@ -356,12 +355,9 @@ JS::Result<const ParserAtom*, OOM&> ParserAtomsTable::concatAtoms(
if (!copy) {
return RaiseParserAtomsOOMError(cx);
}
size_t offset = 0;
for (const ParserAtom* atom : atoms) {
mozilla::PodCopy(copy.get() + offset, atom->latin1Chars(),
atom->length());
offset += atom->length();
}
mozilla::PodCopy(copy.get(), prefix->latin1Chars(), prefixLength);
mozilla::PodCopy(copy.get() + prefixLength, suffix->latin1Chars(),
suffixLength);
InflatedChar16Sequence<Latin1Char> seq(copy.get(), catLen);
@ -380,11 +376,8 @@ JS::Result<const ParserAtom*, OOM&> ParserAtomsTable::concatAtoms(
if (catLen <= ParserAtomEntry::MaxInline<char16_t>()) {
char16_t buf[ParserAtomEntry::MaxInline<char16_t>()];
size_t offset = 0;
for (const ParserAtom* atom : atoms) {
FillChar16Buffer(buf + offset, atom);
offset += atom->length();
}
FillChar16Buffer(buf, prefix);
FillChar16Buffer(buf + prefixLength, suffix);
InflatedChar16Sequence<char16_t> seq(buf, catLen);
@ -406,11 +399,8 @@ JS::Result<const ParserAtom*, OOM&> ParserAtomsTable::concatAtoms(
if (!copy) {
return RaiseParserAtomsOOMError(cx);
}
size_t offset = 0;
for (const ParserAtom* atom : atoms) {
FillChar16Buffer(copy.get() + offset, atom);
offset += atom->length();
}
FillChar16Buffer(copy.get(), prefix);
FillChar16Buffer(copy.get() + prefixLength, suffix);
InflatedChar16Sequence<char16_t> seq(copy.get(), catLen);
@ -439,7 +429,7 @@ const ParserAtom* WellKnownParserAtoms::lookupChar16Seq(
}
bool WellKnownParserAtoms::initSingle(JSContext* cx, const ParserName** name,
const char* str, JSAtom* jsatom) {
const char* str) {
MOZ_ASSERT(name != nullptr);
unsigned int len = strlen(str);
@ -476,7 +466,6 @@ bool WellKnownParserAtoms::initSingle(JSContext* cx, const ParserName** name,
}
entry = maybeEntry.unwrap();
}
entry->jsatom_ = jsatom;
// Save name for returning after moving entry into set.
const ParserName* nm = entry.get()->asName();
@ -490,14 +479,14 @@ bool WellKnownParserAtoms::initSingle(JSContext* cx, const ParserName** name,
bool WellKnownParserAtoms::init(JSContext* cx) {
#define COMMON_NAME_INIT_(idpart, id, text) \
if (!initSingle(cx, &(id), text, cx->names().id)) { \
if (!initSingle(cx, &(id), text)) { \
return false; \
}
FOR_EACH_COMMON_PROPERTYNAME(COMMON_NAME_INIT_)
#undef COMMON_NAME_INIT_
#define COMMON_NAME_INIT_(name, clasp) \
if (!initSingle(cx, &(name), #name, cx->names().name)) { \
if (!initSingle(cx, &(name), #name)) { \
return false; \
}
JS_FOR_EACH_PROTOTYPE(COMMON_NAME_INIT_)
@ -510,6 +499,7 @@ bool WellKnownParserAtoms::init(JSContext* cx) {
} /* namespace js */
bool JSRuntime::initializeParserAtoms(JSContext* cx) {
#ifdef JS_PARSER_ATOMS
MOZ_ASSERT(!commonParserNames);
if (parentRuntime) {
@ -524,11 +514,18 @@ bool JSRuntime::initializeParserAtoms(JSContext* cx) {
}
commonParserNames = names.release();
#else
commonParserNames = nullptr;
#endif // JS_PARSER_ATOMS
return true;
}
void JSRuntime::finishParserAtoms() {
#ifdef JS_PARSER_ATOMS
if (!parentRuntime) {
js_delete(commonParserNames.ref());
}
#else
MOZ_ASSERT(!commonParserNames);
#endif // JS_PARSER_ATOMS
}

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

@ -9,11 +9,9 @@
#include "mozilla/DebugOnly.h" // mozilla::DebugOnly
#include "mozilla/HashFunctions.h" // HashString
#include "mozilla/Range.h" // mozilla::Range
#include "mozilla/Variant.h" // mozilla::Variant
#include "ds/LifoAlloc.h" // LifoAlloc
#include "js/GCPolicyAPI.h" // JS::GCPolicy, JS::IgnoreGCPolicy
#include "js/HashTable.h" // HashSet
#include "js/UniquePtr.h" // js::UniquePtr
#include "js/Vector.h" // Vector
@ -180,6 +178,7 @@ class alignas(alignof(void*)) ParserAtomEntry {
}
}
public:
private:
// Owned characters, either 8-bit Latin1Char, or 16-bit char16_t
ContentPtrVariant variant_;
@ -193,15 +192,9 @@ class alignas(alignof(void*)) ParserAtomEntry {
// Used to dynamically optimize the mapping of ParserAtoms to JSAtom*s.
// If the entry comes from an atom or has been mapped to an
// atom previously, the atom reference is kept here.
//
// Note: if/when this field is removed, remove the comment
// in front of the call to `rt->initializeParserAtoms()` in
// `JS::InitSelfHostedCode`.
mutable JSAtom* jsatom_ = nullptr;
public:
static const uint32_t MAX_LENGTH = JSString::MAX_LENGTH;
template <typename CharT>
ParserAtomEntry(mozilla::UniquePtr<CharT[], JS::FreePolicy> chars,
uint32_t length, HashNumber hash)
@ -256,12 +249,6 @@ class alignas(alignof(void*)) ParserAtomEntry {
MOZ_ASSERT(hasTwoByteChars());
return variant_.getUnchecked<char16_t>();
}
mozilla::Range<const Latin1Char> latin1Range() const {
return mozilla::Range(latin1Chars(), length_);
}
mozilla::Range<const char16_t> twoByteRange() const {
return mozilla::Range(twoByteChars(), length_);
}
bool isIndex(uint32_t* indexp) const;
bool isIndex() const {
@ -368,8 +355,7 @@ class WellKnownParserAtoms {
TempAllocPolicy>;
EntrySet entrySet_;
bool initSingle(JSContext* cx, const ParserName** name, const char* str,
JSAtom* jsatom);
bool initSingle(JSContext* cx, const ParserName** name, const char* str);
public:
explicit WellKnownParserAtoms(JSContext* cx) : entrySet_(cx) {}
@ -462,8 +448,9 @@ class ParserAtomsTable {
JS::Result<const ParserAtom*, OOM&> internJSAtom(JSContext* cx, JSAtom* atom);
JS::Result<const ParserAtom*, OOM&> concatAtoms(
JSContext* cx, mozilla::Range<const ParserAtom*> atoms);
JS::Result<const ParserAtom*, OOM&> concatAtoms(JSContext* cx,
const ParserAtom* prefix,
const ParserAtom* suffix);
};
template <typename CharT>
@ -515,11 +502,4 @@ inline bool ParserAtomEntry::equalsSeq(
} /* namespace frontend */
} /* namespace js */
namespace JS {
// Dummy trace policy until tracing is removed.
template <>
struct GCPolicy<const js::frontend::ParserAtom*>
: IgnoreGCPolicy<const js::frontend::ParserAtom*> {};
} // namespace JS
#endif // frontend_ParserAtom_h

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

@ -18,7 +18,7 @@ using namespace js::frontend;
PropOpEmitter::PropOpEmitter(BytecodeEmitter* bce, Kind kind, ObjKind objKind)
: bce_(bce), kind_(kind), objKind_(objKind) {}
bool PropOpEmitter::prepareAtomIndex(const ParserAtom* prop) {
bool PropOpEmitter::prepareAtomIndex(JSAtom* prop) {
if (!bce_->makeAtomIndex(prop, &propAtomIndex_)) {
return false;
}
@ -36,7 +36,7 @@ bool PropOpEmitter::prepareForObj() {
return true;
}
bool PropOpEmitter::emitGet(const ParserAtom* prop) {
bool PropOpEmitter::emitGet(JSAtom* prop) {
MOZ_ASSERT(state_ == State::Obj);
if (!prepareAtomIndex(prop)) {
@ -134,7 +134,7 @@ bool PropOpEmitter::skipObjAndRhs() {
return true;
}
bool PropOpEmitter::emitDelete(const ParserAtom* prop) {
bool PropOpEmitter::emitDelete(JSAtom* prop) {
MOZ_ASSERT_IF(!isSuper(), state_ == State::Obj);
MOZ_ASSERT_IF(isSuper(), state_ == State::Start);
MOZ_ASSERT(isDelete());
@ -174,7 +174,7 @@ bool PropOpEmitter::emitDelete(const ParserAtom* prop) {
return true;
}
bool PropOpEmitter::emitAssignment(const ParserAtom* prop) {
bool PropOpEmitter::emitAssignment(JSAtom* prop) {
MOZ_ASSERT(isSimpleAssignment() || isPropInit() || isCompoundAssignment());
MOZ_ASSERT(state_ == State::Rhs);
@ -202,7 +202,7 @@ bool PropOpEmitter::emitAssignment(const ParserAtom* prop) {
return true;
}
bool PropOpEmitter::emitIncDec(const ParserAtom* prop) {
bool PropOpEmitter::emitIncDec(JSAtom* prop) {
MOZ_ASSERT(state_ == State::Obj);
MOZ_ASSERT(isIncDec());

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

@ -18,7 +18,6 @@ namespace js {
namespace frontend {
struct BytecodeEmitter;
class ParserAtom;
// Class for emitting bytecode for property operation.
//
@ -233,22 +232,22 @@ class MOZ_STACK_CLASS PropOpEmitter {
return kind_ == Kind::PostIncrement || kind_ == Kind::PreIncrement;
}
MOZ_MUST_USE bool prepareAtomIndex(const ParserAtom* prop);
MOZ_MUST_USE bool prepareAtomIndex(JSAtom* prop);
public:
MOZ_MUST_USE bool prepareForObj();
MOZ_MUST_USE bool emitGet(const ParserAtom* prop);
MOZ_MUST_USE bool emitGet(JSAtom* prop);
MOZ_MUST_USE bool prepareForRhs();
MOZ_MUST_USE bool skipObjAndRhs();
MOZ_MUST_USE bool emitDelete(const ParserAtom* prop);
MOZ_MUST_USE bool emitDelete(JSAtom* prop);
// `prop` can be nullptr for CompoundAssignment.
MOZ_MUST_USE bool emitAssignment(const ParserAtom* prop);
MOZ_MUST_USE bool emitAssignment(JSAtom* prop);
MOZ_MUST_USE bool emitIncDec(const ParserAtom* prop);
MOZ_MUST_USE bool emitIncDec(JSAtom* prop);
};
} /* namespace frontend */

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

@ -16,13 +16,6 @@ namespace frontend {
inline Directives::Directives(ParseContext* parent)
: strict_(parent->sc()->strict()), asmJS_(parent->useAsmOrInsideUseAsm()) {}
inline JSAtom* SharedContext::liftParserAtomToJSAtom(const ParserAtom* atomId) {
return compilationInfo_.liftParserAtomToJSAtom(atomId);
}
inline const ParserAtom* SharedContext::lowerJSAtomToParserAtom(JSAtom* atom) {
return compilationInfo_.lowerJSAtomToParserAtom(atom);
}
} // namespace frontend
} // namespace js

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

@ -205,7 +205,7 @@ EvalSharedContext::EvalSharedContext(JSContext* cx,
CompilationInfo& compilationInfo,
Directives directives, SourceExtent extent)
: SharedContext(cx, Kind::Eval, compilationInfo, directives, extent),
bindings(nullptr) {
bindings(cx) {
// Eval inherits syntax and binding rules from enclosing environment.
allowNewTarget_ = compilationInfo.scopeContext.allowNewTarget;
allowSuperProperty_ = compilationInfo.scopeContext.allowSuperProperty;
@ -222,7 +222,7 @@ bool FunctionBox::atomsAreKept() { return cx_->zone()->hasKeptAtoms(); }
FunctionBox::FunctionBox(JSContext* cx, FunctionBox* traceListHead,
SourceExtent extent, CompilationInfo& compilationInfo,
Directives directives, GeneratorKind generatorKind,
FunctionAsyncKind asyncKind, const ParserAtom* atom,
FunctionAsyncKind asyncKind, JSAtom* atom,
FunctionFlags flags, FunctionIndex index,
TopLevelFunction isTopLevel)
: SharedContext(cx, Kind::FunctionBox, compilationInfo, directives, extent),
@ -381,7 +381,11 @@ void FunctionBox::TraceList(JSTracer* trc, FunctionBox* listHead) {
}
}
void FunctionBox::trace(JSTracer* trc) {}
void FunctionBox::trace(JSTracer* trc) {
if (atom_) {
TraceRoot(trc, &atom_, "funbox-atom");
}
}
ModuleSharedContext::ModuleSharedContext(JSContext* cx,
CompilationInfo& compilationInfo,
@ -389,7 +393,7 @@ ModuleSharedContext::ModuleSharedContext(JSContext* cx,
SourceExtent extent)
: SharedContext(cx, Kind::Module, compilationInfo, Directives(true),
extent),
bindings(nullptr),
bindings(cx),
builder(builder) {
thisBinding_ = ThisBinding::Module;
setFlag(ImmutableFlags::HasModuleGoal);

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

@ -107,21 +107,6 @@ class GlobalSharedContext;
class EvalSharedContext;
class ModuleSharedContext;
using ParserBindingName = AbstractBindingName<const ParserAtom>;
using ParserBindingIter = AbstractBindingIter<const ParserAtom>;
using BaseParserScopeData = AbstractBaseScopeData<const ParserAtom>;
template <typename Scope>
using ParserScopeData = typename Scope::template AbstractData<const ParserAtom>;
using ParserGlobalScopeData = ParserScopeData<GlobalScope>;
using ParserEvalScopeData = ParserScopeData<EvalScope>;
using ParserLexicalScopeData = ParserScopeData<LexicalScope>;
using ParserFunctionScopeData = ParserScopeData<FunctionScope>;
using ParserModuleScopeData = ParserScopeData<ModuleScope>;
using ParserVarScopeData = ParserScopeData<VarScope>;
#define FLAG_GETTER(enumName, enumEntry, lowerName, name) \
public: \
bool lowerName() const { return hasFlag(enumName::enumEntry); }
@ -275,9 +260,6 @@ class SharedContext {
return retVal;
}
inline JSAtom* liftParserAtomToJSAtom(const ParserAtom* atomId);
inline const ParserAtom* lowerJSAtomToParserAtom(JSAtom* atom);
void copyScriptFields(ScriptStencil& stencil);
};
@ -285,14 +267,14 @@ class MOZ_STACK_CLASS GlobalSharedContext : public SharedContext {
ScopeKind scopeKind_;
public:
ParserGlobalScopeData* bindings;
Rooted<GlobalScope::Data*> bindings;
GlobalSharedContext(JSContext* cx, ScopeKind scopeKind,
CompilationInfo& compilationInfo, Directives directives,
SourceExtent extent)
: SharedContext(cx, Kind::Global, compilationInfo, directives, extent),
scopeKind_(scopeKind),
bindings(nullptr) {
bindings(cx) {
MOZ_ASSERT(scopeKind == ScopeKind::Global ||
scopeKind == ScopeKind::NonSyntactic);
MOZ_ASSERT(thisBinding_ == ThisBinding::Global);
@ -308,7 +290,7 @@ inline GlobalSharedContext* SharedContext::asGlobalContext() {
class MOZ_STACK_CLASS EvalSharedContext : public SharedContext {
public:
ParserEvalScopeData* bindings;
Rooted<EvalScope::Data*> bindings;
EvalSharedContext(JSContext* cx, CompilationInfo& compilationInfo,
Directives directives, SourceExtent extent);
@ -341,20 +323,20 @@ class FunctionBox : public SharedContext {
mozilla::Maybe<ScopeIndex> enclosingScopeIndex_;
// Names from the named lambda scope, if a named lambda.
ParserLexicalScopeData* namedLambdaBindings_ = nullptr;
LexicalScope::Data* namedLambdaBindings_ = nullptr;
// Names from the function scope.
ParserFunctionScopeData* functionScopeBindings_ = nullptr;
FunctionScope::Data* functionScopeBindings_ = nullptr;
// Names from the extra 'var' scope of the function, if the parameter list
// has expressions.
ParserVarScopeData* extraVarScopeBindings_ = nullptr;
VarScope::Data* extraVarScopeBindings_ = nullptr;
// The explicit or implicit name of the function. The FunctionFlags indicate
// the kind of name.
// This is copied to ScriptStencil.
// Any update after the copy should be synced to the ScriptStencil.
const ParserAtom* atom_ = nullptr;
JSAtom* atom_ = nullptr;
// Index into CompilationInfo::{funcData, functions}.
FunctionIndex funcDataIndex_ = FunctionIndex(-1);
@ -430,8 +412,8 @@ class FunctionBox : public SharedContext {
FunctionBox(JSContext* cx, FunctionBox* traceListHead, SourceExtent extent,
CompilationInfo& compilationInfo, Directives directives,
GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
const ParserAtom* explicitName, FunctionFlags flags,
FunctionIndex index, TopLevelFunction isTopLevel);
JSAtom* explicitName, FunctionFlags flags, FunctionIndex index,
TopLevelFunction isTopLevel);
MutableHandle<ScriptStencil> functionStencil() const;
@ -439,21 +421,22 @@ class FunctionBox : public SharedContext {
bool atomsAreKept();
#endif
ParserLexicalScopeData* namedLambdaBindings() { return namedLambdaBindings_; }
void setNamedLambdaBindings(ParserLexicalScopeData* bindings) {
namedLambdaBindings_ = bindings;
MutableHandle<LexicalScope::Data*> namedLambdaBindings() {
MOZ_ASSERT(atomsAreKept());
return MutableHandle<LexicalScope::Data*>::fromMarkedLocation(
&namedLambdaBindings_);
}
ParserFunctionScopeData* functionScopeBindings() {
return functionScopeBindings_;
}
void setFunctionScopeBindings(ParserFunctionScopeData* bindings) {
functionScopeBindings_ = bindings;
MutableHandle<FunctionScope::Data*> functionScopeBindings() {
MOZ_ASSERT(atomsAreKept());
return MutableHandle<FunctionScope::Data*>::fromMarkedLocation(
&functionScopeBindings_);
}
ParserVarScopeData* extraVarScopeBindings() { return extraVarScopeBindings_; }
void setExtraVarScopeBindings(ParserVarScopeData* bindings) {
extraVarScopeBindings_ = bindings;
MutableHandle<VarScope::Data*> extraVarScopeBindings() {
MOZ_ASSERT(atomsAreKept());
return MutableHandle<VarScope::Data*>::fromMarkedLocation(
&extraVarScopeBindings_);
}
void initFromLazyFunction(JSFunction* fun);
@ -570,22 +553,22 @@ class FunctionBox : public SharedContext {
bool hasInferredName() const { return flags_.hasInferredName(); }
bool hasGuessedAtom() const { return flags_.hasGuessedAtom(); }
const ParserAtom* displayAtom() const { return atom_; }
const ParserAtom* explicitName() const {
JSAtom* displayAtom() const { return atom_; }
JSAtom* explicitName() const {
return (hasInferredName() || hasGuessedAtom()) ? nullptr : atom_;
}
// NOTE: We propagate to any existing functions for now. This handles both the
// delazification case where functions already exist, and also handles
// code-coverage which is not yet deferred.
void setInferredName(const ParserAtom* atom) {
void setInferredName(JSAtom* atom) {
atom_ = atom;
flags_.setInferredName();
if (isFunctionFieldCopiedToStencil) {
copyUpdatedAtomAndFlags();
}
}
void setGuessedAtom(const ParserAtom* atom) {
void setGuessedAtom(JSAtom* atom) {
atom_ = atom;
flags_.setGuessedAtom();
if (isFunctionFieldCopiedToStencil) {

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

@ -120,8 +120,46 @@ Scope* ScopeStencil::createScope(JSContext* cx,
}
void ScopeStencil::trace(JSTracer* trc) {
// NOTE: Scope::Data fields such as `canonicalFunction` are always nullptr
// while owned by a ScopeStencil so no additional tracing is needed.
// Trace Datas
if (data_) {
switch (kind()) {
case ScopeKind::Function: {
data<FunctionScope>().trace(trc);
break;
}
case ScopeKind::Lexical:
case ScopeKind::SimpleCatch:
case ScopeKind::Catch:
case ScopeKind::NamedLambda:
case ScopeKind::StrictNamedLambda:
case ScopeKind::FunctionLexical:
case ScopeKind::ClassBody: {
data<LexicalScope>().trace(trc);
break;
}
case ScopeKind::FunctionBodyVar: {
data<VarScope>().trace(trc);
break;
}
case ScopeKind::Global:
case ScopeKind::NonSyntactic: {
data<GlobalScope>().trace(trc);
break;
}
case ScopeKind::Eval:
case ScopeKind::StrictEval: {
data<EvalScope>().trace(trc);
break;
}
case ScopeKind::Module: {
data<ModuleScope>().trace(trc);
break;
}
case ScopeKind::With:
default:
MOZ_CRASH("Unexpected data type");
}
}
}
uint32_t ScopeStencil::nextFrameSlot() const {
@ -159,7 +197,20 @@ uint32_t ScopeStencil::nextFrameSlot() const {
MOZ_CRASH("Not an enclosing intra-frame scope");
}
void StencilModuleEntry::trace(JSTracer* trc) {}
void StencilModuleEntry::trace(JSTracer* trc) {
if (specifier) {
TraceManuallyBarrieredEdge(trc, &specifier, "module specifier");
}
if (localName) {
TraceManuallyBarrieredEdge(trc, &localName, "module local name");
}
if (importName) {
TraceManuallyBarrieredEdge(trc, &importName, "module import name");
}
if (exportName) {
TraceManuallyBarrieredEdge(trc, &exportName, "module export name");
}
}
void StencilModuleMetadata::trace(JSTracer* trc) {
requestedModules.trace(trc);
@ -169,7 +220,19 @@ void StencilModuleMetadata::trace(JSTracer* trc) {
starExportEntries.trace(trc);
}
void ScriptStencil::trace(JSTracer* trc) {}
void ScriptStencil::trace(JSTracer* trc) {
for (ScriptThingVariant& thing : gcThings) {
if (thing.is<ScriptAtom>()) {
JSAtom* atom = thing.as<ScriptAtom>();
TraceRoot(trc, &atom, "script-atom");
MOZ_ASSERT(atom == thing.as<ScriptAtom>(), "Atoms should be unmovable");
}
}
if (functionAtom) {
TraceRoot(trc, &functionAtom, "script-atom");
}
}
static bool CreateLazyScript(JSContext* cx, CompilationInfo& compilationInfo,
ScriptStencil& stencil, HandleFunction function) {
@ -220,14 +283,7 @@ static JSFunction* CreateFunction(JSContext* cx,
JSNative maybeNative = isAsmJS ? InstantiateAsmJS : nullptr;
RootedAtom displayAtom(cx);
if (stencil.functionAtom) {
displayAtom.set(
compilationInfo.liftParserAtomToJSAtom(stencil.functionAtom));
if (!displayAtom) {
return nullptr;
}
}
RootedAtom displayAtom(cx, stencil.functionAtom);
RootedFunction fun(
cx, NewFunctionWithProto(cx, maybeNative, stencil.nargs,
stencil.functionFlags, nullptr, displayAtom,
@ -291,7 +347,7 @@ static bool MaybeInstantiateModule(JSContext* cx,
}
if (!compilationInfo.moduleMetadata.get().initModule(
cx, compilationInfo, compilationInfo.module)) {
cx, compilationInfo.module)) {
return false;
}
}
@ -459,7 +515,7 @@ static bool InstantiateTopLevel(JSContext* cx,
// to update it with information determined by the BytecodeEmitter. This applies
// to both initial and delazification parses. The functions being update may or
// may not have bytecode at this point.
static bool UpdateEmittedInnerFunctions(CompilationInfo& compilationInfo) {
static void UpdateEmittedInnerFunctions(CompilationInfo& compilationInfo) {
for (auto item : compilationInfo.functionScriptStencils()) {
auto& stencil = item.stencil;
auto& fun = item.function;
@ -489,24 +545,15 @@ static bool UpdateEmittedInnerFunctions(CompilationInfo& compilationInfo) {
// Inferred and Guessed names are computed by BytecodeEmitter and so may
// need to be applied to existing JSFunctions during delazification.
if (fun->displayAtom() == nullptr) {
JSAtom* funcAtom = nullptr;
if (stencil.functionFlags.hasInferredName() ||
stencil.functionFlags.hasGuessedAtom()) {
funcAtom = compilationInfo.liftParserAtomToJSAtom(stencil.functionAtom);
if (!funcAtom) {
return false;
}
}
if (stencil.functionFlags.hasInferredName()) {
fun->setInferredName(funcAtom);
fun->setInferredName(stencil.functionAtom);
}
if (stencil.functionFlags.hasGuessedAtom()) {
fun->setGuessedAtom(funcAtom);
fun->setGuessedAtom(stencil.functionAtom);
}
}
}
return true;
}
// During initial parse we must link lazy-functions-inside-lazy-functions to
@ -593,9 +640,7 @@ bool CompilationInfo::instantiateStencils() {
// Must be infallible from here forward.
if (!UpdateEmittedInnerFunctions(*this)) {
return false;
}
UpdateEmittedInnerFunctions(*this);
if (lazy == nullptr) {
LinkEnclosingLazyScript(*this);
@ -714,12 +759,12 @@ void ScopeStencil::dumpFields(js::JSONPrinter& json) {
json.beginObjectProperty("data");
AbstractTrailingNamesArray<const ParserAtom>* trailingNames = nullptr;
AbstractTrailingNamesArray<JSAtom>* trailingNames = nullptr;
uint32_t length = 0;
switch (kind_) {
case ScopeKind::Function: {
auto* data = static_cast<ParserFunctionScopeData*>(data_);
auto* data = static_cast<FunctionScope::Data*>(data_.get());
json.property("nextFrameSlot", data->nextFrameSlot);
json.property("hasParameterExprs", data->hasParameterExprs);
json.property("nonPositionalFormalStart", data->nonPositionalFormalStart);
@ -731,7 +776,7 @@ void ScopeStencil::dumpFields(js::JSONPrinter& json) {
}
case ScopeKind::FunctionBodyVar: {
auto* data = static_cast<ParserVarScopeData*>(data_);
auto* data = static_cast<VarScope::Data*>(data_.get());
json.property("nextFrameSlot", data->nextFrameSlot);
trailingNames = &data->trailingNames;
@ -746,7 +791,7 @@ void ScopeStencil::dumpFields(js::JSONPrinter& json) {
case ScopeKind::StrictNamedLambda:
case ScopeKind::FunctionLexical:
case ScopeKind::ClassBody: {
auto* data = static_cast<ParserLexicalScopeData*>(data_);
auto* data = static_cast<LexicalScope::Data*>(data_.get());
json.property("nextFrameSlot", data->nextFrameSlot);
json.property("constStart", data->constStart);
@ -761,7 +806,7 @@ void ScopeStencil::dumpFields(js::JSONPrinter& json) {
case ScopeKind::Eval:
case ScopeKind::StrictEval: {
auto* data = static_cast<ParserEvalScopeData*>(data_);
auto* data = static_cast<EvalScope::Data*>(data_.get());
json.property("nextFrameSlot", data->nextFrameSlot);
trailingNames = &data->trailingNames;
@ -771,7 +816,7 @@ void ScopeStencil::dumpFields(js::JSONPrinter& json) {
case ScopeKind::Global:
case ScopeKind::NonSyntactic: {
auto* data = static_cast<ParserGlobalScopeData*>(data_);
auto* data = static_cast<GlobalScope::Data*>(data_.get());
json.property("letStart", data->letStart);
json.property("constStart", data->constStart);
@ -781,7 +826,7 @@ void ScopeStencil::dumpFields(js::JSONPrinter& json) {
}
case ScopeKind::Module: {
auto* data = static_cast<ParserModuleScopeData*>(data_);
auto* data = static_cast<ModuleScope::Data*>(data_.get());
json.property("nextFrameSlot", data->nextFrameSlot);
json.property("varStart", data->varStart);
json.property("letStart", data->letStart);
@ -793,9 +838,7 @@ void ScopeStencil::dumpFields(js::JSONPrinter& json) {
}
case ScopeKind::WasmInstance: {
auto* data =
static_cast<AbstractScopeData<WasmInstanceScope, const ParserAtom>*>(
data_);
auto* data = static_cast<WasmInstanceScope::Data*>(data_.get());
json.property("nextFrameSlot", data->nextFrameSlot);
json.property("globalsStart", data->globalsStart);
@ -805,9 +848,7 @@ void ScopeStencil::dumpFields(js::JSONPrinter& json) {
}
case ScopeKind::WasmFunction: {
auto* data =
static_cast<AbstractScopeData<WasmFunctionScope, const ParserAtom>*>(
data_);
auto* data = static_cast<WasmFunctionScope::Data*>(data_.get());
json.property("nextFrameSlot", data->nextFrameSlot);
trailingNames = &data->trailingNames;
@ -1102,7 +1143,7 @@ static void DumpScriptThing(js::JSONPrinter& json, ScriptThingVariant& thing) {
void operator()(ScriptAtom& data) {
json.beginObject();
json.property("type", "ScriptAtom");
const ParserAtom* atom = data;
JSAtom* atom = data;
GenericPrinter& out = json.beginStringProperty("value");
atom->dumpCharsNoQuote(out);
json.endStringProperty();

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

@ -21,7 +21,7 @@
#include "js/GCVariant.h" // GC Support for mozilla::Variant
#include "js/RegExpFlags.h" // JS::RegExpFlags
#include "js/RootingAPI.h" // Handle
#include "js/TypeDecls.h" // JSContext
#include "js/TypeDecls.h" // JSContext,JSAtom,JSFunction
#include "js/UniquePtr.h" // js::UniquePtr
#include "js/Utility.h" // UniqueTwoByteChars
#include "js/Vector.h" // js::Vector
@ -48,19 +48,6 @@ class ScriptStencil;
class RegExpStencil;
class BigIntStencil;
using BaseParserScopeData = AbstractBaseScopeData<const ParserAtom>;
template <typename Scope>
using ParserScopeData = typename Scope::template AbstractData<const ParserAtom>;
using ParserGlobalScopeData = ParserScopeData<GlobalScope>;
using ParserEvalScopeData = ParserScopeData<EvalScope>;
using ParserLexicalScopeData = ParserScopeData<LexicalScope>;
using ParserFunctionScopeData = ParserScopeData<FunctionScope>;
using ParserModuleScopeData = ParserScopeData<ModuleScope>;
using ParserVarScopeData = ParserScopeData<VarScope>;
using ParserBindingIter = AbstractBindingIter<const ParserAtom>;
// [SMDOC] Script Stencil (Frontend Representation)
//
// Stencils are GC object free representations of artifacts created during
@ -177,16 +164,13 @@ class ScopeStencil {
// The list of binding and scope-specific data. Note that the back pointers to
// the owning JSFunction / ModuleObject are not set until Stencils are
// converted to GC allocations.
//
// !NOTE! This data is currently allocated on the CompilationInfo::lifoAlloc.
// TODO-Stencil: This must outlive the parse for stencil to be useful.
BaseParserScopeData* data_;
UniquePtr<BaseScopeData> data_;
public:
ScopeStencil(ScopeKind kind, mozilla::Maybe<ScopeIndex> enclosing,
uint32_t firstFrameSlot,
mozilla::Maybe<uint32_t> numEnvironmentSlots,
BaseParserScopeData* data = {},
UniquePtr<BaseScopeData> data = {},
mozilla::Maybe<FunctionIndex> functionIndex = mozilla::Nothing(),
bool isArrow = false)
: enclosing_(enclosing),
@ -195,22 +179,21 @@ class ScopeStencil {
numEnvironmentSlots_(numEnvironmentSlots),
functionIndex_(functionIndex),
isArrow_(isArrow),
data_(data) {}
data_(std::move(data)) {}
static bool createForFunctionScope(
JSContext* cx, CompilationInfo& compilationInfo,
ParserFunctionScopeData* dataArg, bool hasParameterExprs,
Handle<FunctionScope::Data*> dataArg, bool hasParameterExprs,
bool needsEnvironment, FunctionIndex functionIndex, bool isArrow,
mozilla::Maybe<ScopeIndex> enclosing, ScopeIndex* index);
static bool createForLexicalScope(
JSContext* cx, CompilationInfo& compilationInfo, ScopeKind kind,
ParserLexicalScopeData* dataArg, uint32_t firstFrameSlot,
Handle<LexicalScope::Data*> dataArg, uint32_t firstFrameSlot,
mozilla::Maybe<ScopeIndex> enclosing, ScopeIndex* index);
static bool createForVarScope(JSContext* cx,
frontend::CompilationInfo& compilationInfo,
ScopeKind kind, ParserVarScopeData* dataArg,
static bool createForVarScope(JSContext* cx, CompilationInfo& compilationInfo,
ScopeKind kind, Handle<VarScope::Data*> dataArg,
uint32_t firstFrameSlot, bool needsEnvironment,
mozilla::Maybe<ScopeIndex> enclosing,
ScopeIndex* index);
@ -218,18 +201,19 @@ class ScopeStencil {
static bool createForGlobalScope(JSContext* cx,
CompilationInfo& compilationInfo,
ScopeKind kind,
ParserGlobalScopeData* dataArg,
Handle<GlobalScope::Data*> dataArg,
ScopeIndex* index);
static bool createForEvalScope(JSContext* cx,
CompilationInfo& compilationInfo,
ScopeKind kind, ParserEvalScopeData* dataArg,
ScopeKind kind,
Handle<EvalScope::Data*> dataArg,
mozilla::Maybe<ScopeIndex> enclosing,
ScopeIndex* index);
static bool createForModuleScope(JSContext* cx,
CompilationInfo& compilationInfo,
ParserModuleScopeData* dataArg,
Handle<ModuleScope::Data*> dataArg,
mozilla::Maybe<ScopeIndex> enclosing,
ScopeIndex* index);
@ -266,19 +250,15 @@ class ScopeStencil {
private:
// Non owning reference to data
template <typename SpecificScopeType>
typename SpecificScopeType::template AbstractData<const ParserAtom>& data()
const {
using Data =
typename SpecificScopeType ::template AbstractData<const ParserAtom>;
MOZ_ASSERT(data_);
return *static_cast<Data*>(data_);
typename SpecificScopeType::Data& data() const {
MOZ_ASSERT(data_.get());
return *static_cast<typename SpecificScopeType::Data*>(data_.get());
}
// Transfer ownership into a new UniquePtr.
template <typename SpecificScopeType>
UniquePtr<typename SpecificScopeType::Data> createSpecificScopeData(
JSContext* cx, CompilationInfo& compilationInfo);
UniquePtr<typename SpecificScopeType::Data> releaseData(
CompilationInfo& compilationInfo);
template <typename SpecificScopeType>
uint32_t nextFrameSlot() const {
@ -322,10 +302,10 @@ class StencilModuleEntry {
// localName | null | required | required | nullptr |
// importName | null | required | nullptr | required |
// exportName | null | null | required | optional |
const ParserAtom* specifier = nullptr;
const ParserAtom* localName = nullptr;
const ParserAtom* importName = nullptr;
const ParserAtom* exportName = nullptr;
JSAtom* specifier = nullptr;
JSAtom* localName = nullptr;
JSAtom* importName = nullptr;
JSAtom* exportName = nullptr;
// Location used for error messages. If this is for a module request entry
// then it is the module specifier string, otherwise the import/export spec
@ -339,18 +319,17 @@ class StencilModuleEntry {
: lineno(lineno), column(column) {}
public:
static StencilModuleEntry moduleRequest(const ParserAtom* specifier,
uint32_t lineno, uint32_t column) {
static StencilModuleEntry moduleRequest(JSAtom* specifier, uint32_t lineno,
uint32_t column) {
MOZ_ASSERT(specifier);
StencilModuleEntry entry(lineno, column);
entry.specifier = specifier;
return entry;
}
static StencilModuleEntry importEntry(const ParserAtom* specifier,
const ParserAtom* localName,
const ParserAtom* importName,
uint32_t lineno, uint32_t column) {
static StencilModuleEntry importEntry(JSAtom* specifier, JSAtom* localName,
JSAtom* importName, uint32_t lineno,
uint32_t column) {
MOZ_ASSERT(specifier && localName && importName);
StencilModuleEntry entry(lineno, column);
entry.specifier = specifier;
@ -359,8 +338,7 @@ class StencilModuleEntry {
return entry;
}
static StencilModuleEntry exportAsEntry(const ParserAtom* localName,
const ParserAtom* exportName,
static StencilModuleEntry exportAsEntry(JSAtom* localName, JSAtom* exportName,
uint32_t lineno, uint32_t column) {
MOZ_ASSERT(localName && exportName);
StencilModuleEntry entry(lineno, column);
@ -369,10 +347,10 @@ class StencilModuleEntry {
return entry;
}
static StencilModuleEntry exportFromEntry(const ParserAtom* specifier,
const ParserAtom* importName,
const ParserAtom* exportName,
uint32_t lineno, uint32_t column) {
static StencilModuleEntry exportFromEntry(JSAtom* specifier,
JSAtom* importName,
JSAtom* exportName, uint32_t lineno,
uint32_t column) {
// NOTE: The `export * from "mod";` syntax generates nullptr exportName.
MOZ_ASSERT(specifier && importName);
StencilModuleEntry entry(lineno, column);
@ -407,8 +385,7 @@ class StencilModuleMetadata {
starExportEntries(cx),
functionDecls(cx) {}
bool initModule(JSContext* cx, CompilationInfo& compilationInfo,
JS::Handle<ModuleObject*> module);
bool initModule(JSContext* cx, JS::Handle<ModuleObject*> module);
void trace(JSTracer* trc);
@ -420,10 +397,9 @@ class StencilModuleMetadata {
};
// The lazy closed-over-binding info is represented by these types that will
// convert to a nullptr.
// convert to a GCCellPtr(nullptr), GCCellPtr(JSAtom*).
class NullScriptThing {};
using ScriptAtom = const ParserAtom*;
using ScriptAtom = JSAtom*;
// These types all end up being baked into GC things as part of stencil
// instantiation.
@ -467,7 +443,7 @@ class ScriptStencil {
// The explicit or implicit name of the function. The FunctionFlags indicate
// the kind of name.
const ParserAtom* functionAtom = nullptr;
JSAtom* functionAtom = nullptr;
// See: `FunctionFlags`.
FunctionFlags functionFlags = {};

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

@ -122,7 +122,7 @@ bool SwitchEmitter::emitDiscriminant(const Maybe<uint32_t>& switchPos) {
return true;
}
bool SwitchEmitter::emitLexical(ParserLexicalScopeData* bindings) {
bool SwitchEmitter::emitLexical(Handle<LexicalScope::Data*> bindings) {
MOZ_ASSERT(state_ == State::Discriminant);
MOZ_ASSERT(bindings);

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

@ -441,7 +441,7 @@ class MOZ_STACK_CLASS SwitchEmitter {
// `bindings` is a lexical scope for the entire switch, in case there's
// let/const effectively directly under case or default blocks.
MOZ_MUST_USE bool emitLexical(ParserLexicalScopeData* bindings);
MOZ_MUST_USE bool emitLexical(Handle<LexicalScope::Data*> bindings);
MOZ_MUST_USE bool emitCond();
MOZ_MUST_USE bool emitTable(const TableGenerator& tableGen);

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

@ -36,7 +36,7 @@ namespace frontend {
// amounts of code that never executes (which happens often).
class SyntaxParseHandler {
// Remember the last encountered name or string literal during syntax parses.
const ParserAtom* lastAtom;
JSAtom* lastAtom;
TokenPos lastStringPos;
// WARNING: Be careful about adding fields to this function, that might be
@ -192,8 +192,7 @@ class SyntaxParseHandler {
FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
#undef DECLARE_AS
NameNodeType newName(const ParserName* name, const TokenPos& pos,
JSContext* cx) {
NameNodeType newName(PropertyName* name, const TokenPos& pos, JSContext* cx) {
lastAtom = name;
if (name == cx->parserNames().arguments) {
return NodeArgumentsName;
@ -212,12 +211,11 @@ class SyntaxParseHandler {
return NodeGeneric;
}
NameNodeType newObjectLiteralPropertyName(const ParserAtom* atom,
const TokenPos& pos) {
NameNodeType newObjectLiteralPropertyName(JSAtom* atom, const TokenPos& pos) {
return NodeName;
}
NameNodeType newPrivateName(const ParserAtom* atom, const TokenPos& pos) {
NameNodeType newPrivateName(JSAtom* atom, const TokenPos& pos) {
return NodePrivateName;
}
@ -232,14 +230,13 @@ class SyntaxParseHandler {
return NodeGeneric;
}
NameNodeType newStringLiteral(const ParserAtom* atom, const TokenPos& pos) {
NameNodeType newStringLiteral(JSAtom* atom, const TokenPos& pos) {
lastAtom = atom;
lastStringPos = pos;
return NodeUnparenthesizedString;
}
NameNodeType newTemplateStringLiteral(const ParserAtom* atom,
const TokenPos& pos) {
NameNodeType newTemplateStringLiteral(JSAtom* atom, const TokenPos& pos) {
return NodeGeneric;
}
@ -461,11 +458,11 @@ class SyntaxParseHandler {
CaseClauseType newCaseOrDefault(uint32_t begin, Node expr, Node body) {
return NodeGeneric;
}
ContinueStatementType newContinueStatement(const ParserName* label,
ContinueStatementType newContinueStatement(PropertyName* label,
const TokenPos& pos) {
return NodeGeneric;
}
BreakStatementType newBreakStatement(const ParserName* label,
BreakStatementType newBreakStatement(PropertyName* label,
const TokenPos& pos) {
return NodeBreak;
}
@ -477,7 +474,7 @@ class SyntaxParseHandler {
return NodeGeneric;
}
LabeledStatementType newLabeledStatement(const ParserName* label, Node stmt,
LabeledStatementType newLabeledStatement(PropertyName* label, Node stmt,
uint32_t begin) {
return NodeGeneric;
}
@ -494,7 +491,7 @@ class SyntaxParseHandler {
return NodeGeneric;
}
NameNodeType newPropertyName(const ParserName* name, const TokenPos& pos) {
NameNodeType newPropertyName(PropertyName* name, const TokenPos& pos) {
lastAtom = name;
return NodeGeneric;
}
@ -703,7 +700,7 @@ class SyntaxParseHandler {
bool isPrivateName(Node node) { return node == NodePrivateName; }
bool isPrivateField(Node node) { return node == NodePrivateElement; }
const ParserName* maybeDottedProperty(Node node) {
PropertyName* maybeDottedProperty(Node node) {
// Note: |super.apply(...)| is a special form that calls an "apply"
// method retrieved from one value, but using a *different* value as
// |this|. It's not really eligible for the funapply/funcall
@ -712,10 +709,10 @@ class SyntaxParseHandler {
if (node != NodeDottedProperty && node != NodeOptionalDottedProperty) {
return nullptr;
}
return lastAtom->asName();
return lastAtom->asPropertyName();
}
const ParserAtom* isStringExprStatement(Node pn, TokenPos* pos) {
JSAtom* isStringExprStatement(Node pn, TokenPos* pos) {
if (pn == NodeStringExprStatement) {
*pos = lastStringPos;
return lastAtom;

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

@ -24,7 +24,7 @@ bool TDZCheckCache::ensureCache(BytecodeEmitter* bce) {
}
Maybe<MaybeCheckTDZ> TDZCheckCache::needsTDZCheck(BytecodeEmitter* bce,
const ParserAtom* name) {
JSAtom* name) {
if (!ensureCache(bce)) {
return Nothing();
}
@ -52,7 +52,7 @@ Maybe<MaybeCheckTDZ> TDZCheckCache::needsTDZCheck(BytecodeEmitter* bce,
return Some(rv);
}
bool TDZCheckCache::noteTDZCheck(BytecodeEmitter* bce, const ParserAtom* name,
bool TDZCheckCache::noteTDZCheck(BytecodeEmitter* bce, JSAtom* name,
MaybeCheckTDZ check) {
if (!ensureCache(bce)) {
return false;

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

@ -47,8 +47,8 @@ class TDZCheckCache : public Nestable<TDZCheckCache> {
explicit TDZCheckCache(BytecodeEmitter* bce);
mozilla::Maybe<MaybeCheckTDZ> needsTDZCheck(BytecodeEmitter* bce,
const ParserAtom* name);
MOZ_MUST_USE bool noteTDZCheck(BytecodeEmitter* bce, const ParserAtom* name,
JSAtom* name);
MOZ_MUST_USE bool noteTDZCheck(BytecodeEmitter* bce, JSAtom* name,
MaybeCheckTDZ check);
};

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

@ -16,9 +16,9 @@
#include <stdint.h> // uint32_t
#include "frontend/ParserAtom.h" // js::frontend::{ParserAtom,ParserName}
#include "frontend/TokenKind.h" // js::frontend::TokenKind
#include "js/RegExpFlags.h" // JS::RegExpFlags
#include "vm/StringType.h" // js::PropertyName
namespace js {
@ -144,10 +144,10 @@ struct Token {
friend struct Token;
/** Non-numeric atom. */
const ParserName* name;
PropertyName* name;
/** Potentially-numeric atom. */
const ParserAtom* atom;
JSAtom* atom;
struct {
/** Numeric literal's value. */
@ -168,12 +168,12 @@ struct Token {
// Mutators
void setName(const ParserName* name) {
void setName(PropertyName* name) {
MOZ_ASSERT(type == TokenKind::Name || type == TokenKind::PrivateName);
u.name = name;
}
void setAtom(const ParserAtom* atom) {
void setAtom(JSAtom* atom) {
MOZ_ASSERT(type == TokenKind::String || type == TokenKind::TemplateHead ||
type == TokenKind::NoSubsTemplate);
u.atom = atom;
@ -192,12 +192,12 @@ struct Token {
// Type-safe accessors
const ParserName* name() const {
PropertyName* name() const {
MOZ_ASSERT(type == TokenKind::Name || type == TokenKind::PrivateName);
return u.name->asName(); // poor-man's type verification
return u.name->JSAtom::asPropertyName(); // poor-man's type verification
}
const ParserAtom* atom() const {
JSAtom* atom() const {
MOZ_ASSERT(type == TokenKind::String || type == TokenKind::TemplateHead ||
type == TokenKind::NoSubsTemplate);
return u.atom;

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

@ -33,7 +33,6 @@
#include "frontend/BytecodeCompiler.h"
#include "frontend/Parser.h"
#include "frontend/ParserAtom.h"
#include "frontend/ReservedWords.h"
#include "js/CharacterEncoding.h"
#include "js/RegExpFlags.h" // JS::RegExpFlags
@ -126,34 +125,28 @@ MOZ_ALWAYS_INLINE const ReservedWordInfo* FindReservedWord<Utf8Unit>(
return FindReservedWord(Utf8AsUnsignedChars(units), length);
}
template <typename CharT>
static const ReservedWordInfo* FindReservedWord(
const CharT* chars, size_t length,
js::frontend::NameVisibility* visibility) {
JSLinearString* str, js::frontend::NameVisibility* visibility) {
JS::AutoCheckCannotGC nogc;
if (str->hasLatin1Chars()) {
const JS::Latin1Char* chars = str->latin1Chars(nogc);
size_t length = str->length();
if (length > 0 && chars[0] == '#') {
*visibility = js::frontend::NameVisibility::Private;
return nullptr;
}
*visibility = js::frontend::NameVisibility::Public;
return FindReservedWord(chars, length);
}
static const ReservedWordInfo* FindReservedWord(
JSLinearString* str, js::frontend::NameVisibility* visibility) {
JS::AutoCheckCannotGC nogc;
if (str->hasLatin1Chars()) {
return FindReservedWord(str->latin1Chars(nogc), str->length(), visibility);
}
return FindReservedWord(str->twoByteChars(nogc), str->length(), visibility);
}
static const ReservedWordInfo* FindReservedWord(
const js::frontend::ParserAtomEntry* atom,
js::frontend::NameVisibility* visibility) {
if (atom->hasLatin1Chars()) {
return FindReservedWord(atom->latin1Chars(), atom->length(), visibility);
const char16_t* chars = str->twoByteChars(nogc);
size_t length = str->length();
if (length > 0 && chars[0] == '#') {
*visibility = js::frontend::NameVisibility::Private;
return nullptr;
}
return FindReservedWord(atom->twoByteChars(), atom->length(), visibility);
*visibility = js::frontend::NameVisibility::Public;
return FindReservedWord(chars, length);
}
static uint32_t GetSingleCodePoint(const char16_t** p, const char16_t* end) {
@ -207,12 +200,6 @@ bool IsIdentifier(JSLinearString* str) {
}
return IsIdentifier(str->twoByteChars(nogc), str->length());
}
bool IsIdentifier(const ParserAtom* atom) {
MOZ_ASSERT(atom);
return atom->hasLatin1Chars()
? IsIdentifier(atom->latin1Chars(), atom->length())
: IsIdentifier(atom->twoByteChars(), atom->length());
}
bool IsIdentifierNameOrPrivateName(JSLinearString* str) {
JS::AutoCheckCannotGC nogc;
@ -222,12 +209,6 @@ bool IsIdentifierNameOrPrivateName(JSLinearString* str) {
}
return IsIdentifierNameOrPrivateName(str->twoByteChars(nogc), str->length());
}
bool IsIdentifierNameOrPrivateName(const ParserAtom* atom) {
if (atom->hasLatin1Chars()) {
return IsIdentifierNameOrPrivateName(atom->latin1Chars(), atom->length());
}
return IsIdentifierNameOrPrivateName(atom->twoByteChars(), atom->length());
}
bool IsIdentifier(const Latin1Char* chars, size_t length) {
if (length == 0) {
@ -321,14 +302,6 @@ bool IsIdentifierNameOrPrivateName(const char16_t* chars, size_t length) {
return true;
}
bool IsKeyword(const ParserAtom* atom) {
NameVisibility visibility;
if (const ReservedWordInfo* rw = FindReservedWord(atom, &visibility)) {
return TokenKindIsKeyword(rw->tokentype);
}
return false;
}
bool IsKeyword(JSLinearString* str) {
NameVisibility visibility;
if (const ReservedWordInfo* rw = FindReservedWord(str, &visibility)) {
@ -338,9 +311,9 @@ bool IsKeyword(JSLinearString* str) {
return false;
}
TokenKind ReservedWordTokenKind(const ParserName* name) {
TokenKind ReservedWordTokenKind(PropertyName* str) {
NameVisibility visibility;
if (const ReservedWordInfo* rw = FindReservedWord(name, &visibility)) {
if (const ReservedWordInfo* rw = FindReservedWord(str, &visibility)) {
return rw->tokentype;
}
@ -348,9 +321,9 @@ TokenKind ReservedWordTokenKind(const ParserName* name) {
: TokenKind::Name;
}
const char* ReservedWordToCharZ(const ParserName* name) {
const char* ReservedWordToCharZ(PropertyName* str) {
NameVisibility visibility;
if (const ReservedWordInfo* rw = FindReservedWord(name, &visibility)) {
if (const ReservedWordInfo* rw = FindReservedWord(str, &visibility)) {
return ReservedWordToCharZ(rw->tokentype);
}
@ -371,7 +344,7 @@ const char* ReservedWordToCharZ(TokenKind tt) {
return nullptr;
}
const ParserName* TokenStreamAnyChars::reservedWordToPropertyName(
PropertyName* TokenStreamAnyChars::reservedWordToPropertyName(
TokenKind tt) const {
MOZ_ASSERT(tt != TokenKind::Name);
switch (tt) {
@ -2251,7 +2224,7 @@ MOZ_MUST_USE bool TokenStreamSpecific<Unit, AnyCharsAccess>::identifierName(
}
}
const ParserAtom* atom = nullptr;
JSAtom* atom;
if (MOZ_UNLIKELY(escaping == IdentifierEscapes::SawUnicodeEscape)) {
// Identifiers containing Unicode escapes have to be converted into
// tokenbuf before atomizing.
@ -2283,10 +2256,10 @@ MOZ_MUST_USE bool TokenStreamSpecific<Unit, AnyCharsAccess>::identifierName(
noteBadToken.release();
if (visibility == NameVisibility::Private) {
newPrivateNameToken(atom->asName(), start, modifier, out);
newPrivateNameToken(atom->asPropertyName(), start, modifier, out);
return true;
}
newNameToken(atom->asName(), start, modifier, out);
newNameToken(atom->asPropertyName(), start, modifier, out);
return true;
}
@ -3696,7 +3669,7 @@ bool TokenStreamSpecific<Unit, AnyCharsAccess>::getStringOrTemplateToken(
}
}
const ParserAtom* atom = drainCharBufferIntoAtom();
JSAtom* atom = drainCharBufferIntoAtom();
if (!atom) {
return false;
}

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

@ -205,7 +205,6 @@
#include "frontend/CompilationInfo.h"
#include "frontend/ErrorReporter.h"
#include "frontend/ParserAtom.h"
#include "frontend/Token.h"
#include "frontend/TokenKind.h"
#include "js/CompileOptions.h"
@ -228,9 +227,9 @@ class AutoKeepAtoms;
namespace frontend {
extern TokenKind ReservedWordTokenKind(const ParserName* name);
extern TokenKind ReservedWordTokenKind(PropertyName* str);
extern const char* ReservedWordToCharZ(const ParserName* name);
extern const char* ReservedWordToCharZ(PropertyName* str);
extern const char* ReservedWordToCharZ(TokenKind tt);
@ -731,10 +730,10 @@ class TokenStreamAnyChars : public TokenStreamShared {
MOZ_MUST_USE bool checkOptions();
private:
const ParserName* reservedWordToPropertyName(TokenKind tt) const;
PropertyName* reservedWordToPropertyName(TokenKind tt) const;
public:
const ParserName* currentName() const {
PropertyName* currentName() const {
if (isCurrentTokenType(TokenKind::Name) ||
isCurrentTokenType(TokenKind::PrivateName)) {
return currentToken().name();
@ -748,8 +747,7 @@ class TokenStreamAnyChars : public TokenStreamShared {
if (isCurrentTokenType(TokenKind::Name) ||
isCurrentTokenType(TokenKind::PrivateName)) {
TokenPos pos = currentToken().pos;
const ParserAtom* name = currentToken().name();
return (pos.end - pos.begin) != name->length();
return (pos.end - pos.begin) != currentToken().name()->length();
}
MOZ_ASSERT(TokenKindIsPossibleIdentifierName(currentToken().type));
@ -1539,16 +1537,24 @@ class TokenStreamCharsShared {
return mozilla::IsAscii(static_cast<char32_t>(unit));
}
const ParserAtom* drainCharBufferIntoAtom() {
JSAtom* drainCharBufferIntoAtom() {
JSAtom* atom = AtomizeChars(this->compilationInfo->cx, charBuffer.begin(),
charBuffer.length());
if (!atom) {
return nullptr;
}
// Add to parser atoms table.
#ifdef JS_PARSER_ATOMS
auto maybeId = this->compilationInfo->parserAtoms.internChar16(
this->compilationInfo->cx, charBuffer.begin(), charBuffer.length());
if (maybeId.isErr()) {
return nullptr;
}
#endif // JS_PARSER_ATOMS
charBuffer.clear();
return maybeId.unwrap();
return atom;
}
protected:
@ -1609,8 +1615,7 @@ class TokenStreamCharsBase : public TokenStreamCharsShared {
sourceUnits.ungetCodeUnit();
}
MOZ_ALWAYS_INLINE const ParserAtom* atomizeSourceChars(
mozilla::Span<const Unit> units);
MOZ_ALWAYS_INLINE JSAtom* atomizeSourceChars(mozilla::Span<const Unit> units);
/**
* Try to match a non-LineTerminator ASCII code point. Return true iff it
@ -1696,21 +1701,45 @@ inline void TokenStreamCharsBase<Unit>::consumeKnownCodeUnit(int32_t unit) {
}
template <>
MOZ_ALWAYS_INLINE const ParserAtom*
TokenStreamCharsBase<char16_t>::atomizeSourceChars(
MOZ_ALWAYS_INLINE JSAtom* TokenStreamCharsBase<char16_t>::atomizeSourceChars(
mozilla::Span<const char16_t> units) {
return this->compilationInfo->parserAtoms
.internChar16(this->compilationInfo->cx, units.data(), units.size())
.unwrapOr(nullptr);
JSAtom* atom =
AtomizeChars(this->compilationInfo->cx, units.data(), units.size());
if (!atom) {
return nullptr;
}
#ifdef JS_PARSER_ATOMS
auto maybeId = this->compilationInfo->parserAtoms.internChar16(
this->compilationInfo->cx, units.data(), units.size());
if (maybeId.isErr()) {
return nullptr;
}
#endif // JS_PARSER_ATOMS
return atom;
}
template <>
/* static */ MOZ_ALWAYS_INLINE const ParserAtom*
/* static */ MOZ_ALWAYS_INLINE JSAtom*
TokenStreamCharsBase<mozilla::Utf8Unit>::atomizeSourceChars(
mozilla::Span<const mozilla::Utf8Unit> units) {
return this->compilationInfo->parserAtoms
.internUtf8(this->compilationInfo->cx, units.data(), units.size())
.unwrapOr(nullptr);
auto chars = ToCharSpan(units);
JSAtom* atom =
AtomizeUTF8Chars(this->compilationInfo->cx, chars.data(), chars.size());
if (!atom) {
return nullptr;
}
#ifdef JS_PARSER_ATOMS
auto maybeId = this->compilationInfo->parserAtoms.internUtf8(
this->compilationInfo->cx, units.data(), units.size());
if (maybeId.isErr()) {
return nullptr;
}
#endif // JS_PARSER_ATOMS
return atom;
}
template <typename Unit>
@ -1994,7 +2023,7 @@ class GeneralTokenStreamChars : public SpecializedTokenStreamCharsBase<Unit> {
newToken(TokenKind::BigInt, start, modifier, out);
}
void newAtomToken(TokenKind kind, const ParserAtom* atom, TokenStart start,
void newAtomToken(TokenKind kind, JSAtom* atom, TokenStart start,
TokenStreamShared::Modifier modifier, TokenKind* out) {
MOZ_ASSERT(kind == TokenKind::String || kind == TokenKind::TemplateHead ||
kind == TokenKind::NoSubsTemplate);
@ -2003,13 +2032,13 @@ class GeneralTokenStreamChars : public SpecializedTokenStreamCharsBase<Unit> {
token->setAtom(atom);
}
void newNameToken(const ParserName* name, TokenStart start,
void newNameToken(PropertyName* name, TokenStart start,
TokenStreamShared::Modifier modifier, TokenKind* out) {
Token* token = newToken(TokenKind::Name, start, modifier, out);
token->setName(name);
}
void newPrivateNameToken(const ParserName* name, TokenStart start,
void newPrivateNameToken(PropertyName* name, TokenStart start,
TokenStreamShared::Modifier modifier,
TokenKind* out) {
Token* token = newToken(TokenKind::PrivateName, start, modifier, out);
@ -2122,7 +2151,7 @@ class GeneralTokenStreamChars : public SpecializedTokenStreamCharsBase<Unit> {
*/
void consumeOptionalHashbangComment();
const ParserAtom* getRawTemplateStringAtom() {
JSAtom* getRawTemplateStringAtom() {
TokenStreamAnyChars& anyChars = anyCharsAccess();
MOZ_ASSERT(anyChars.currentToken().type == TokenKind::TemplateHead ||

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

@ -96,10 +96,10 @@ namespace frontend {
// clang-format on
struct UnboundPrivateName {
const ParserAtom* atom;
JSAtom* atom;
TokenPos position;
UnboundPrivateName(const ParserAtom* atom, TokenPos position)
UnboundPrivateName(JSAtom* atom, TokenPos position)
: atom(atom), position(position) {}
};
@ -165,8 +165,7 @@ class UsedNameTracker {
mozilla::Maybe<TokenPos> pos() { return firstUsePos_; }
};
using UsedNameMap = HashMap<const ParserAtom*, UsedNameInfo,
DefaultHasher<const ParserAtom*>>;
using UsedNameMap = HashMap<JSAtom*, UsedNameInfo, DefaultHasher<JSAtom*>>;
private:
// The map of names to chains of uses.
@ -193,13 +192,11 @@ class UsedNameTracker {
return scopeCounter_++;
}
UsedNameMap::Ptr lookup(const ParserAtom* name) const {
return map_.lookup(name);
}
UsedNameMap::Ptr lookup(JSAtom* name) const { return map_.lookup(name); }
MOZ_MUST_USE bool noteUse(
JSContext* cx, const ParserAtom* name, NameVisibility visibility,
uint32_t scriptId, uint32_t scopeId,
JSContext* cx, JSAtom* name, NameVisibility visbility, uint32_t scriptId,
uint32_t scopeId,
mozilla::Maybe<TokenPos> tokenPosition = mozilla::Nothing());
// Fill maybeUnboundName with the first (source order) unbound name, or

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

@ -465,8 +465,6 @@ JS_PUBLIC_API bool JS::InitSelfHostedCode(JSContext* cx) {
return false;
}
// Initialization of well-known ParserAtoms must happen AFTER
// initialization of the coresponding JSAtoms.
if (!rt->initializeParserAtoms(cx)) {
return false;
}

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

@ -26,8 +26,6 @@
#include "jstypes.h"
#include "double-conversion/double-conversion.h"
#include "frontend/CompilationInfo.h" // frontend::CompilationInfo
#include "frontend/ParserAtom.h" // frontend::ParserAtom
#include "js/CharacterEncoding.h"
#include "js/Conversions.h"
#if !JS_HAS_INTL_API
@ -847,23 +845,6 @@ JSAtom* js::Int32ToAtom(JSContext* cx, int32_t si) {
return atom;
}
const frontend::ParserAtom* js::Int32ToParserAtom(
frontend::CompilationInfo& compilationInfo, int32_t si) {
char buffer[JSFatInlineString::MAX_LENGTH_TWO_BYTE + 1];
size_t length;
char* start = BackfillInt32InBuffer(
si, buffer, JSFatInlineString::MAX_LENGTH_TWO_BYTE + 1, &length);
Maybe<uint32_t> indexValue;
if (si >= 0) {
indexValue.emplace(si);
}
return compilationInfo.parserAtoms
.internAscii(compilationInfo.cx, start, length)
.unwrapOr(nullptr);
}
/* Returns a non-nullptr pointer to inside cbuf. */
static char* Int32ToCString(ToCStringBuf* cbuf, int32_t i, size_t* len,
int base = 10) {
@ -1650,28 +1631,6 @@ JSAtom* js::NumberToAtom(JSContext* cx, double d) {
return atom;
}
const frontend::ParserAtom* js::NumberToParserAtom(
frontend::CompilationInfo& compilationInfo, double d) {
int32_t si;
if (NumberEqualsInt32(d, &si)) {
return Int32ToParserAtom(compilationInfo, si);
}
ToCStringBuf cbuf;
char* numStr = FracNumberToCString(compilationInfo.cx, &cbuf, d);
if (!numStr) {
ReportOutOfMemory(compilationInfo.cx);
return nullptr;
}
MOZ_ASSERT(!cbuf.dbuf && numStr >= cbuf.sbuf &&
numStr < cbuf.sbuf + cbuf.sbufSize);
size_t length = strlen(numStr);
return compilationInfo.parserAtoms
.internAscii(compilationInfo.cx, numStr, length)
.unwrapOr(nullptr);
}
JSLinearString* js::IndexToString(JSContext* cx, uint32_t index) {
if (StaticStrings::hasUint(index)) {
return cx->staticStrings().getUint(index);

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

@ -19,13 +19,6 @@
namespace js {
namespace frontend {
struct CompilationInfo;
class ParserAtom;
} // namespace frontend
class GlobalObject;
class StringBuffer;
@ -49,9 +42,6 @@ extern JSString* NumberToStringHelperPure(JSContext* cx, double d);
extern JSAtom* NumberToAtom(JSContext* cx, double d);
const frontend::ParserAtom* NumberToParserAtom(
frontend::CompilationInfo& compilationInfo, double d);
template <AllowGC allowGC>
extern JSLinearString* Int32ToString(JSContext* cx, int32_t i);
@ -59,9 +49,6 @@ extern JSLinearString* Int32ToStringHelperPure(JSContext* cx, int32_t i);
extern JSAtom* Int32ToAtom(JSContext* cx, int32_t si);
const frontend::ParserAtom* Int32ToParserAtom(
frontend::CompilationInfo& compilationInfo, int32_t si);
// ES6 15.7.3.12
extern bool IsInteger(const Value& val);

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

@ -12,8 +12,6 @@
#include <algorithm>
#include "frontend/CompilationInfo.h" // frontend::CompilationInfo
#include "frontend/ParserAtom.h" // frontend::ParserAtom
#include "vm/JSObject-inl.h"
#include "vm/StringType-inl.h"
@ -76,20 +74,6 @@ bool StringBuffer::inflateChars() {
return true;
}
bool StringBuffer::append(const frontend::ParserAtom* ent) {
if (isLatin1()) {
if (ent->hasLatin1Chars()) {
return latin1Chars().append(ent->latin1Chars(), ent->length());
}
if (!inflateChars()) {
return false;
}
}
return ent->hasLatin1Chars()
? twoByteChars().append(ent->latin1Chars(), ent->length())
: twoByteChars().append(ent->twoByteChars(), ent->length());
}
template <typename CharT>
JSLinearString* StringBuffer::finishStringInternal(JSContext* cx) {
size_t len = length();
@ -154,32 +138,6 @@ JSAtom* StringBuffer::finishAtom() {
return atom;
}
const frontend::ParserAtom* StringBuffer::finishParserAtom(
frontend::CompilationInfo& compilationInfo) {
size_t len = length();
if (len == 0) {
return cx_->parserNames().empty;
}
if (isLatin1()) {
auto result = compilationInfo.parserAtoms.internLatin1(
cx_, latin1Chars().begin(), len);
if (result.isErr()) {
return nullptr;
}
latin1Chars().clear();
return result.unwrap();
}
auto result = compilationInfo.parserAtoms.internChar16(
cx_, twoByteChars().begin(), len);
if (result.isErr()) {
return nullptr;
}
twoByteChars().clear();
return result.unwrap();
}
bool js::ValueToStringBufferSlow(JSContext* cx, const Value& arg,
StringBuffer& sb) {
RootedValue v(cx, arg);

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

@ -16,13 +16,6 @@
namespace js {
namespace frontend {
class ParserAtom;
struct CompilationInfo;
} // namespace frontend
class StringBufferAllocPolicy {
TempAllocPolicy impl_;
@ -243,7 +236,6 @@ class StringBuffer {
size_t len);
inline MOZ_MUST_USE bool appendSubstring(JSLinearString* base, size_t off,
size_t len);
MOZ_MUST_USE bool append(const frontend::ParserAtom* atom);
MOZ_MUST_USE bool append(const char* chars, size_t len) {
return append(reinterpret_cast<const Latin1Char*>(chars), len);
@ -319,8 +311,6 @@ class StringBuffer {
/* Identical to finishString() except that an atom is created. */
JSAtom* finishAtom();
const frontend::ParserAtom* finishParserAtom(
frontend::CompilationInfo& compilationInfo);
/*
* Creates a raw string from the characters in this buffer. The string is

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

@ -74,48 +74,43 @@ static bool IsPrototype(BuiltinObjectKind kind) {
MOZ_CRASH("Unexpected builtin object kind");
}
using BuiltinName =
const js::frontend::ParserName* js::frontend::WellKnownParserAtoms::*;
using BuiltinName = js::ImmutablePropertyNamePtr JSAtomState::*;
struct BuiltinObjectMap {
BuiltinName name;
BuiltinObjectKind kind;
};
BuiltinObjectKind js::BuiltinConstructorForName(
JSContext* cx, const js::frontend::ParserAtom* name) {
using WellKnownName = js::frontend::WellKnownParserAtoms;
BuiltinObjectKind js::BuiltinConstructorForName(JSContext* cx, JSAtom* name) {
static constexpr BuiltinObjectMap constructors[] = {
{&WellKnownName::Array, BuiltinObjectKind::Array},
{&WellKnownName::ArrayBuffer, BuiltinObjectKind::ArrayBuffer},
{&WellKnownName::Iterator, BuiltinObjectKind::Iterator},
{&WellKnownName::Promise, BuiltinObjectKind::Promise},
{&WellKnownName::RegExp, BuiltinObjectKind::RegExp},
{&WellKnownName::SharedArrayBuffer, BuiltinObjectKind::SharedArrayBuffer},
{&WellKnownName::DateTimeFormat, BuiltinObjectKind::DateTimeFormat},
{&WellKnownName::NumberFormat, BuiltinObjectKind::NumberFormat},
{&JSAtomState::Array, BuiltinObjectKind::Array},
{&JSAtomState::ArrayBuffer, BuiltinObjectKind::ArrayBuffer},
{&JSAtomState::Iterator, BuiltinObjectKind::Iterator},
{&JSAtomState::Promise, BuiltinObjectKind::Promise},
{&JSAtomState::RegExp, BuiltinObjectKind::RegExp},
{&JSAtomState::SharedArrayBuffer, BuiltinObjectKind::SharedArrayBuffer},
{&JSAtomState::DateTimeFormat, BuiltinObjectKind::DateTimeFormat},
{&JSAtomState::NumberFormat, BuiltinObjectKind::NumberFormat},
};
for (auto& builtin : constructors) {
if (name == cx->parserNames().*(builtin.name)) {
if (name == cx->names().*(builtin.name)) {
return builtin.kind;
}
}
return BuiltinObjectKind::None;
}
BuiltinObjectKind js::BuiltinPrototypeForName(
JSContext* cx, const js::frontend::ParserAtom* name) {
using WellKnownName = js::frontend::WellKnownParserAtoms;
BuiltinObjectKind js::BuiltinPrototypeForName(JSContext* cx, JSAtom* name) {
static constexpr BuiltinObjectMap prototypes[] = {
{&WellKnownName::Function, BuiltinObjectKind::FunctionPrototype},
{&WellKnownName::Object, BuiltinObjectKind::ObjectPrototype},
{&WellKnownName::RegExp, BuiltinObjectKind::RegExpPrototype},
{&WellKnownName::String, BuiltinObjectKind::StringPrototype},
{&JSAtomState::Function, BuiltinObjectKind::FunctionPrototype},
{&JSAtomState::Object, BuiltinObjectKind::ObjectPrototype},
{&JSAtomState::RegExp, BuiltinObjectKind::RegExpPrototype},
{&JSAtomState::String, BuiltinObjectKind::StringPrototype},
};
for (auto& builtin : prototypes) {
if (name == cx->parserNames().*(builtin.name)) {
if (name == cx->names().*(builtin.name)) {
return builtin.kind;
}
}

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

@ -17,10 +17,6 @@ class JS_PUBLIC_API JSObject;
namespace js {
namespace frontend {
class ParserAtom;
} // namespace frontend
class GlobalObject;
/**
@ -54,15 +50,13 @@ enum class BuiltinObjectKind : uint8_t {
* Return the BuiltinObjectKind for the given constructor name. Return
* BuiltinObjectKind::None if no matching constructor was found.
*/
BuiltinObjectKind BuiltinConstructorForName(JSContext* cx,
const frontend::ParserAtom* name);
BuiltinObjectKind BuiltinConstructorForName(JSContext* cx, JSAtom* name);
/**
* Return the BuiltinObjectKind for the given prototype name. Return
* BuiltinObjectKind::None if no matching prototype was found.
*/
BuiltinObjectKind BuiltinPrototypeForName(JSContext* cx,
const frontend::ParserAtom* name);
BuiltinObjectKind BuiltinPrototypeForName(JSContext* cx, JSAtom* name);
/**
* Return the built-in object if already created for the given global. Otherwise

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

@ -6,8 +6,6 @@
#include "vm/GeneratorObject.h"
#include "frontend/CompilationInfo.h"
#include "frontend/ParserAtom.h"
#include "js/PropertySpec.h"
#include "vm/AsyncFunction.h"
#include "vm/AsyncIteration.h"
@ -385,16 +383,14 @@ bool JSObject::is<js::AbstractGeneratorObject>() const {
is<AsyncGeneratorObject>();
}
GeneratorResumeKind js::ParserAtomToResumeKind(
frontend::CompilationInfo& compilationInfo,
const frontend::ParserAtom* atom) {
if (atom == compilationInfo.cx->parserNames().next) {
GeneratorResumeKind js::AtomToResumeKind(JSContext* cx, JSAtom* atom) {
if (atom == cx->names().next) {
return GeneratorResumeKind::Next;
}
if (atom == compilationInfo.cx->parserNames().throw_) {
if (atom == cx->names().throw_) {
return GeneratorResumeKind::Throw;
}
MOZ_ASSERT(atom == compilationInfo.cx->parserNames().return_);
MOZ_ASSERT(atom == cx->names().return_);
return GeneratorResumeKind::Return;
}

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

@ -17,11 +17,6 @@
namespace js {
namespace frontend {
class ParserAtom;
struct CompilationInfo;
} // namespace frontend
extern const JSClass GeneratorFunctionClass;
class AbstractGeneratorObject : public NativeObject {
@ -225,9 +220,7 @@ inline GeneratorResumeKind ResumeKindFromPC(jsbytecode* pc) {
return IntToResumeKind(GET_UINT8(pc));
}
GeneratorResumeKind ParserAtomToResumeKind(
frontend::CompilationInfo& compilationInfo,
const frontend::ParserAtom* atom);
GeneratorResumeKind AtomToResumeKind(JSContext* cx, JSAtom* atom);
JSAtom* ResumeKindToAtom(JSContext* cx, GeneratorResumeKind kind);
} // namespace js

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

@ -9,7 +9,6 @@
#include "jsapi.h"
#include "debugger/DebugAPI.h"
#include "frontend/CompilationInfo.h"
#include "proxy/DeadObjectProxy.h"
#include "vm/JSObject-inl.h"
@ -93,14 +92,15 @@ static bool StringToInstrumentationKind(JSContext* cx, HandleString str,
}
/* static */
const frontend::ParserAtom* RealmInstrumentation::getInstrumentationKindName(
frontend::CompilationInfo& compilationInfo, InstrumentationKind kind) {
JSAtom* RealmInstrumentation::getInstrumentationKindName(
JSContext* cx, InstrumentationKind kind) {
for (size_t i = 0; i < mozilla::ArrayLength(instrumentationNames); i++) {
if (kind == (InstrumentationKind)(1 << i)) {
return compilationInfo.parserAtoms
.internAscii(compilationInfo.cx, instrumentationNames[i],
strlen(instrumentationNames[i]))
.unwrapOr(nullptr);
JSString* str = JS_AtomizeString(cx, instrumentationNames[i]);
if (!str) {
return nullptr;
}
return &str->asAtom();
}
}
MOZ_CRASH("Unexpected instrumentation kind");

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

@ -12,11 +12,6 @@
namespace js {
namespace frontend {
struct CompilationInfo;
class ParserAtom;
} // namespace frontend
// Logic related to instrumentation which can be performed in a realm.
#define FOR_EACH_INSTRUMENTATION_KIND(MACRO) \
@ -69,8 +64,8 @@ class RealmInstrumentation {
static uint32_t getInstrumentationKinds(GlobalObject* global);
// Get the string name of an instrumentation kind.
static const frontend::ParserAtom* getInstrumentationKindName(
frontend::CompilationInfo& compilationInfo, InstrumentationKind kind);
static JSAtom* getInstrumentationKindName(JSContext* cx,
InstrumentationKind kind);
static bool getScriptId(JSContext* cx, Handle<GlobalObject*> global,
HandleScript script, int32_t* id);

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

@ -222,7 +222,9 @@ struct JS_PUBLIC_API JSContext : public JS::RootingContext,
}
#ifdef DEBUG
bool isInitialized() const { return kind_ != js::ContextKind::Uninitialized; }
bool isInitialized() const {
return kind_ != js::ContextKind::Uninitialized;
}
#endif
bool isMainThreadContext() const {
@ -281,9 +283,13 @@ struct JS_PUBLIC_API JSContext : public JS::RootingContext,
// Accessors for immutable runtime data.
JSAtomState& names() { return *runtime_->commonNames; }
#ifdef JS_PARSER_ATOMS
js::frontend::WellKnownParserAtoms& parserNames() {
return *runtime_->commonParserNames;
}
#else
JSAtomState& parserNames() { return *runtime_->commonNames; }
#endif // JS_PARSER_ATOMS
js::StaticStrings& staticStrings() { return *runtime_->staticStrings; }
js::SharedImmutableStringsCache& sharedImmutableStrings() {
return runtime_->sharedImmutableStrings();

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

@ -13,7 +13,6 @@
#include "builtin/ModuleObject.h" // js::{{Im,Ex}portEntry,Requested{Module,}}Object
#include "frontend/CompilationInfo.h" // js::frontend::CompilationInfo
#include "frontend/EitherParser.h" // js::frontend::EitherParser
#include "frontend/ParserAtom.h" // js::frontend::ParserAtom
#include "frontend/Stencil.h" // js::frontend::StencilModuleEntry
#include "js/GCHashTable.h" // JS::GCHash{Map,Set}
#include "js/GCVector.h" // JS::GCVector
@ -48,7 +47,7 @@ class MOZ_STACK_CLASS ModuleBuilder {
bool processExport(frontend::ParseNode* exportNode);
bool processExportFrom(frontend::BinaryNode* exportNode);
bool hasExportedName(const frontend::ParserAtom* name) const;
bool hasExportedName(JSAtom* name) const;
bool buildTables(frontend::StencilModuleMetadata& metadata);
@ -59,10 +58,9 @@ class MOZ_STACK_CLASS ModuleBuilder {
private:
using RequestedModuleVector = JS::GCVector<frontend::StencilModuleEntry>;
using AtomSet = JS::GCHashSet<const frontend::ParserAtom*>;
using AtomSet = JS::GCHashSet<JSAtom*>;
using ExportEntryVector = GCVector<frontend::StencilModuleEntry>;
using ImportEntryMap =
JS::GCHashMap<const frontend::ParserAtom*, frontend::StencilModuleEntry>;
using ImportEntryMap = JS::GCHashMap<JSAtom*, frontend::StencilModuleEntry>;
using RootedExportEntryVector = JS::Rooted<ExportEntryVector>;
using RootedRequestedModuleVector = JS::Rooted<RequestedModuleVector>;
using RootedAtomSet = JS::Rooted<AtomSet>;
@ -81,23 +79,22 @@ class MOZ_STACK_CLASS ModuleBuilder {
// These are populated while emitting bytecode.
frontend::FunctionDeclarationVector functionDecls_;
frontend::StencilModuleEntry* importEntryFor(
const frontend::ParserAtom* localName) const;
frontend::StencilModuleEntry* importEntryFor(JSAtom* localName) const;
bool processExportBinding(frontend::ParseNode* pn);
bool processExportArrayBinding(frontend::ListNode* array);
bool processExportObjectBinding(frontend::ListNode* obj);
bool appendExportEntry(const frontend::ParserAtom* exportName,
const frontend::ParserAtom* localName,
bool appendExportEntry(JS::Handle<JSAtom*> exportName,
JS::Handle<JSAtom*> localName,
frontend::ParseNode* node = nullptr);
bool appendExportFromEntry(const frontend::ParserAtom* exportName,
const frontend::ParserAtom* moduleRequest,
const frontend::ParserAtom* importName,
bool appendExportFromEntry(JS::Handle<JSAtom*> exportName,
JS::Handle<JSAtom*> moduleRequest,
JS::Handle<JSAtom*> importName,
frontend::ParseNode* node);
bool maybeAppendRequestedModule(const frontend::ParserAtom* specifier,
bool maybeAppendRequestedModule(JS::Handle<JSAtom*> specifier,
frontend::ParseNode* node);
};

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

@ -14,7 +14,6 @@
#include <stdio.h>
#include "ds/LifoAlloc.h"
#include "frontend/ParserAtom.h"
#include "js/CharacterEncoding.h"
#include "util/Memory.h"
#include "util/Text.h"
@ -379,14 +378,6 @@ bool QuoteString(Sprinter* sp, JSString* str, char quote /*= '\0' */) {
sp, linear->twoByteRange(nogc), quote);
}
bool QuoteString(Sprinter* sp, const frontend::ParserAtom* atom,
char quote /*= '\0' */) {
return atom->hasLatin1Chars()
? QuoteString<QuoteTarget::String>(sp, atom->latin1Range(), quote)
: QuoteString<QuoteTarget::String>(sp, atom->twoByteRange(),
quote);
}
UniqueChars QuoteString(JSContext* cx, JSString* str, char quote /* = '\0' */) {
Sprinter sprinter(cx);
if (!sprinter.init()) {
@ -398,18 +389,6 @@ UniqueChars QuoteString(JSContext* cx, JSString* str, char quote /* = '\0' */) {
return sprinter.release();
}
UniqueChars QuoteString(JSContext* cx, const frontend::ParserAtom* atom,
char quote /* = '\0' */) {
Sprinter sprinter(cx);
if (!sprinter.init()) {
return nullptr;
}
if (!QuoteString(&sprinter, atom, quote)) {
return nullptr;
}
return sprinter.release();
}
bool JSONQuoteString(Sprinter* sp, JSString* str) {
JSLinearString* linear = str->ensureLinear(sp->context);
if (!linear) {

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

@ -20,12 +20,6 @@
namespace js {
namespace frontend {
class ParserAtom;
} // namespace frontend
class LifoAlloc;
// Generic printf interface, similar to an ostream in the standard library.
@ -206,20 +200,10 @@ extern const char js_EscapeMap[];
extern JS::UniqueChars QuoteString(JSContext* cx, JSString* str,
char quote = '\0');
// Same as above, except quote a parser atom.
extern JS::UniqueChars QuoteString(JSContext* cx,
const frontend::ParserAtom* ent,
char quote = '\0');
// Appends the quoted string to the given Sprinter. Follows the same semantics
// as QuoteString from above.
extern bool QuoteString(Sprinter* sp, JSString* str, char quote = '\0');
// Appends the quoted parser atom to the given Sprinter. Follows the same
// semantics as QuoteString from above.
bool QuoteString(Sprinter* sp, const frontend::ParserAtom* ent,
char quote = '\0');
// Appends the JSON quoted string to the given Sprinter.
extern bool JSONQuoteString(Sprinter* sp, JSString* str);

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

@ -16,7 +16,6 @@
#include "frontend/SharedContext.h"
#include "frontend/Stencil.h"
#include "gc/Allocator.h"
#include "gc/MaybeRooted.h"
#include "util/StringBuffer.h"
#include "vm/EnvironmentObject.h"
#include "vm/JSScript.h"
@ -147,60 +146,9 @@ Shape* js::CreateEnvironmentShape(JSContext* cx, BindingIter& bi,
return shape;
}
Shape* js::CreateEnvironmentShape(
JSContext* cx, AbstractBindingIter<const frontend::ParserAtom>& bi,
const JSClass* cls, uint32_t numSlots, uint32_t baseShapeFlags) {
RootedShape shape(cx,
EmptyEnvironmentShape(cx, cls, numSlots, baseShapeFlags));
if (!shape) {
return nullptr;
}
RootedAtom name(cx);
StackBaseShape stackBase(cls, baseShapeFlags);
for (; bi; bi++) {
BindingLocation loc = bi.location();
if (loc.kind() == BindingLocation::Kind::Environment) {
auto mbJSAtom = bi.name()->toJSAtom(cx);
if (mbJSAtom.isErr()) {
return nullptr;
}
name = mbJSAtom.unwrap();
MOZ_ASSERT(name);
cx->markAtom(name);
shape = NextEnvironmentShape(cx, name, bi.kind(), loc.slot(), stackBase,
shape);
if (!shape) {
return nullptr;
}
}
}
return shape;
}
template <class Data>
inline size_t SizeOfAllocatedData(Data* data) {
return SizeOfScopeData<Data>(data->length);
}
template <typename ConcreteScope, typename AtomT>
static UniquePtr<AbstractScopeData<ConcreteScope, AtomT>> CopyScopeDataImpl(
JSContext* cx, AbstractScopeData<ConcreteScope, AtomT>* data) {
using Data = AbstractScopeData<ConcreteScope, AtomT>;
size_t size = SizeOfAllocatedData(data);
void* bytes = cx->pod_malloc<char>(size);
if (!bytes) {
return nullptr;
}
auto* dataCopy = new (bytes) Data(*data);
std::uninitialized_copy_n(data->trailingNames.start(), data->length,
dataCopy->trailingNames.start());
return UniquePtr<Data>(dataCopy);
return SizeOfData<Data>(data->length);
}
template <typename ConcreteScope>
@ -215,13 +163,18 @@ static UniquePtr<typename ConcreteScope::Data> CopyScopeData(
cx->markAtom(name);
}
}
return CopyScopeDataImpl<ConcreteScope>(cx, data);
}
template <typename ConcreteScope>
static UniquePtr<ParserScopeData<ConcreteScope>> CopyScopeData(
JSContext* cx, ParserScopeData<ConcreteScope>* data) {
return CopyScopeDataImpl<ConcreteScope>(cx, data);
size_t size = SizeOfAllocatedData(data);
void* bytes = cx->pod_malloc<char>(size);
if (!bytes) {
return nullptr;
}
auto* dataCopy = new (bytes) typename ConcreteScope::Data(*data);
std::uninitialized_copy_n(names, length, dataCopy->trailingNames.start());
return UniquePtr<typename ConcreteScope::Data>(dataCopy);
}
static bool SetEnvironmentShape(JSContext* cx, BindingIter& freshBi,
@ -234,8 +187,8 @@ static bool SetEnvironmentShape(JSContext* cx, BindingIter& freshBi,
return envShape;
}
static bool SetEnvironmentShape(JSContext* cx, ParserBindingIter& freshBi,
ParserBindingIter& bi, const JSClass* cls,
static bool SetEnvironmentShape(JSContext* cx, BindingIter& freshBi,
BindingIter& bi, const JSClass* cls,
uint32_t firstFrameSlot,
uint32_t baseShapeFlags,
mozilla::Maybe<uint32_t>* envShape) {
@ -243,17 +196,16 @@ static bool SetEnvironmentShape(JSContext* cx, ParserBindingIter& freshBi,
return true;
}
template <typename ConcreteScope, typename AtomT, typename EnvironmentT,
typename ShapeT>
template <typename ConcreteScope, typename EnvironmentType, typename ShapeType>
static bool PrepareScopeData(
JSContext* cx, AbstractBindingIter<AtomT>& bi,
typename MaybeRootedScopeData<ConcreteScope, AtomT>::HandleType data,
uint32_t firstFrameSlot, ShapeT envShape) {
const JSClass* cls = &EnvironmentT::class_;
uint32_t baseShapeFlags = EnvironmentT::BASESHAPE_FLAGS;
JSContext* cx, BindingIter& bi,
Handle<UniquePtr<typename ConcreteScope::Data>> data,
uint32_t firstFrameSlot, ShapeType envShape) {
const JSClass* cls = &EnvironmentType::class_;
uint32_t baseShapeFlags = EnvironmentType::BASESHAPE_FLAGS;
// Copy a fresh BindingIter for use below.
AbstractBindingIter<AtomT> freshBi(bi);
BindingIter freshBi(bi);
// Iterate through all bindings. This counts the number of environment
// slots needed and computes the maximum frame slot.
@ -263,9 +215,6 @@ static bool PrepareScopeData(
data->nextFrameSlot =
bi.canHaveFrameSlots() ? bi.nextFrameSlot() : LOCALNO_LIMIT;
// Data is not used after this point. Before this point, gc cannot
// occur, so `data` is fine as a raw pointer.
// Make a new environment shape if any environment slots were used.
if (bi.nextEnvironmentSlot() != JSSLOT_FREE(cls)) {
if (!SetEnvironmentShape(cx, freshBi, bi, cls, firstFrameSlot,
@ -277,63 +226,16 @@ static bool PrepareScopeData(
return true;
}
template <typename ConcreteScope, typename AtomT>
static UniquePtr<AbstractScopeData<ConcreteScope, AtomT>> NewEmptyScopeData(
JSContext* cx, uint32_t length = 0) {
using Data = AbstractScopeData<ConcreteScope, AtomT>;
size_t dataSize = SizeOfScopeData<Data>(length);
uint8_t* bytes = cx->pod_malloc<uint8_t>(dataSize);
auto data = reinterpret_cast<Data*>(bytes);
if (data) {
new (data) Data(length);
}
return UniquePtr<Data>(data);
}
template <typename ConcreteScope>
static UniquePtr<typename ConcreteScope::Data> LiftParserScopeData(
JSContext* cx, ParserScopeData<ConcreteScope>* data) {
using ConcreteData = typename ConcreteScope::Data;
// Convert all scope ParserAtoms to rooted JSAtoms.
// Rooting is necessary as conversion can gc.
JS::RootedVector<JSAtom*> jsatoms(cx);
if (!jsatoms.reserve(data->length)) {
return nullptr;
static UniquePtr<typename ConcreteScope::Data> NewEmptyScopeData(
JSContext* cx, uint32_t length = 0) {
size_t dataSize = SizeOfData<typename ConcreteScope::Data>(length);
uint8_t* bytes = cx->pod_malloc<uint8_t>(dataSize);
auto data = reinterpret_cast<typename ConcreteScope::Data*>(bytes);
if (data) {
new (data) typename ConcreteScope::Data(length);
}
auto* names = data->trailingNames.start();
uint32_t length = data->length;
for (size_t i = 0; i < length; i++) {
JSAtom* jsatom = nullptr;
if (names[i].name()) {
jsatom = names[i].name()->toJSAtom(cx).unwrapOr(nullptr);
if (jsatom == nullptr) {
return nullptr;
}
}
jsatoms.infallibleAppend(jsatom);
}
// Allocate a new scope-data of the right kind.
UniquePtr<ConcreteData> scopeData(
NewEmptyScopeData<ConcreteScope, JSAtom>(cx, data->length));
if (!scopeData) {
return nullptr;
}
// Memcopy the head of the structure directly, no translation needed.
static_assert(sizeof(ConcreteData) == sizeof(ParserScopeData<ConcreteScope>),
"Parser and VM scope-data structures should be same size.");
memcpy(scopeData.get(), data, offsetof(ConcreteData, trailingNames));
// Initialize new scoped names.
auto* namesOut = scopeData->trailingNames.start();
for (size_t i = 0; i < length; i++) {
namesOut[i] = names[i].transformName(jsatoms[i].get());
}
return scopeData;
return UniquePtr<typename ConcreteScope::Data>(data);
}
static constexpr size_t HasAtomMask = 1;
@ -404,7 +306,7 @@ XDRResult Scope::XDRSizedBindingNames(
if (mode == XDR_ENCODE) {
data.set(&scope->data());
} else {
data.set(NewEmptyScopeData<ConcreteScope, JSAtom>(cx, length).release());
data.set(NewEmptyScopeData<ConcreteScope>(cx, length).release());
if (!data) {
return xdr->fail(JS::TranscodeResult_Throw);
}
@ -468,11 +370,11 @@ inline void Scope::initData(
setHeaderPtr(data.get().release());
}
template <typename EnvironmentT>
template <typename EnvironmentType>
bool Scope::updateEnvShapeIfRequired(JSContext* cx, MutableHandleShape envShape,
bool needsEnvironment) {
if (!envShape && needsEnvironment) {
envShape.set(EmptyEnvironmentShape<EnvironmentT>(cx));
envShape.set(EmptyEnvironmentShape<EnvironmentType>(cx));
if (!envShape) {
return false;
}
@ -480,7 +382,7 @@ bool Scope::updateEnvShapeIfRequired(JSContext* cx, MutableHandleShape envShape,
return true;
}
template <typename EnvironmentT>
template <typename EnvironmentType>
bool Scope::updateEnvShapeIfRequired(JSContext* cx,
mozilla::Maybe<uint32_t>* envShape,
bool needsEnvironment) {
@ -779,18 +681,18 @@ uint32_t LexicalScope::nextFrameSlot(const AbstractScopePtr& scope) {
MOZ_CRASH("Not an enclosing intra-frame Scope");
}
template <typename AtomT, typename ShapeT>
bool LexicalScope::prepareForScopeCreation(
JSContext* cx, ScopeKind kind, uint32_t firstFrameSlot,
typename MaybeRootedScopeData<LexicalScope, AtomT>::MutableHandleType data,
ShapeT envShape) {
template <typename ShapeType>
bool LexicalScope::prepareForScopeCreation(JSContext* cx, ScopeKind kind,
uint32_t firstFrameSlot,
MutableHandle<UniquePtr<Data>> data,
ShapeType envShape) {
bool isNamedLambda =
kind == ScopeKind::NamedLambda || kind == ScopeKind::StrictNamedLambda;
MOZ_ASSERT_IF(isNamedLambda, firstFrameSlot == LOCALNO_LIMIT);
AbstractBindingIter<AtomT> bi(*data, firstFrameSlot, isNamedLambda);
if (!PrepareScopeData<LexicalScope, AtomT, LexicalEnvironmentObject>(
BindingIter bi(*data, firstFrameSlot, isNamedLambda);
if (!PrepareScopeData<LexicalScope, LexicalEnvironmentObject>(
cx, bi, data, firstFrameSlot, envShape)) {
return false;
}
@ -804,8 +706,7 @@ LexicalScope* LexicalScope::createWithData(JSContext* cx, ScopeKind kind,
HandleScope enclosing) {
RootedShape envShape(cx);
if (!prepareForScopeCreation<JSAtom>(cx, kind, firstFrameSlot, data,
&envShape)) {
if (!prepareForScopeCreation(cx, kind, firstFrameSlot, data, &envShape)) {
return nullptr;
}
@ -880,16 +781,14 @@ template
LexicalScope::XDR(XDRState<XDR_DECODE>* xdr, ScopeKind kind,
HandleScope enclosing, MutableHandleScope scope);
template <typename AtomT, typename ShapeT>
template <typename ShapeType>
bool FunctionScope::prepareForScopeCreation(
JSContext* cx,
typename MaybeRootedScopeData<FunctionScope, AtomT>::MutableHandleType data,
bool hasParameterExprs, bool needsEnvironment, HandleFunction fun,
ShapeT envShape) {
JSContext* cx, MutableHandle<UniquePtr<Data>> data, bool hasParameterExprs,
bool needsEnvironment, HandleFunction fun, ShapeType envShape) {
uint32_t firstFrameSlot = 0;
AbstractBindingIter<AtomT> bi(*data, hasParameterExprs);
if (!PrepareScopeData<FunctionScope, AtomT, CallObject>(
cx, bi, data, firstFrameSlot, envShape)) {
BindingIter bi(*data, hasParameterExprs);
if (!PrepareScopeData<FunctionScope, CallObject>(cx, bi, data, firstFrameSlot,
envShape)) {
return false;
}
@ -917,8 +816,8 @@ FunctionScope* FunctionScope::createWithData(
// GCPtr. Destruction of |data| below may trigger calls into the GC.
RootedShape envShape(cx);
if (!prepareForScopeCreation<JSAtom>(cx, data, hasParameterExprs,
needsEnvironment, fun, &envShape)) {
if (!prepareForScopeCreation(cx, data, hasParameterExprs, needsEnvironment,
fun, &envShape)) {
return nullptr;
}
@ -936,13 +835,6 @@ bool FunctionScope::isSpecialName(JSContext* cx, JSAtom* name) {
name == cx->names().dotGenerator;
}
/* static */
bool FunctionScope::isSpecialName(JSContext* cx, const ParserAtom* name) {
return name == cx->parserNames().arguments ||
name == cx->parserNames().dotThis ||
name == cx->parserNames().dotGenerator;
}
/* static */
FunctionScope* FunctionScope::clone(JSContext* cx, Handle<FunctionScope*> scope,
HandleFunction fun, HandleScope enclosing) {
@ -1035,13 +927,24 @@ template
FunctionScope::XDR(XDRState<XDR_DECODE>* xdr, HandleFunction fun,
HandleScope enclosing, MutableHandleScope scope);
template <typename AtomT, typename ShapeT>
bool VarScope::prepareForScopeCreation(
JSContext* cx, ScopeKind kind,
typename MaybeRootedScopeData<VarScope, AtomT>::MutableHandleType data,
uint32_t firstFrameSlot, bool needsEnvironment, ShapeT envShape) {
AbstractBindingIter<AtomT> bi(*data, firstFrameSlot);
if (!PrepareScopeData<VarScope, AtomT, VarEnvironmentObject>(
static UniquePtr<VarScope::Data> NewEmptyVarScopeData(JSContext* cx,
uint32_t firstFrameSlot) {
UniquePtr<VarScope::Data> data(NewEmptyScopeData<VarScope>(cx));
if (data) {
data->nextFrameSlot = firstFrameSlot;
}
return data;
}
template <typename ShapeType>
bool VarScope::prepareForScopeCreation(JSContext* cx, ScopeKind kind,
MutableHandle<UniquePtr<Data>> data,
uint32_t firstFrameSlot,
bool needsEnvironment,
ShapeType envShape) {
BindingIter bi(*data, firstFrameSlot);
if (!PrepareScopeData<VarScope, VarEnvironmentObject>(
cx, bi, data, firstFrameSlot, envShape)) {
return false;
}
@ -1063,8 +966,8 @@ VarScope* VarScope::createWithData(JSContext* cx, ScopeKind kind,
MOZ_ASSERT(data);
RootedShape envShape(cx);
if (!prepareForScopeCreation<JSAtom>(cx, kind, data, firstFrameSlot,
needsEnvironment, &envShape)) {
if (!prepareForScopeCreation(cx, kind, data, firstFrameSlot, needsEnvironment,
&envShape)) {
return nullptr;
}
@ -1133,9 +1036,9 @@ GlobalScope* GlobalScope::create(JSContext* cx, ScopeKind kind,
Handle<Data*> dataArg) {
// The data that's passed in is from the frontend and is LifoAlloc'd.
// Copy it now that we're creating a permanent VM scope.
Rooted<UniquePtr<Data>> data(
cx, dataArg ? CopyScopeData<GlobalScope>(cx, dataArg)
: NewEmptyScopeData<GlobalScope, JSAtom>(cx));
Rooted<UniquePtr<Data>> data(cx, dataArg
? CopyScopeData<GlobalScope>(cx, dataArg)
: NewEmptyScopeData<GlobalScope>(cx));
if (!data) {
return nullptr;
}
@ -1248,15 +1151,14 @@ template
WithScope::XDR(XDRState<XDR_DECODE>* xdr, HandleScope enclosing,
MutableHandleScope scope);
template <typename AtomT, typename ShapeT>
bool EvalScope::prepareForScopeCreation(
JSContext* cx, ScopeKind scopeKind,
typename MaybeRootedScopeData<EvalScope, AtomT>::MutableHandleType data,
ShapeT envShape) {
template <typename ShapeType>
bool EvalScope::prepareForScopeCreation(JSContext* cx, ScopeKind scopeKind,
MutableHandle<UniquePtr<Data>> data,
ShapeType envShape) {
if (scopeKind == ScopeKind::StrictEval) {
uint32_t firstFrameSlot = 0;
AbstractBindingIter<AtomT> bi(*data, true);
if (!PrepareScopeData<EvalScope, AtomT, VarEnvironmentObject>(
BindingIter bi(*data, true);
if (!PrepareScopeData<EvalScope, VarEnvironmentObject>(
cx, bi, data, firstFrameSlot, envShape)) {
return false;
}
@ -1277,7 +1179,7 @@ EvalScope* EvalScope::createWithData(JSContext* cx, ScopeKind scopeKind,
MOZ_ASSERT(data);
RootedShape envShape(cx);
if (!prepareForScopeCreation<JSAtom>(cx, scopeKind, data, &envShape)) {
if (!prepareForScopeCreation(cx, scopeKind, data, &envShape)) {
return nullptr;
}
@ -1347,14 +1249,14 @@ Zone* ModuleScope::AbstractData<BindingName>::zone() const {
}
/* static */
template <typename AtomT, typename ShapeT>
bool ModuleScope::prepareForScopeCreation(
JSContext* cx,
typename MaybeRootedScopeData<ModuleScope, AtomT>::MutableHandleType data,
HandleModuleObject module, ShapeT envShape) {
template <typename ShapeType>
bool ModuleScope::prepareForScopeCreation(JSContext* cx,
MutableHandle<UniquePtr<Data>> data,
HandleModuleObject module,
ShapeType envShape) {
uint32_t firstFrameSlot = 0;
AbstractBindingIter<AtomT> bi(*data);
if (!PrepareScopeData<ModuleScope, AtomT, ModuleEnvironmentObject>(
BindingIter bi(*data);
if (!PrepareScopeData<ModuleScope, ModuleEnvironmentObject>(
cx, bi, data, firstFrameSlot, envShape)) {
return false;
}
@ -1377,7 +1279,7 @@ ModuleScope* ModuleScope::createWithData(JSContext* cx,
MOZ_ASSERT(enclosing->is<GlobalScope>());
RootedShape envShape(cx);
if (!prepareForScopeCreation<JSAtom>(cx, data, module, &envShape)) {
if (!prepareForScopeCreation(cx, data, module, &envShape)) {
return nullptr;
}
@ -1487,7 +1389,7 @@ WasmInstanceScope* WasmInstanceScope::create(JSContext* cx,
namesCount += globalsCount;
Rooted<UniquePtr<Data>> data(
cx, NewEmptyScopeData<WasmInstanceScope, JSAtom>(cx, namesCount));
cx, NewEmptyScopeData<WasmInstanceScope>(cx, namesCount));
if (!data) {
return nullptr;
}
@ -1543,7 +1445,7 @@ WasmFunctionScope* WasmFunctionScope::create(JSContext* cx,
uint32_t namesCount = locals.length();
Rooted<UniquePtr<Data>> data(
cx, NewEmptyScopeData<WasmFunctionScope, JSAtom>(cx, namesCount));
cx, NewEmptyScopeData<WasmFunctionScope>(cx, namesCount));
if (!data) {
return nullptr;
}
@ -1570,10 +1472,9 @@ bool ScopeIter::hasSyntacticEnvironment() const {
scope()->kind() != ScopeKind::NonSyntactic;
}
AbstractBindingIter<JSAtom>::AbstractBindingIter(ScopeKind kind,
BaseScopeData* data,
BindingIter::BindingIter(ScopeKind kind, BaseScopeData* data,
uint32_t firstFrameSlot)
: BaseAbstractBindingIter<JSAtom>() {
: Base() {
switch (kind) {
case ScopeKind::Lexical:
case ScopeKind::SimpleCatch:
@ -1623,17 +1524,14 @@ AbstractBindingIter<JSAtom>::AbstractBindingIter(ScopeKind kind,
}
}
AbstractBindingIter<JSAtom>::AbstractBindingIter(Scope* scope)
: AbstractBindingIter<JSAtom>(scope->kind(), scope->rawData(),
scope->firstFrameSlot()) {}
BindingIter::BindingIter(Scope* scope)
: BindingIter(scope->kind(), scope->rawData(), scope->firstFrameSlot()) {}
AbstractBindingIter<JSAtom>::AbstractBindingIter(JSScript* script)
: AbstractBindingIter<JSAtom>(script->bodyScope()) {}
BindingIter::BindingIter(JSScript* script) : BindingIter(script->bodyScope()) {}
template <typename NameT>
void BaseAbstractBindingIter<NameT>::init(
LexicalScope::AbstractData<NameT>& data, uint32_t firstFrameSlot,
uint8_t flags) {
void AbstractBindingIter<NameT>::init(LexicalScope::AbstractData<NameT>& data,
uint32_t firstFrameSlot, uint8_t flags) {
// Named lambda scopes can only have environment slots. If the callee
// isn't closed over, it is accessed via JSOp::Callee.
if (flags & IsNamedLambda) {
@ -1656,14 +1554,12 @@ void BaseAbstractBindingIter<NameT>::init(
}
}
template void BaseAbstractBindingIter<JSAtom>::init(
template void AbstractBindingIter<JSAtom>::init(
LexicalScope::AbstractData<JSAtom>&, uint32_t, uint8_t);
template void BaseAbstractBindingIter<const ParserAtom>::init(
LexicalScope::AbstractData<const ParserAtom>&, uint32_t, uint8_t);
template <typename NameT>
void BaseAbstractBindingIter<NameT>::init(
FunctionScope::AbstractData<NameT>& data, uint8_t flags) {
void AbstractBindingIter<NameT>::init(FunctionScope::AbstractData<NameT>& data,
uint8_t flags) {
flags = CanHaveFrameSlots | CanHaveEnvironmentSlots | flags;
if (!(flags & HasFormalParameterExprs)) {
flags |= CanHaveArgumentSlots;
@ -1679,13 +1575,11 @@ void BaseAbstractBindingIter<NameT>::init(
data.length, flags, 0, JSSLOT_FREE(&CallObject::class_),
data.trailingNames.start(), data.length);
}
template void BaseAbstractBindingIter<JSAtom>::init(
template void AbstractBindingIter<JSAtom>::init(
FunctionScope::AbstractData<JSAtom>&, uint8_t);
template void BaseAbstractBindingIter<const ParserAtom>::init(
FunctionScope::AbstractData<const ParserAtom>&, uint8_t);
template <typename NameT>
void BaseAbstractBindingIter<NameT>::init(VarScope::AbstractData<NameT>& data,
void AbstractBindingIter<NameT>::init(VarScope::AbstractData<NameT>& data,
uint32_t firstFrameSlot) {
// imports - [0, 0)
// positional formals - [0, 0)
@ -1698,14 +1592,11 @@ void BaseAbstractBindingIter<NameT>::init(VarScope::AbstractData<NameT>& data,
JSSLOT_FREE(&VarEnvironmentObject::class_), data.trailingNames.start(),
data.length);
}
template void BaseAbstractBindingIter<JSAtom>::init(
VarScope::AbstractData<JSAtom>&, uint32_t);
template void BaseAbstractBindingIter<const ParserAtom>::init(
VarScope::AbstractData<const ParserAtom>&, uint32_t);
template void AbstractBindingIter<JSAtom>::init(VarScope::AbstractData<JSAtom>&,
uint32_t);
template <typename NameT>
void BaseAbstractBindingIter<NameT>::init(
GlobalScope::AbstractData<NameT>& data) {
void AbstractBindingIter<NameT>::init(GlobalScope::AbstractData<NameT>& data) {
// imports - [0, 0)
// positional formals - [0, 0)
// other formals - [0, 0)
@ -1715,13 +1606,11 @@ void BaseAbstractBindingIter<NameT>::init(
init(0, 0, 0, data.letStart, data.constStart, CannotHaveSlots, UINT32_MAX,
UINT32_MAX, data.trailingNames.start(), data.length);
}
template void BaseAbstractBindingIter<JSAtom>::init(
template void AbstractBindingIter<JSAtom>::init(
GlobalScope::AbstractData<JSAtom>&);
template void BaseAbstractBindingIter<const ParserAtom>::init(
GlobalScope::AbstractData<const ParserAtom>&);
template <typename NameT>
void BaseAbstractBindingIter<NameT>::init(EvalScope::AbstractData<NameT>& data,
void AbstractBindingIter<NameT>::init(EvalScope::AbstractData<NameT>& data,
bool strict) {
uint32_t flags;
uint32_t firstFrameSlot;
@ -1745,14 +1634,11 @@ void BaseAbstractBindingIter<NameT>::init(EvalScope::AbstractData<NameT>& data,
init(0, 0, 0, data.length, data.length, flags, firstFrameSlot,
firstEnvironmentSlot, data.trailingNames.start(), data.length);
}
template void BaseAbstractBindingIter<JSAtom>::init(
template void AbstractBindingIter<JSAtom>::init(
EvalScope::AbstractData<JSAtom>&, bool);
template void BaseAbstractBindingIter<const ParserAtom>::init(
EvalScope::AbstractData<const ParserAtom>&, bool);
template <typename NameT>
void BaseAbstractBindingIter<NameT>::init(
ModuleScope::AbstractData<NameT>& data) {
void AbstractBindingIter<NameT>::init(ModuleScope::AbstractData<NameT>& data) {
// imports - [0, data.varStart)
// positional formals - [data.varStart, data.varStart)
// other formals - [data.varStart, data.varStart)
@ -1764,13 +1650,11 @@ void BaseAbstractBindingIter<NameT>::init(
JSSLOT_FREE(&ModuleEnvironmentObject::class_),
data.trailingNames.start(), data.length);
}
template void BaseAbstractBindingIter<JSAtom>::init(
template void AbstractBindingIter<JSAtom>::init(
ModuleScope::AbstractData<JSAtom>&);
template void BaseAbstractBindingIter<const ParserAtom>::init(
ModuleScope::AbstractData<const ParserAtom>&);
template <typename NameT>
void BaseAbstractBindingIter<NameT>::init(
void AbstractBindingIter<NameT>::init(
WasmInstanceScope::AbstractData<NameT>& data) {
// imports - [0, 0)
// positional formals - [0, 0)
@ -1782,13 +1666,11 @@ void BaseAbstractBindingIter<NameT>::init(
CanHaveFrameSlots | CanHaveEnvironmentSlots, UINT32_MAX, UINT32_MAX,
data.trailingNames.start(), data.length);
}
template void BaseAbstractBindingIter<JSAtom>::init(
template void AbstractBindingIter<JSAtom>::init(
WasmInstanceScope::AbstractData<JSAtom>&);
template void BaseAbstractBindingIter<const ParserAtom>::init(
WasmInstanceScope::AbstractData<const ParserAtom>&);
template <typename NameT>
void BaseAbstractBindingIter<NameT>::init(
void AbstractBindingIter<NameT>::init(
WasmFunctionScope::AbstractData<NameT>& data) {
// imports - [0, 0)
// positional formals - [0, 0)
@ -1800,10 +1682,8 @@ void BaseAbstractBindingIter<NameT>::init(
CanHaveFrameSlots | CanHaveEnvironmentSlots, UINT32_MAX, UINT32_MAX,
data.trailingNames.start(), data.length);
}
template void BaseAbstractBindingIter<JSAtom>::init(
template void AbstractBindingIter<JSAtom>::init(
WasmFunctionScope::AbstractData<JSAtom>&);
template void BaseAbstractBindingIter<const ParserAtom>::init(
WasmFunctionScope::AbstractData<const ParserAtom>&);
PositionalFormalParameterIter::PositionalFormalParameterIter(Scope* scope)
: BindingIter(scope) {
@ -1914,17 +1794,17 @@ JS::ubi::Node::Size JS::ubi::Concrete<Scope>::size(
/* static */
bool ScopeStencil::createForFunctionScope(
JSContext* cx, frontend::CompilationInfo& compilationInfo,
ParserFunctionScopeData* data, bool hasParameterExprs,
Handle<FunctionScope::Data*> dataArg, bool hasParameterExprs,
bool needsEnvironment, FunctionIndex functionIndex, bool isArrow,
mozilla::Maybe<ScopeIndex> enclosing, ScopeIndex* index) {
// If incoming data is null, initialize an epty scope data.
if (!data) {
data = NewEmptyScopeData<FunctionScope, const frontend::ParserAtom>(cx)
.release();
// The data that's passed in is from the frontend and is LifoAlloc'd.
// Copy it now that we're creating a permanent VM scope.
Rooted<UniquePtr<FunctionScope::Data>> data(
cx, dataArg ? CopyScopeData<FunctionScope>(cx, dataArg)
: NewEmptyScopeData<FunctionScope>(cx));
if (!data) {
return false;
}
}
// We do not initialize the canonical function while the data is owned by the
// ScopeStencil. It gets set in ScopeStencil::releaseData.
@ -1932,78 +1812,78 @@ bool ScopeStencil::createForFunctionScope(
uint32_t firstFrameSlot = 0;
mozilla::Maybe<uint32_t> envShape;
if (!FunctionScope::prepareForScopeCreation<const ParserAtom>(
if (!FunctionScope::prepareForScopeCreation(
cx, &data, hasParameterExprs, needsEnvironment, fun, &envShape)) {
return false;
}
*index = compilationInfo.scopeData.length();
return compilationInfo.scopeData.emplaceBack(
ScopeKind::Function, enclosing, firstFrameSlot, envShape, data,
mozilla::Some(functionIndex), isArrow);
ScopeKind::Function, enclosing, firstFrameSlot, envShape,
std::move(data.get()), mozilla::Some(functionIndex), isArrow);
}
/* static */
bool ScopeStencil::createForLexicalScope(
JSContext* cx, frontend::CompilationInfo& compilationInfo, ScopeKind kind,
ParserLexicalScopeData* data, uint32_t firstFrameSlot,
Handle<LexicalScope::Data*> dataArg, uint32_t firstFrameSlot,
mozilla::Maybe<ScopeIndex> enclosing, ScopeIndex* index) {
// If incoming data is null, initialize an epty scope data.
if (!data) {
data = NewEmptyScopeData<LexicalScope, const frontend::ParserAtom>(cx)
.release();
// The data that's passed in is from the frontend and is LifoAlloc'd.
// Copy it now that we're creating a permanent VM scope.
Rooted<UniquePtr<LexicalScope::Data>> data(
cx, CopyScopeData<LexicalScope>(cx, dataArg));
if (!data) {
return false;
}
}
mozilla::Maybe<uint32_t> envShape;
if (!LexicalScope::prepareForScopeCreation<const ParserAtom>(
cx, kind, firstFrameSlot, &data, &envShape)) {
if (!LexicalScope::prepareForScopeCreation(cx, kind, firstFrameSlot, &data,
&envShape)) {
return false;
}
*index = compilationInfo.scopeData.length();
return compilationInfo.scopeData.emplaceBack(kind, enclosing, firstFrameSlot,
envShape, data);
envShape, std::move(data.get()));
}
bool ScopeStencil::createForVarScope(
JSContext* cx, frontend::CompilationInfo& compilationInfo, ScopeKind kind,
ParserVarScopeData* data, uint32_t firstFrameSlot, bool needsEnvironment,
mozilla::Maybe<ScopeIndex> enclosing, ScopeIndex* index) {
// If incoming data is null, initialize an epty scope data.
if (!data) {
data =
NewEmptyScopeData<VarScope, const frontend::ParserAtom>(cx).release();
Handle<VarScope::Data*> dataArg, uint32_t firstFrameSlot,
bool needsEnvironment, mozilla::Maybe<ScopeIndex> enclosing,
ScopeIndex* index) {
// The data that's passed in is from the frontend and is LifoAlloc'd.
// Copy it now that we're creating a permanent VM scope.
Rooted<UniquePtr<VarScope::Data>> data(
cx, dataArg ? CopyScopeData<VarScope>(cx, dataArg)
: NewEmptyVarScopeData(cx, firstFrameSlot));
if (!data) {
return false;
}
}
mozilla::Maybe<uint32_t> envShape;
if (!VarScope::prepareForScopeCreation<const ParserAtom>(
cx, kind, &data, firstFrameSlot, needsEnvironment, &envShape)) {
if (!VarScope::prepareForScopeCreation(cx, kind, &data, firstFrameSlot,
needsEnvironment, &envShape)) {
return false;
}
*index = compilationInfo.scopeData.length();
return compilationInfo.scopeData.emplaceBack(kind, enclosing, firstFrameSlot,
envShape, data);
envShape, std::move(data.get()));
}
/* static */
bool ScopeStencil::createForGlobalScope(
JSContext* cx, frontend::CompilationInfo& compilationInfo, ScopeKind kind,
ParserGlobalScopeData* data, ScopeIndex* index) {
// If incoming data is null, initialize an epty scope data.
if (!data) {
data = NewEmptyScopeData<GlobalScope, const frontend::ParserAtom>(cx)
.release();
Handle<GlobalScope::Data*> dataArg, ScopeIndex* index) {
// The data that's passed in is from the frontend and is LifoAlloc'd.
// Copy it now that we're creating a permanent VM scope.
Rooted<UniquePtr<GlobalScope::Data>> data(
cx, dataArg ? CopyScopeData<GlobalScope>(cx, dataArg)
: NewEmptyScopeData<GlobalScope>(cx));
if (!data) {
return false;
}
}
// The global scope has no environment shape. Its environment is the
// global lexical scope and the global object or non-syntactic objects
@ -2016,48 +1896,47 @@ bool ScopeStencil::createForGlobalScope(
*index = compilationInfo.scopeData.length();
return compilationInfo.scopeData.emplaceBack(kind, enclosing, firstFrameSlot,
envShape, data);
envShape, std::move(data.get()));
}
/* static */
bool ScopeStencil::createForEvalScope(
JSContext* cx, frontend::CompilationInfo& compilationInfo, ScopeKind kind,
ParserEvalScopeData* data, mozilla::Maybe<ScopeIndex> enclosing,
Handle<EvalScope::Data*> dataArg, mozilla::Maybe<ScopeIndex> enclosing,
ScopeIndex* index) {
// If incoming data is null, initialize an epty scope data.
if (!data) {
data =
NewEmptyScopeData<EvalScope, const frontend::ParserAtom>(cx).release();
// The data that's passed in is from the frontend and is LifoAlloc'd.
// Copy it now that we're creating a permanent VM scope.
Rooted<UniquePtr<EvalScope::Data>> data(
cx, dataArg ? CopyScopeData<EvalScope>(cx, dataArg)
: NewEmptyScopeData<EvalScope>(cx));
if (!data) {
return false;
}
}
uint32_t firstFrameSlot = 0;
mozilla::Maybe<uint32_t> envShape;
if (!EvalScope::prepareForScopeCreation<const ParserAtom>(cx, kind, &data,
&envShape)) {
if (!EvalScope::prepareForScopeCreation(cx, kind, &data, &envShape)) {
return false;
}
*index = compilationInfo.scopeData.length();
return compilationInfo.scopeData.emplaceBack(kind, enclosing, firstFrameSlot,
envShape, data);
envShape, std::move(data.get()));
}
/* static */
bool ScopeStencil::createForModuleScope(
JSContext* cx, frontend::CompilationInfo& compilationInfo,
ParserModuleScopeData* data, mozilla::Maybe<ScopeIndex> enclosing,
Handle<ModuleScope::Data*> dataArg, mozilla::Maybe<ScopeIndex> enclosing,
ScopeIndex* index) {
// If incoming data is null, initialize an epty scope data.
if (!data) {
data = NewEmptyScopeData<ModuleScope, const frontend::ParserAtom>(cx)
.release();
// The data that's passed in is from the frontend and is LifoAlloc'd.
// Copy it now that we're creating a permanent VM scope.
Rooted<UniquePtr<ModuleScope::Data>> data(
cx, dataArg ? CopyScopeData<ModuleScope>(cx, dataArg)
: NewEmptyScopeData<ModuleScope>(cx));
if (!data) {
return false;
}
}
MOZ_ASSERT(enclosing.isNothing());
@ -2069,22 +1948,22 @@ bool ScopeStencil::createForModuleScope(
// Copy it now that we're creating a permanent VM scope.
uint32_t firstFrameSlot = 0;
mozilla::Maybe<uint32_t> envShape;
if (!ModuleScope::prepareForScopeCreation<const ParserAtom>(cx, &data, module,
&envShape)) {
if (!ModuleScope::prepareForScopeCreation(cx, &data, module, &envShape)) {
return false;
}
*index = compilationInfo.scopeData.length();
return compilationInfo.scopeData.emplaceBack(ScopeKind::Module, enclosing,
firstFrameSlot, envShape, data);
firstFrameSlot, envShape,
std::move(data.get()));
}
template <typename SpecificEnvironmentT>
template <typename SpecificEnvironmentType>
bool ScopeStencil::createSpecificShape(JSContext* cx, ScopeKind kind,
BaseScopeData* scopeData,
MutableHandleShape shape) {
const JSClass* cls = &SpecificEnvironmentT::class_;
uint32_t baseShapeFlags = SpecificEnvironmentT::BASESHAPE_FLAGS;
const JSClass* cls = &SpecificEnvironmentType::class_;
uint32_t baseShapeFlags = SpecificEnvironmentType::BASESHAPE_FLAGS;
if (numEnvironmentSlots_.isSome()) {
if (*numEnvironmentSlots_ > 0) {
@ -2113,43 +1992,32 @@ bool ScopeStencil::createForWithScope(
firstFrameSlot, envShape);
}
template <typename SpecificScopeT>
UniquePtr<typename SpecificScopeT::Data> ScopeStencil::createSpecificScopeData(
JSContext* cx, CompilationInfo& compilationInfo) {
return LiftParserScopeData<SpecificScopeT>(cx, &data<SpecificScopeT>());
template <typename SpecificScopeType>
UniquePtr<typename SpecificScopeType::Data> ScopeStencil::releaseData(
CompilationInfo& compilationInfo) {
return UniquePtr<typename SpecificScopeType::Data>(
static_cast<typename SpecificScopeType::Data*>(data_.release()));
}
template <>
UniquePtr<FunctionScope::Data>
ScopeStencil::createSpecificScopeData<FunctionScope>(
JSContext* cx, CompilationInfo& compilationInfo) {
// Allocate a new vm function-scope.
UniquePtr<FunctionScope::Data> data =
LiftParserScopeData<FunctionScope>(cx, &this->data<FunctionScope>());
if (!data) {
return nullptr;
}
UniquePtr<FunctionScope::Data> ScopeStencil::releaseData<FunctionScope>(
CompilationInfo& compilationInfo) {
// Initialize the GCPtrs in the Scope::Data.
data<FunctionScope>().canonicalFunction =
compilationInfo.functions[*functionIndex_];
// Initialize the GCPtrs in the FunctionScope::Data.
data->canonicalFunction = compilationInfo.functions[*functionIndex_];
return data;
return UniquePtr<FunctionScope::Data>(
static_cast<FunctionScope::Data*>(data_.release()));
}
template <>
UniquePtr<ModuleScope::Data> ScopeStencil::createSpecificScopeData<ModuleScope>(
JSContext* cx, CompilationInfo& compilationInfo) {
// Allocate a new vm module-scope.
UniquePtr<ModuleScope::Data> data =
LiftParserScopeData<ModuleScope>(cx, &this->data<ModuleScope>());
if (!data) {
return nullptr;
}
UniquePtr<ModuleScope::Data> ScopeStencil::releaseData<ModuleScope>(
CompilationInfo& compilationInfo) {
// Initialize the GCPtrs in the Scope::Data.
data<ModuleScope>().module = compilationInfo.module;
// Initialize the GCPtrs in the ModuleScope::Data.
data->module = compilationInfo.module;
return data;
return UniquePtr<ModuleScope::Data>(
static_cast<ModuleScope::Data*>(data_.release()));
}
// WithScope does not use binding data.
@ -2165,10 +2033,7 @@ template <>
Scope* ScopeStencil::createSpecificScope<GlobalScope, std::nullptr_t>(
JSContext* cx, CompilationInfo& compilationInfo) {
Rooted<UniquePtr<GlobalScope::Data>> rootedData(
cx, createSpecificScopeData<GlobalScope>(cx, compilationInfo));
if (!rootedData) {
return nullptr;
}
cx, releaseData<GlobalScope>(compilationInfo));
MOZ_ASSERT(enclosing(compilationInfo).isNullptr());
@ -2176,17 +2041,14 @@ Scope* ScopeStencil::createSpecificScope<GlobalScope, std::nullptr_t>(
return Scope::create<GlobalScope>(cx, kind(), nullptr, nullptr, &rootedData);
}
template <typename SpecificScopeT, typename SpecificEnvironmentT>
template <typename SpecificScopeType, typename SpecificEnvironmentType>
Scope* ScopeStencil::createSpecificScope(JSContext* cx,
CompilationInfo& compilationInfo) {
Rooted<UniquePtr<typename SpecificScopeT::Data>> rootedData(
cx, createSpecificScopeData<SpecificScopeT>(cx, compilationInfo));
if (!rootedData) {
return nullptr;
}
Rooted<UniquePtr<typename SpecificScopeType::Data>> rootedData(
cx, releaseData<SpecificScopeType>(compilationInfo));
RootedShape shape(cx);
if (!createSpecificShape<SpecificEnvironmentT>(
if (!createSpecificShape<SpecificEnvironmentType>(
cx, kind(), rootedData.get().get(), &shape)) {
return nullptr;
}
@ -2194,7 +2056,7 @@ Scope* ScopeStencil::createSpecificScope(JSContext* cx,
RootedScope enclosingScope(cx, enclosing(compilationInfo).existingScope());
// Because we already baked the data here, we needn't do it again.
return Scope::create<SpecificScopeT>(cx, kind(), enclosingScope, shape,
return Scope::create<SpecificScopeType>(cx, kind(), enclosingScope, shape,
&rootedData);
}

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

@ -26,23 +26,17 @@
namespace js {
namespace frontend {
struct CompilationInfo;
class ScriptStencil;
class ScopeStencil;
class ParserAtom;
}; // namespace frontend
template <typename NameT>
class AbstractBaseScopeData;
template <typename NameT>
class BaseAbstractBindingIter;
template <typename NameT>
class AbstractBindingIter;
using BindingIter = AbstractBindingIter<JSAtom>;
class BindingIter;
class ModuleObject;
class AbstractScopePtr;
@ -78,9 +72,6 @@ const char* ScopeKindString(ScopeKind kind);
template <typename NameT>
class AbstractBindingName {
template <typename OtherNameT>
friend class AbstractBindingName;
// A JSAtom* with its low bit used as a tag for the:
// * whether it is closed over (i.e., exists in the environment shape)
// * whether it is a top-level function binding in global or eval scope,
@ -96,10 +87,6 @@ class AbstractBindingName {
public:
AbstractBindingName() : bits_(0) {}
template <typename OldNameT>
AbstractBindingName(NameT* name, const AbstractBindingName<OldNameT>& old)
: bits_(uintptr_t(name) | (old.bits_ & FlagMask)) {}
AbstractBindingName(NameT* name, bool closedOver,
bool isTopLevelFunction = false)
: bits_(uintptr_t(name) | (closedOver ? ClosedOverFlag : 0x0) |
@ -125,13 +112,8 @@ class AbstractBindingName {
bool closedOver() const { return bits_ & ClosedOverFlag; }
template <typename NewNameT>
AbstractBindingName<NewNameT> transformName(NewNameT* newName) const {
return AbstractBindingName<NewNameT>(newName, *this);
}
private:
friend class BaseAbstractBindingIter<NameT>;
friend class AbstractBindingIter<NameT>;
friend class frontend::ScopeStencil;
// This method should be called only for binding names in `vars` range in
@ -153,10 +135,7 @@ const size_t ScopeDataAlignBytes = size_t(1) << gc::CellFlagBitsReservedForGC;
* suitably aligned to allow storing GC flags in the low bits.
*/
template <typename NameT>
class alignas(ScopeDataAlignBytes) AbstractBaseScopeData {
public:
using NameType = NameT;
};
class alignas(ScopeDataAlignBytes) AbstractBaseScopeData {};
using BaseScopeData = AbstractBaseScopeData<JSAtom>;
@ -175,7 +154,7 @@ using BaseScopeData = AbstractBaseScopeData<JSAtom>;
*
* The names array is implemented in terms of an generic type that
* allows specialization between a (JSAtom*) BindingName and a
* ParserAtom
* ParserAtomId
*/
template <typename NameT>
class AbstractTrailingNamesArray {
@ -298,7 +277,7 @@ class WrappedPtrOperations<Scope*, Wrapper> {
class Scope : public gc::TenuredCellWithNonGCPointer<BaseScopeData> {
friend class GCMarker;
friend class frontend::ScopeStencil;
friend class js::AbstractBindingIter<JSAtom>;
friend class js::BindingIter;
protected:
// The raw data pointer, stored in the cell header.
@ -337,11 +316,11 @@ class Scope : public gc::TenuredCellWithNonGCPointer<BaseScopeData> {
template <typename F>
void applyScopeDataTyped(F&& f);
template <typename EnvironmentT>
template <typename EnvironmentType>
static bool updateEnvShapeIfRequired(JSContext* cx, MutableHandleShape shape,
bool needsEnvironment);
template <typename EnvironmentT>
template <typename EnvironmentType>
static bool updateEnvShapeIfRequired(JSContext* cx,
mozilla::Maybe<uint32_t>* envShape,
bool needsEnvironment);
@ -433,25 +412,14 @@ class Scope : public gc::TenuredCellWithNonGCPointer<BaseScopeData> {
};
template <class Data>
inline size_t SizeOfScopeData(uint32_t numBindings) {
return sizeof(Data) + ((numBindings ? numBindings - 1 : 0) *
sizeof(AbstractBindingName<typename Data::NameType>));
inline size_t SizeOfData(uint32_t numBindings) {
static_assert(std::is_base_of_v<BaseScopeData, Data>,
"Data must be the correct sort of data, i.e. it must "
"inherit from BaseScopeData");
return sizeof(Data) +
(numBindings ? numBindings - 1 : 0) * sizeof(BindingName);
}
//
// A useful typedef for selecting between a gc-aware wrappers
// around pointers to BaseScopeData-derived types, and around raw
// pointer wrappers around BaseParserScopeData-derived types.
//
template <typename ScopeT, typename AtomT>
using AbstractScopeData = typename ScopeT::template AbstractData<AtomT>;
template <typename ScopeT, typename AtomT>
using MaybeRootedScopeData = std::conditional_t<
std::is_same_v<AtomT, JSAtom>,
MaybeRooted<UniquePtr<typename ScopeT::Data>, AllowGC::CanGC>,
MaybeRooted<AbstractScopeData<ScopeT, AtomT>*, AllowGC::NoGC>>;
//
// A lexical scope that holds let and const bindings. There are 4 kinds of
// LexicalScopes.
@ -475,7 +443,7 @@ using MaybeRootedScopeData = std::conditional_t<
//
class LexicalScope : public Scope {
friend class Scope;
friend class AbstractBindingIter<JSAtom>;
friend class BindingIter;
friend class GCMarker;
friend class frontend::ScopeStencil;
@ -516,12 +484,11 @@ class LexicalScope : public Scope {
uint32_t firstFrameSlot,
HandleScope enclosing);
template <typename AtomT, typename ShapeT>
static bool prepareForScopeCreation(
JSContext* cx, ScopeKind kind, uint32_t firstFrameSlot,
typename MaybeRootedScopeData<LexicalScope, AtomT>::MutableHandleType
data,
ShapeT envShape);
template <typename ShapeType>
static bool prepareForScopeCreation(JSContext* cx, ScopeKind kind,
uint32_t firstFrameSlot,
MutableHandle<UniquePtr<Data>> data,
ShapeType envShape);
Data& data() { return *static_cast<Data*>(rawData()); }
const Data& data() const { return *static_cast<const Data*>(rawData()); }
@ -564,7 +531,7 @@ inline bool Scope::is<LexicalScope>() const {
//
class FunctionScope : public Scope {
friend class GCMarker;
friend class AbstractBindingIter<JSAtom>;
friend class BindingIter;
friend class PositionalFormalParameterIter;
friend class Scope;
friend class AbstractScopePtr;
@ -630,13 +597,12 @@ class FunctionScope : public Scope {
using Data = AbstractData<JSAtom>;
template <typename AtomT, typename ShapeT>
static bool prepareForScopeCreation(
JSContext* cx,
typename MaybeRootedScopeData<FunctionScope, AtomT>::MutableHandleType
data,
bool hasParameterExprs, bool needsEnvironment, HandleFunction fun,
ShapeT envShape);
template <typename ShapeType>
static bool prepareForScopeCreation(JSContext* cx,
MutableHandle<UniquePtr<Data>> data,
bool hasParameterExprs,
bool needsEnvironment, HandleFunction fun,
ShapeType envShape);
static FunctionScope* clone(JSContext* cx, Handle<FunctionScope*> scope,
HandleFunction fun, HandleScope enclosing);
@ -671,7 +637,6 @@ class FunctionScope : public Scope {
}
static bool isSpecialName(JSContext* cx, JSAtom* name);
static bool isSpecialName(JSContext* cx, const frontend::ParserAtom* name);
};
//
@ -685,7 +650,7 @@ class FunctionScope : public Scope {
//
class VarScope : public Scope {
friend class GCMarker;
friend class AbstractBindingIter<JSAtom>;
friend class BindingIter;
friend class Scope;
friend class frontend::ScopeStencil;
@ -723,11 +688,12 @@ class VarScope : public Scope {
uint32_t firstFrameSlot,
bool needsEnvironment, HandleScope enclosing);
template <typename AtomT, typename ShapeT>
static bool prepareForScopeCreation(
JSContext* cx, ScopeKind kind,
typename MaybeRootedScopeData<VarScope, AtomT>::MutableHandleType data,
uint32_t firstFrameSlot, bool needsEnvironment, ShapeT envShape);
template <typename ShapeType>
static bool prepareForScopeCreation(JSContext* cx, ScopeKind kind,
MutableHandle<UniquePtr<Data>> data,
uint32_t firstFrameSlot,
bool needsEnvironment,
ShapeType envShape);
Data& data() { return *static_cast<Data*>(rawData()); }
@ -763,14 +729,14 @@ inline bool Scope::is<VarScope>() const {
//
class GlobalScope : public Scope {
friend class Scope;
friend class AbstractBindingIter<JSAtom>;
friend class BindingIter;
friend class GCMarker;
public:
// Data is public because it is created by the frontend. See
// Parser<FullParseHandler>::newGlobalScopeData.
template <typename NameT>
struct AbstractData : public AbstractBaseScopeData<NameT> {
struct AbstractData : BaseScopeData {
// Bindings are sorted by kind.
// `vars` includes top-level functions which is distinguished by a bit
// on the BindingName.
@ -855,7 +821,7 @@ class WithScope : public Scope {
//
class EvalScope : public Scope {
friend class Scope;
friend class AbstractBindingIter<JSAtom>;
friend class BindingIter;
friend class GCMarker;
friend class frontend::ScopeStencil;
@ -896,11 +862,10 @@ class EvalScope : public Scope {
MutableHandle<UniquePtr<Data>> data,
HandleScope enclosing);
template <typename AtomT, typename ShapeT>
static bool prepareForScopeCreation(
JSContext* cx, ScopeKind scopeKind,
typename MaybeRootedScopeData<EvalScope, AtomT>::MutableHandleType data,
ShapeT envShape);
template <typename ShapeType>
static bool prepareForScopeCreation(JSContext* cx, ScopeKind scopeKind,
MutableHandle<UniquePtr<Data>> data,
ShapeType envShape);
Data& data() { return *static_cast<Data*>(rawData()); }
@ -940,7 +905,7 @@ inline bool Scope::is<EvalScope>() const {
//
class ModuleScope : public Scope {
friend class GCMarker;
friend class AbstractBindingIter<JSAtom>;
friend class BindingIter;
friend class Scope;
friend class AbstractScopePtr;
friend class frontend::ScopeStencil;
@ -950,7 +915,7 @@ class ModuleScope : public Scope {
// Data is public because it is created by the frontend. See
// Parser<FullParseHandler>::newModuleScopeData.
template <typename NameT>
struct AbstractData : public AbstractBaseScopeData<NameT> {
struct AbstractData : BaseScopeData {
// The module of the scope.
GCPtr<ModuleObject*> module = {};
@ -989,11 +954,11 @@ class ModuleScope : public Scope {
MutableHandle<UniquePtr<Data>> data,
Handle<ModuleObject*> module,
HandleScope enclosing);
template <typename AtomT, typename ShapeT>
static bool prepareForScopeCreation(
JSContext* cx,
typename MaybeRootedScopeData<ModuleScope, AtomT>::MutableHandleType data,
HandleModuleObject module, ShapeT envShape);
template <typename ShapeType>
static bool prepareForScopeCreation(JSContext* cx,
MutableHandle<UniquePtr<Data>> data,
HandleModuleObject module,
ShapeType envShape);
Data& data() { return *static_cast<Data*>(rawData()); }
@ -1006,7 +971,7 @@ class ModuleScope : public Scope {
};
class WasmInstanceScope : public Scope {
friend class AbstractBindingIter<JSAtom>;
friend class BindingIter;
friend class Scope;
friend class GCMarker;
friend class AbstractScopePtr;
@ -1060,7 +1025,7 @@ class WasmInstanceScope : public Scope {
// Debugger only, and not for wasm execution.
//
class WasmFunctionScope : public Scope {
friend class AbstractBindingIter<JSAtom>;
friend class BindingIter;
friend class Scope;
friend class GCMarker;
friend class AbstractScopePtr;
@ -1152,7 +1117,7 @@ void Scope::applyScopeDataTyped(F&& f) {
// }
//
template <typename NameT>
class BaseAbstractBindingIter {
class AbstractBindingIter {
protected:
// Bindings are sorted by kind. Because different Scopes have differently
// laid out Data for packing, BindingIter must handle all binding kinds.
@ -1294,44 +1259,43 @@ class BaseAbstractBindingIter {
}
}
BaseAbstractBindingIter() = default;
AbstractBindingIter() = default;
public:
BaseAbstractBindingIter(LexicalScope::AbstractData<NameT>& data,
AbstractBindingIter(LexicalScope::AbstractData<NameT>& data,
uint32_t firstFrameSlot, bool isNamedLambda) {
init(data, firstFrameSlot, isNamedLambda ? IsNamedLambda : 0);
}
BaseAbstractBindingIter(FunctionScope::AbstractData<NameT>& data,
AbstractBindingIter(FunctionScope::AbstractData<NameT>& data,
bool hasParameterExprs) {
init(data, IgnoreDestructuredFormalParameters |
(hasParameterExprs ? HasFormalParameterExprs : 0));
}
BaseAbstractBindingIter(VarScope::AbstractData<NameT>& data,
AbstractBindingIter(VarScope::AbstractData<NameT>& data,
uint32_t firstFrameSlot) {
init(data, firstFrameSlot);
}
explicit BaseAbstractBindingIter(GlobalScope::AbstractData<NameT>& data) {
explicit AbstractBindingIter(GlobalScope::AbstractData<NameT>& data) {
init(data);
}
explicit BaseAbstractBindingIter(ModuleScope::AbstractData<NameT>& data) {
explicit AbstractBindingIter(ModuleScope::AbstractData<NameT>& data) {
init(data);
}
explicit BaseAbstractBindingIter(
WasmFunctionScope::AbstractData<NameT>& data) {
explicit AbstractBindingIter(WasmFunctionScope::AbstractData<NameT>& data) {
init(data);
}
BaseAbstractBindingIter(EvalScope::AbstractData<NameT>& data, bool strict) {
AbstractBindingIter(EvalScope::AbstractData<NameT>& data, bool strict) {
init(data, strict);
}
MOZ_IMPLICIT BaseAbstractBindingIter(
const BaseAbstractBindingIter<NameT>& bi) = default;
MOZ_IMPLICIT AbstractBindingIter(const AbstractBindingIter<NameT>& bi) =
default;
bool done() const { return index_ == length_; }
@ -1444,34 +1408,22 @@ class BaseAbstractBindingIter {
}
};
template <typename NameT>
class AbstractBindingIter;
template <>
class AbstractBindingIter<JSAtom> : public BaseAbstractBindingIter<JSAtom> {
using Base = BaseAbstractBindingIter<JSAtom>;
class BindingIter : public AbstractBindingIter<JSAtom> {
using Base = AbstractBindingIter<JSAtom>;
public:
AbstractBindingIter<JSAtom>(ScopeKind kind, BaseScopeData* data,
uint32_t firstFrameSlot);
BindingIter(ScopeKind kind, BaseScopeData* data, uint32_t firstFrameSlot);
explicit AbstractBindingIter<JSAtom>(Scope* scope);
explicit AbstractBindingIter<JSAtom>(JSScript* script);
explicit BindingIter(Scope* scope);
explicit BindingIter(JSScript* script);
using Base::Base;
MOZ_IMPLICIT BindingIter(const BindingIter& bi) = default;
void trace(JSTracer* trc);
};
template <>
class AbstractBindingIter<const frontend::ParserAtom>
: public BaseAbstractBindingIter<const frontend::ParserAtom> {
using Base = BaseAbstractBindingIter<const frontend::ParserAtom>;
public:
using Base::Base;
};
void DumpBindings(JSContext* cx, Scope* scope);
JSAtom* FrameSlotName(JSScript* script, jsbytecode* pc);
@ -1632,10 +1584,6 @@ Shape* CreateEnvironmentShape(JSContext* cx, BindingIter& bi,
const JSClass* cls, uint32_t numSlots,
uint32_t baseShapeFlags);
Shape* CreateEnvironmentShape(
JSContext* cx, AbstractBindingIter<const frontend::ParserAtom>& bi,
const JSClass* cls, uint32_t numSlots, uint32_t baseShapeFlags);
Shape* EmptyEnvironmentShape(JSContext* cx, const JSClass* cls,
uint32_t numSlots, uint32_t baseShapeFlags);

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

@ -42,7 +42,6 @@
#include "builtin/String.h"
#include "builtin/TypedObject.h"
#include "builtin/WeakMapObject.h"
#include "frontend/ParserAtom.h" // js::frontend::ParserAtom
#include "gc/Marking.h"
#include "gc/Policy.h"
#include "jit/AtomicOperations.h"
@ -958,16 +957,6 @@ bool js::IsExtendedUnclonedSelfHostedFunctionName(JSAtom* name) {
}
return name->latin1OrTwoByteChar(0) == '$';
}
bool js::IsExtendedUnclonedSelfHostedFunctionName(
const frontend::ParserAtom* id) {
if (id->length() < 2) {
return false;
}
char16_t ch =
id->hasLatin1Chars() ? id->latin1Chars()[0] : id->twoByteChars()[0];
return ch == '$';
}
static void SetUnclonedSelfHostedFunctionName(JSFunction* fun, JSAtom* name) {
fun->setExtendedSlot(ORIGINAL_FUNCTION_NAME_SLOT, StringValue(name));

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

@ -14,10 +14,6 @@
namespace js {
namespace frontend {
class ParserAtom;
}
/*
* Check whether the given JSFunction is a self-hosted function whose
* self-hosted name is the given name.
@ -49,7 +45,6 @@ PropertyName* GetClonedSelfHostedFunctionNameOffMainThread(JSFunction* fun);
* extended function, to store the original name in `_SetCanonicalName`.
*/
bool IsExtendedUnclonedSelfHostedFunctionName(JSAtom* name);
bool IsExtendedUnclonedSelfHostedFunctionName(const frontend::ParserAtom* id);
bool IsCallSelfHostedNonGenericMethod(NativeImpl impl);

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

@ -27,7 +27,6 @@
#include "jsfriendapi.h"
#include "frontend/BytecodeCompiler.h"
#include "frontend/ParserAtom.h"
#include "gc/Marking.h"
#include "gc/MaybeRooted.h"
#include "gc/Nursery.h"
@ -1506,14 +1505,6 @@ bool AutoStableStringChars::copyTwoByteChars(JSContext* cx,
return true;
}
UniqueChars js::ParserAtomToNewUTF8CharsZ(
JSContext* maybecx, const js::frontend::ParserAtom* atom) {
return UniqueChars(
atom->hasLatin1Chars()
? JS::CharsToNewUTF8CharsZ(maybecx, atom->latin1Range()).c_str()
: JS::CharsToNewUTF8CharsZ(maybecx, atom->twoByteRange()).c_str());
}
#if defined(DEBUG) || defined(JS_JITSPEW)
void JSAtom::dump(js::GenericPrinter& out) {
out.printf("JSAtom* (%p) = ", (void*)this);

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

@ -45,12 +45,6 @@ class JS_FRIEND_API AutoStableStringChars;
namespace js {
namespace frontend {
class ParserAtom;
} // namespace frontend
class StaticStrings;
class PropertyName;
@ -1476,9 +1470,6 @@ static inline UniqueChars StringToNewUTF8CharsZ(JSContext* maybecx,
.c_str());
}
UniqueChars ParserAtomToNewUTF8CharsZ(JSContext* maybecx,
const js::frontend::ParserAtom* atom);
/**
* Allocate a string with the given contents. If |allowGC == CanGC|, this may
* trigger a GC.

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

@ -539,13 +539,13 @@ static inline ParseNode* ExpressionStatementExpr(ParseNode* pn) {
return UnaryKid(pn);
}
static inline const ParserName* LoopControlMaybeLabel(ParseNode* pn) {
static inline PropertyName* LoopControlMaybeLabel(ParseNode* pn) {
MOZ_ASSERT(pn->isKind(ParseNodeKind::BreakStmt) ||
pn->isKind(ParseNodeKind::ContinueStmt));
return pn->as<LoopControlStatement>().label();
}
static inline const ParserName* LabeledStatementLabel(ParseNode* pn) {
static inline PropertyName* LabeledStatementLabel(ParseNode* pn) {
return pn->as<LabeledStatement>().label();
}
@ -565,8 +565,8 @@ static ParseNode* DotBase(ParseNode* pn) {
return &pn->as<PropertyAccess>().expression();
}
static const ParserName* DotMember(ParseNode* pn) {
return pn->as<PropertyAccess>().name();
static PropertyName* DotMember(ParseNode* pn) {
return &pn->as<PropertyAccess>().name();
}
static ParseNode* ElemBase(ParseNode* pn) {
@ -577,9 +577,9 @@ static ParseNode* ElemIndex(ParseNode* pn) {
return &pn->as<PropertyByValue>().key();
}
static inline const ParserName* FunctionName(FunctionNode* funNode) {
if (const ParserAtom* name = funNode->funbox()->explicitName()) {
return name->asName();
static inline PropertyName* FunctionName(FunctionNode* funNode) {
if (JSAtom* name = funNode->funbox()->explicitName()) {
return name->asPropertyName();
}
return nullptr;
}
@ -600,10 +600,10 @@ static inline bool IsNormalObjectField(ParseNode* pn) {
BinaryLeft(pn)->isKind(ParseNodeKind::ObjectPropertyName);
}
static inline const ParserName* ObjectNormalFieldName(ParseNode* pn) {
static inline PropertyName* ObjectNormalFieldName(ParseNode* pn) {
MOZ_ASSERT(IsNormalObjectField(pn));
MOZ_ASSERT(BinaryLeft(pn)->isKind(ParseNodeKind::ObjectPropertyName));
return BinaryLeft(pn)->as<NameNode>().atom()->asName();
return BinaryLeft(pn)->as<NameNode>().atom()->asPropertyName();
}
static inline ParseNode* ObjectNormalFieldInitializer(ParseNode* pn) {
@ -611,12 +611,11 @@ static inline ParseNode* ObjectNormalFieldInitializer(ParseNode* pn) {
return BinaryRight(pn);
}
static inline bool IsUseOfName(ParseNode* pn, const ParserName* name) {
static inline bool IsUseOfName(ParseNode* pn, PropertyName* name) {
return pn->isName(name);
}
static inline bool IsIgnoredDirectiveName(JSContext* cx,
const ParserAtom* atom) {
static inline bool IsIgnoredDirectiveName(JSContext* cx, JSAtom* atom) {
return atom != cx->parserNames().useStrict;
}
@ -1038,7 +1037,7 @@ static const unsigned VALIDATION_LIFO_DEFAULT_CHUNK_SIZE = 4 * 1024;
class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidatorShared {
public:
class Func {
const ParserName* name_;
PropertyName* name_;
uint32_t sigIndex_;
uint32_t firstUse_;
uint32_t funcDefIndex_;
@ -1053,7 +1052,7 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidatorShared {
Uint32Vector callSiteLineNums_;
public:
Func(const ParserName* name, uint32_t sigIndex, uint32_t firstUse,
Func(PropertyName* name, uint32_t sigIndex, uint32_t firstUse,
uint32_t funcDefIndex)
: name_(name),
sigIndex_(sigIndex),
@ -1064,7 +1063,7 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidatorShared {
srcEnd_(0),
line_(0) {}
const ParserName* name() const { return name_; }
PropertyName* name() const { return name_; }
uint32_t sigIndex() const { return sigIndex_; }
uint32_t firstUse() const { return firstUse_; }
bool defined() const { return defined_; }
@ -1108,7 +1107,7 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidatorShared {
class Table {
uint32_t sigIndex_;
const ParserName* name_;
PropertyName* name_;
uint32_t firstUse_;
uint32_t mask_;
bool defined_;
@ -1116,7 +1115,7 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidatorShared {
Table(Table&& rhs) = delete;
public:
Table(uint32_t sigIndex, const ParserName* name, uint32_t firstUse,
Table(uint32_t sigIndex, PropertyName* name, uint32_t firstUse,
uint32_t mask)
: sigIndex_(sigIndex),
name_(name),
@ -1125,7 +1124,7 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidatorShared {
defined_(false) {}
uint32_t sigIndex() const { return sigIndex_; }
const ParserName* name() const { return name_; }
PropertyName* name() const { return name_; }
uint32_t firstUse() const { return firstUse_; }
unsigned mask() const { return mask_; }
bool defined() const { return defined_; }
@ -1257,10 +1256,9 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidatorShared {
};
struct ArrayView {
ArrayView(const ParserName* name, Scalar::Type type)
: name(name), type(type) {}
ArrayView(PropertyName* name, Scalar::Type type) : name(name), type(type) {}
const ParserName* name;
PropertyName* name;
Scalar::Type type;
};
@ -1284,19 +1282,18 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidatorShared {
};
class NamedSig : public HashableSig {
const ParserName* name_;
PropertyName* name_;
public:
NamedSig(const ParserName* name, uint32_t sigIndex,
const TypeDefVector& types)
NamedSig(PropertyName* name, uint32_t sigIndex, const TypeDefVector& types)
: HashableSig(sigIndex, types), name_(name) {}
const ParserName* name() const { return name_; }
PropertyName* name() const { return name_; }
// Implement HashPolicy:
struct Lookup {
const ParserName* name;
PropertyName* name;
const FuncType& funcType;
Lookup(const ParserName* name, const FuncType& funcType)
Lookup(PropertyName* name, const FuncType& funcType)
: name(name), funcType(funcType) {}
};
static HashNumber hash(Lookup l) {
@ -1309,18 +1306,17 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidatorShared {
using SigSet = HashSet<HashableSig, HashableSig>;
using FuncImportMap = HashMap<NamedSig, uint32_t, NamedSig>;
using GlobalMap = HashMap<const ParserName*, Global*>;
using MathNameMap = HashMap<const ParserName*, MathBuiltin>;
using GlobalMap = HashMap<PropertyName*, Global*>;
using MathNameMap = HashMap<PropertyName*, MathBuiltin>;
using ArrayViewVector = Vector<ArrayView>;
protected:
JSContext* cx_;
CompilationInfo& compilationInfo_;
FunctionNode* moduleFunctionNode_;
const ParserName* moduleFunctionName_;
const ParserName* globalArgumentName_ = nullptr;
const ParserName* importArgumentName_ = nullptr;
const ParserName* bufferArgumentName_ = nullptr;
PropertyName* moduleFunctionName_;
PropertyName* globalArgumentName_ = nullptr;
PropertyName* importArgumentName_ = nullptr;
PropertyName* bufferArgumentName_ = nullptr;
MathNameMap standardLibraryMathNames_;
// Validation-internal state:
@ -1343,10 +1339,8 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidatorShared {
bool errorOverRecursed_ = false;
protected:
ModuleValidatorShared(JSContext* cx, CompilationInfo& compilationInfo,
FunctionNode* moduleFunctionNode)
ModuleValidatorShared(JSContext* cx, FunctionNode* moduleFunctionNode)
: cx_(cx),
compilationInfo_(compilationInfo),
moduleFunctionNode_(moduleFunctionNode),
moduleFunctionName_(FunctionName(moduleFunctionNode)),
standardLibraryMathNames_(cx),
@ -1386,13 +1380,12 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidatorShared {
auto AddMathFunction = [this](const char* name,
AsmJSMathBuiltinFunction func) {
auto mbAtom =
compilationInfo_.parserAtoms.internAscii(cx_, name, strlen(name));
if (mbAtom.isErr()) {
JSAtom* atom = Atomize(cx_, name, strlen(name));
if (!atom) {
return false;
}
MathBuiltin builtin(func);
return this->standardLibraryMathNames_.putNew(mbAtom.unwrap()->asName(),
return this->standardLibraryMathNames_.putNew(atom->asPropertyName(),
builtin);
};
@ -1417,13 +1410,12 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidatorShared {
};
auto AddMathConstant = [this](const char* name, double cst) {
auto mbAtom =
compilationInfo_.parserAtoms.internAscii(cx_, name, strlen(name));
if (mbAtom.isErr()) {
JSAtom* atom = Atomize(cx_, name, strlen(name));
if (!atom) {
return false;
}
MathBuiltin builtin(cst);
return this->standardLibraryMathNames_.putNew(mbAtom.unwrap()->asName(),
return this->standardLibraryMathNames_.putNew(atom->asPropertyName(),
builtin);
};
@ -1438,49 +1430,52 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidatorShared {
public:
JSContext* cx() const { return cx_; }
const ParserName* moduleFunctionName() const { return moduleFunctionName_; }
const ParserName* globalArgumentName() const { return globalArgumentName_; }
const ParserName* importArgumentName() const { return importArgumentName_; }
const ParserName* bufferArgumentName() const { return bufferArgumentName_; }
PropertyName* moduleFunctionName() const { return moduleFunctionName_; }
PropertyName* globalArgumentName() const { return globalArgumentName_; }
PropertyName* importArgumentName() const { return importArgumentName_; }
PropertyName* bufferArgumentName() const { return bufferArgumentName_; }
const ModuleEnvironment& env() { return env_; }
uint64_t minMemoryLength() const { return env_.minMemoryLength; }
void initModuleFunctionName(const ParserName* name) {
void initModuleFunctionName(PropertyName* name) {
MOZ_ASSERT(!moduleFunctionName_);
moduleFunctionName_ = name;
}
MOZ_MUST_USE bool initGlobalArgumentName(const ParserName* n) {
MOZ_MUST_USE bool initGlobalArgumentName(PropertyName* n) {
globalArgumentName_ = n;
if (n) {
asmJSMetadata_->globalArgumentName = ParserAtomToNewUTF8CharsZ(cx_, n);
MOZ_ASSERT(n->isTenured());
asmJSMetadata_->globalArgumentName = StringToNewUTF8CharsZ(cx_, *n);
if (!asmJSMetadata_->globalArgumentName) {
return false;
}
}
return true;
}
MOZ_MUST_USE bool initImportArgumentName(const ParserName* n) {
MOZ_MUST_USE bool initImportArgumentName(PropertyName* n) {
importArgumentName_ = n;
if (n) {
asmJSMetadata_->importArgumentName = ParserAtomToNewUTF8CharsZ(cx_, n);
MOZ_ASSERT(n->isTenured());
asmJSMetadata_->importArgumentName = StringToNewUTF8CharsZ(cx_, *n);
if (!asmJSMetadata_->importArgumentName) {
return false;
}
}
return true;
}
MOZ_MUST_USE bool initBufferArgumentName(const ParserName* n) {
MOZ_MUST_USE bool initBufferArgumentName(PropertyName* n) {
bufferArgumentName_ = n;
if (n) {
asmJSMetadata_->bufferArgumentName = ParserAtomToNewUTF8CharsZ(cx_, n);
MOZ_ASSERT(n->isTenured());
asmJSMetadata_->bufferArgumentName = StringToNewUTF8CharsZ(cx_, *n);
if (!asmJSMetadata_->bufferArgumentName) {
return false;
}
}
return true;
}
bool addGlobalVarInit(const ParserName* var, const NumLit& lit, Type type,
bool addGlobalVarInit(PropertyName* var, const NumLit& lit, Type type,
bool isConst) {
MOZ_ASSERT(type.isGlobalVarType());
MOZ_ASSERT(type == Type::canonicalize(Type::lit(lit)));
@ -1510,11 +1505,11 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidatorShared {
g.pod.u.var.u.val_ = lit.value();
return asmJSMetadata_->asmJSGlobals.append(std::move(g));
}
bool addGlobalVarImport(const ParserName* var, const ParserName* field,
Type type, bool isConst) {
bool addGlobalVarImport(PropertyName* var, PropertyName* field, Type type,
bool isConst) {
MOZ_ASSERT(type.isGlobalVarType());
UniqueChars fieldChars = ParserAtomToNewUTF8CharsZ(cx_, field);
UniqueChars fieldChars = StringToNewUTF8CharsZ(cx_, *field);
if (!fieldChars) {
return false;
}
@ -1541,11 +1536,11 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidatorShared {
g.pod.u.var.u.importValType_ = valType.packed();
return asmJSMetadata_->asmJSGlobals.append(std::move(g));
}
bool addArrayView(const ParserName* var, Scalar::Type vt,
const ParserName* maybeField) {
bool addArrayView(PropertyName* var, Scalar::Type vt,
PropertyName* maybeField) {
UniqueChars fieldChars;
if (maybeField) {
fieldChars = ParserAtomToNewUTF8CharsZ(cx_, maybeField);
fieldChars = StringToNewUTF8CharsZ(cx_, *maybeField);
if (!fieldChars) {
return false;
}
@ -1568,10 +1563,9 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidatorShared {
g.pod.u.viewType_ = vt;
return asmJSMetadata_->asmJSGlobals.append(std::move(g));
}
bool addMathBuiltinFunction(const ParserName* var,
AsmJSMathBuiltinFunction func,
const ParserName* field) {
UniqueChars fieldChars = ParserAtomToNewUTF8CharsZ(cx_, field);
bool addMathBuiltinFunction(PropertyName* var, AsmJSMathBuiltinFunction func,
PropertyName* field) {
UniqueChars fieldChars = StringToNewUTF8CharsZ(cx_, *field);
if (!fieldChars) {
return false;
}
@ -1591,7 +1585,7 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidatorShared {
}
private:
bool addGlobalDoubleConstant(const ParserName* var, double constant) {
bool addGlobalDoubleConstant(PropertyName* var, double constant) {
Global* global = validationLifo_.new_<Global>(Global::ConstantLiteral);
if (!global) {
return false;
@ -1601,9 +1595,9 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidatorShared {
}
public:
bool addMathBuiltinConstant(const ParserName* var, double constant,
const ParserName* field) {
UniqueChars fieldChars = ParserAtomToNewUTF8CharsZ(cx_, field);
bool addMathBuiltinConstant(PropertyName* var, double constant,
PropertyName* field) {
UniqueChars fieldChars = StringToNewUTF8CharsZ(cx_, *field);
if (!fieldChars) {
return false;
}
@ -1617,9 +1611,9 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidatorShared {
g.pod.u.constant.kind_ = AsmJSGlobal::MathConstant;
return asmJSMetadata_->asmJSGlobals.append(std::move(g));
}
bool addGlobalConstant(const ParserName* var, double constant,
const ParserName* field) {
UniqueChars fieldChars = ParserAtomToNewUTF8CharsZ(cx_, field);
bool addGlobalConstant(PropertyName* var, double constant,
PropertyName* field) {
UniqueChars fieldChars = StringToNewUTF8CharsZ(cx_, *field);
if (!fieldChars) {
return false;
}
@ -1633,9 +1627,9 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidatorShared {
g.pod.u.constant.kind_ = AsmJSGlobal::GlobalConstant;
return asmJSMetadata_->asmJSGlobals.append(std::move(g));
}
bool addArrayViewCtor(const ParserName* var, Scalar::Type vt,
const ParserName* field) {
UniqueChars fieldChars = ParserAtomToNewUTF8CharsZ(cx_, field);
bool addArrayViewCtor(PropertyName* var, Scalar::Type vt,
PropertyName* field) {
UniqueChars fieldChars = StringToNewUTF8CharsZ(cx_, *field);
if (!fieldChars) {
return false;
}
@ -1653,8 +1647,8 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidatorShared {
g.pod.u.viewType_ = vt;
return asmJSMetadata_->asmJSGlobals.append(std::move(g));
}
bool addFFI(const ParserName* var, const ParserName* field) {
UniqueChars fieldChars = ParserAtomToNewUTF8CharsZ(cx_, field);
bool addFFI(PropertyName* var, PropertyName* field) {
UniqueChars fieldChars = StringToNewUTF8CharsZ(cx_, *field);
if (!fieldChars) {
return false;
}
@ -1677,11 +1671,11 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidatorShared {
g.pod.u.ffiIndex_ = ffiIndex;
return asmJSMetadata_->asmJSGlobals.append(std::move(g));
}
bool addExportField(const Func& func, const ParserName* maybeField) {
bool addExportField(const Func& func, PropertyName* maybeField) {
// Record the field name of this export.
CacheableChars fieldChars;
if (maybeField) {
fieldChars = ParserAtomToNewUTF8CharsZ(cx_, maybeField);
fieldChars = StringToNewUTF8CharsZ(cx_, *maybeField);
} else {
fieldChars = DuplicateString("");
}
@ -1783,17 +1777,16 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidatorShared {
return false;
}
bool failNameOffset(uint32_t offset, const char* fmt,
const ParserName* name) {
bool failNameOffset(uint32_t offset, const char* fmt, PropertyName* name) {
// This function is invoked without the caller properly rooting its locals.
gc::AutoSuppressGC suppress(cx_);
if (UniqueChars bytes = ParserAtomToPrintableString(cx_, name)) {
if (UniqueChars bytes = AtomToPrintableString(cx_, name)) {
failfOffset(offset, fmt, bytes.get());
}
return false;
}
bool failName(ParseNode* pn, const char* fmt, const ParserName* name) {
bool failName(ParseNode* pn, const char* fmt, PropertyName* name) {
return failNameOffset(pn->pn_pos.begin, fmt, name);
}
@ -1809,14 +1802,14 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidatorShared {
unsigned numFuncPtrTables() const { return tables_.length(); }
Table& table(unsigned i) const { return *tables_[i]; }
const Global* lookupGlobal(const ParserName* name) const {
const Global* lookupGlobal(PropertyName* name) const {
if (GlobalMap::Ptr p = globalMap_.lookup(name)) {
return p->value();
}
return nullptr;
}
Func* lookupFuncDef(const ParserName* name) {
Func* lookupFuncDef(PropertyName* name) {
if (GlobalMap::Ptr p = globalMap_.lookup(name)) {
Global* value = p->value();
if (value->which() == Global::Function) {
@ -1826,7 +1819,7 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidatorShared {
return nullptr;
}
bool lookupStandardLibraryMathName(const ParserName* name,
bool lookupStandardLibraryMathName(PropertyName* name,
MathBuiltin* mathBuiltin) const {
if (MathNameMap::Ptr p = standardLibraryMathNames_.lookup(name)) {
*mathBuiltin = p->value();
@ -1866,10 +1859,9 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidator
AsmJSParser<Unit>& parser_;
public:
ModuleValidator(JSContext* cx, CompilationInfo& compilationInfo,
AsmJSParser<Unit>& parser, FunctionNode* moduleFunctionNode)
: ModuleValidatorShared(cx, compilationInfo, moduleFunctionNode),
parser_(parser) {}
ModuleValidator(JSContext* cx, AsmJSParser<Unit>& parser,
FunctionNode* moduleFunctionNode)
: ModuleValidatorShared(cx, moduleFunctionNode), parser_(parser) {}
~ModuleValidator() {
if (errorString_) {
@ -1957,7 +1949,7 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidator
auto& tokenStream() const { return parser_.tokenStream; }
public:
bool addFuncDef(const ParserName* name, uint32_t firstUse, FuncType&& sig,
bool addFuncDef(PropertyName* name, uint32_t firstUse, FuncType&& sig,
Func** func) {
uint32_t sigIndex;
if (!declareSig(std::move(sig), &sigIndex)) {
@ -1983,7 +1975,7 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidator
*func = &funcDefs_.back();
return true;
}
bool declareFuncPtrTable(FuncType&& sig, const ParserName* name,
bool declareFuncPtrTable(FuncType&& sig, PropertyName* name,
uint32_t firstUse, uint32_t mask,
uint32_t* tableIndex) {
if (mask > MaxTableLength) {
@ -2022,7 +2014,7 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidator
Table* t = validationLifo_.new_<Table>(sigIndex, name, firstUse, mask);
return t && tables_.append(t);
}
bool declareImport(const ParserName* name, FuncType&& sig, unsigned ffiIndex,
bool declareImport(PropertyName* name, FuncType&& sig, unsigned ffiIndex,
uint32_t* importIndex) {
FuncImportMap::AddPtr p =
funcImportMap_.lookupForAdd(NamedSig::Lookup(name, sig));
@ -2084,7 +2076,7 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidator
return nullptr;
}
for (const Func& func : funcDefs_) {
CacheableChars funcName = ParserAtomToNewUTF8CharsZ(cx_, func.name());
CacheableChars funcName = StringToNewUTF8CharsZ(cx_, *func.name());
if (!funcName ||
!asmJSMetadata_->asmJSFuncNames.emplaceBack(std::move(funcName))) {
return nullptr;
@ -2311,7 +2303,7 @@ static inline bool IsLiteralInt(ModuleValidatorShared& m, ParseNode* pn,
namespace {
typedef Vector<const ParserName*, 4, SystemAllocPolicy> LabelVector;
typedef Vector<PropertyName*, 4, SystemAllocPolicy> LabelVector;
class MOZ_STACK_CLASS FunctionValidatorShared {
public:
@ -2324,8 +2316,8 @@ class MOZ_STACK_CLASS FunctionValidatorShared {
};
protected:
using LocalMap = HashMap<const ParserName*, Local>;
using LabelMap = HashMap<const ParserName*, uint32_t>;
using LocalMap = HashMap<PropertyName*, Local>;
using LabelMap = HashMap<PropertyName*, uint32_t>;
// This is also a ModuleValidator<Unit>& after the appropriate static_cast<>.
ModuleValidatorShared& m_;
@ -2390,13 +2382,13 @@ class MOZ_STACK_CLASS FunctionValidatorShared {
return false;
}
bool failName(ParseNode* pn, const char* fmt, const ParserName* name) {
bool failName(ParseNode* pn, const char* fmt, PropertyName* name) {
return m_.failName(pn, fmt, name);
}
/***************************************************** Local scope setup */
bool addLocal(ParseNode* pn, const ParserName* name, Type type) {
bool addLocal(ParseNode* pn, PropertyName* name, Type type) {
LocalMap::AddPtr p = locals_.lookupForAdd(name);
if (p) {
return failName(pn, "duplicate local name '%s' not allowed", name);
@ -2424,7 +2416,7 @@ class MOZ_STACK_CLASS FunctionValidatorShared {
return encoder().writeOp(op) &&
encoder().writeVarU32(blockDepth_ - 1 - absolute);
}
void removeLabel(const ParserName* label, LabelMap* map) {
void removeLabel(PropertyName* label, LabelMap* map) {
LabelMap::Ptr p = map->lookup(label);
MOZ_ASSERT(p);
map->remove(p);
@ -2443,7 +2435,7 @@ class MOZ_STACK_CLASS FunctionValidatorShared {
bool pushUnbreakableBlock(const LabelVector* labels = nullptr) {
if (labels) {
for (const ParserName* label : *labels) {
for (PropertyName* label : *labels) {
if (!breakLabels_.putNew(label, blockDepth_)) {
return false;
}
@ -2455,7 +2447,7 @@ class MOZ_STACK_CLASS FunctionValidatorShared {
}
bool popUnbreakableBlock(const LabelVector* labels = nullptr) {
if (labels) {
for (const ParserName* label : *labels) {
for (PropertyName* label : *labels) {
removeLabel(label, &breakLabels_);
}
}
@ -2523,7 +2515,7 @@ class MOZ_STACK_CLASS FunctionValidatorShared {
bool addLabels(const LabelVector& labels, uint32_t relativeBreakDepth,
uint32_t relativeContinueDepth) {
for (const ParserName* label : labels) {
for (PropertyName* label : labels) {
if (!breakLabels_.putNew(label, blockDepth_ + relativeBreakDepth)) {
return false;
}
@ -2534,12 +2526,12 @@ class MOZ_STACK_CLASS FunctionValidatorShared {
return true;
}
void removeLabels(const LabelVector& labels) {
for (const ParserName* label : labels) {
for (PropertyName* label : labels) {
removeLabel(label, &breakLabels_);
removeLabel(label, &continueLabels_);
}
}
bool writeLabeledBreakOrContinue(const ParserName* label, bool isBreak) {
bool writeLabeledBreakOrContinue(PropertyName* label, bool isBreak) {
LabelMap& map = isBreak ? breakLabels_ : continueLabels_;
if (LabelMap::Ptr p = map.lookup(label)) {
return writeBr(p->value());
@ -2549,15 +2541,14 @@ class MOZ_STACK_CLASS FunctionValidatorShared {
/*************************************************** Read-only interface */
const Local* lookupLocal(const ParserName* name) const {
const Local* lookupLocal(PropertyName* name) const {
if (auto p = locals_.lookup(name)) {
return &p->value();
}
return nullptr;
}
const ModuleValidatorShared::Global* lookupGlobal(
const ParserName* name) const {
const ModuleValidatorShared::Global* lookupGlobal(PropertyName* name) const {
if (locals_.has(name)) {
return nullptr;
}
@ -2642,7 +2633,7 @@ class MOZ_STACK_CLASS FunctionValidator : public FunctionValidatorShared {
// asm.js type-checking and code-generation algorithm
static bool CheckIdentifier(ModuleValidatorShared& m, ParseNode* usepn,
const ParserName* name) {
PropertyName* name) {
if (name == m.cx()->parserNames().arguments ||
name == m.cx()->parserNames().eval) {
return m.failName(usepn, "'%s' is not an allowed identifier", name);
@ -2651,7 +2642,7 @@ static bool CheckIdentifier(ModuleValidatorShared& m, ParseNode* usepn,
}
static bool CheckModuleLevelName(ModuleValidatorShared& m, ParseNode* usepn,
const ParserName* name) {
PropertyName* name) {
if (!CheckIdentifier(m, usepn, name)) {
return false;
}
@ -2679,14 +2670,15 @@ static bool CheckFunctionHead(ModuleValidatorShared& m, FunctionNode* funNode) {
}
static bool CheckArgument(ModuleValidatorShared& m, ParseNode* arg,
const ParserName** name) {
PropertyName** name) {
*name = nullptr;
if (!arg->isKind(ParseNodeKind::Name)) {
return m.fail(arg, "argument is not a plain name");
}
const ParserName* argName = arg->as<NameNode>().name();
PropertyName* argName = arg->as<NameNode>().name();
;
if (!CheckIdentifier(m, arg, argName)) {
return false;
}
@ -2696,7 +2688,7 @@ static bool CheckArgument(ModuleValidatorShared& m, ParseNode* arg,
}
static bool CheckModuleArgument(ModuleValidatorShared& m, ParseNode* arg,
const ParserName** name) {
PropertyName** name) {
if (!CheckArgument(m, arg, name)) {
return false;
}
@ -2719,7 +2711,7 @@ static bool CheckModuleArguments(ModuleValidatorShared& m,
return m.fail(funNode, "asm.js modules takes at most 3 argument");
}
const ParserName* arg1Name = nullptr;
PropertyName* arg1Name = nullptr;
if (arg1 && !CheckModuleArgument(m, arg1, &arg1Name)) {
return false;
}
@ -2727,7 +2719,7 @@ static bool CheckModuleArguments(ModuleValidatorShared& m,
return false;
}
const ParserName* arg2Name = nullptr;
PropertyName* arg2Name = nullptr;
if (arg2 && !CheckModuleArgument(m, arg2, &arg2Name)) {
return false;
}
@ -2735,7 +2727,7 @@ static bool CheckModuleArguments(ModuleValidatorShared& m,
return false;
}
const ParserName* arg3Name = nullptr;
PropertyName* arg3Name = nullptr;
if (arg3 && !CheckModuleArgument(m, arg3, &arg3Name)) {
return false;
}
@ -2761,7 +2753,7 @@ static bool CheckPrecedingStatements(ModuleValidatorShared& m,
}
static bool CheckGlobalVariableInitConstant(ModuleValidatorShared& m,
const ParserName* varName,
PropertyName* varName,
ParseNode* initNode, bool isConst) {
NumLit lit = ExtractNumericLiteral(m, initNode);
if (!lit.valid()) {
@ -2813,7 +2805,7 @@ static bool CheckTypeAnnotation(ModuleValidatorShared& m,
}
static bool CheckGlobalVariableInitImport(ModuleValidatorShared& m,
const ParserName* varName,
PropertyName* varName,
ParseNode* initNode, bool isConst) {
Type coerceTo;
ParseNode* coercedExpr;
@ -2831,9 +2823,9 @@ static bool CheckGlobalVariableInitImport(ModuleValidatorShared& m,
}
ParseNode* base = DotBase(coercedExpr);
const ParserName* field = DotMember(coercedExpr);
PropertyName* field = DotMember(coercedExpr);
const ParserName* importName = m.importArgumentName();
PropertyName* importName = m.importArgumentName();
if (!importName) {
return m.fail(coercedExpr,
"cannot import without an asm.js foreign parameter");
@ -2846,9 +2838,9 @@ static bool CheckGlobalVariableInitImport(ModuleValidatorShared& m,
return m.addGlobalVarImport(varName, field, coerceTo, isConst);
}
static bool IsArrayViewCtorName(ModuleValidatorShared& m,
const ParserName* name, Scalar::Type* type) {
js::frontend::WellKnownParserAtoms& names = m.cx()->parserNames();
static bool IsArrayViewCtorName(ModuleValidatorShared& m, PropertyName* name,
Scalar::Type* type) {
JSAtomState& names = m.cx()->parserNames();
if (name == names.Int8Array) {
*type = Scalar::Int8;
} else if (name == names.Uint8Array) {
@ -2872,7 +2864,7 @@ static bool IsArrayViewCtorName(ModuleValidatorShared& m,
}
static bool CheckNewArrayViewArgs(ModuleValidatorShared& m, ParseNode* newExpr,
const ParserName* bufferName) {
PropertyName* bufferName) {
ParseNode* ctorExpr = BinaryLeft(newExpr);
ParseNode* ctorArgs = BinaryRight(newExpr);
ParseNode* bufArg = ListHead(ctorArgs);
@ -2889,15 +2881,15 @@ static bool CheckNewArrayViewArgs(ModuleValidatorShared& m, ParseNode* newExpr,
return true;
}
static bool CheckNewArrayView(ModuleValidatorShared& m,
const ParserName* varName, ParseNode* newExpr) {
const ParserName* globalName = m.globalArgumentName();
static bool CheckNewArrayView(ModuleValidatorShared& m, PropertyName* varName,
ParseNode* newExpr) {
PropertyName* globalName = m.globalArgumentName();
if (!globalName) {
return m.fail(
newExpr, "cannot create array view without an asm.js global parameter");
}
const ParserName* bufferName = m.bufferArgumentName();
PropertyName* bufferName = m.bufferArgumentName();
if (!bufferName) {
return m.fail(newExpr,
"cannot create array view without an asm.js heap parameter");
@ -2905,7 +2897,7 @@ static bool CheckNewArrayView(ModuleValidatorShared& m,
ParseNode* ctorExpr = BinaryLeft(newExpr);
const ParserName* field;
PropertyName* field;
Scalar::Type type;
if (ctorExpr->isKind(ParseNodeKind::DotExpr)) {
ParseNode* base = DotBase(ctorExpr);
@ -2924,7 +2916,7 @@ static bool CheckNewArrayView(ModuleValidatorShared& m,
"expecting name of imported array view constructor");
}
const ParserName* globalName = ctorExpr->as<NameNode>().name();
PropertyName* globalName = ctorExpr->as<NameNode>().name();
const ModuleValidatorShared::Global* global = m.lookupGlobal(globalName);
if (!global) {
return m.failName(ctorExpr, "%s not found in module global scope",
@ -2949,8 +2941,7 @@ static bool CheckNewArrayView(ModuleValidatorShared& m,
}
static bool CheckGlobalMathImport(ModuleValidatorShared& m, ParseNode* initNode,
const ParserName* varName,
const ParserName* field) {
PropertyName* varName, PropertyName* field) {
// Math builtin, with the form glob.Math.[[builtin]]
ModuleValidatorShared::MathBuiltin mathBuiltin;
if (!m.lookupStandardLibraryMathName(field, &mathBuiltin)) {
@ -2969,16 +2960,15 @@ static bool CheckGlobalMathImport(ModuleValidatorShared& m, ParseNode* initNode,
}
static bool CheckGlobalDotImport(ModuleValidatorShared& m,
const ParserName* varName,
ParseNode* initNode) {
PropertyName* varName, ParseNode* initNode) {
ParseNode* base = DotBase(initNode);
const ParserName* field = DotMember(initNode);
PropertyName* field = DotMember(initNode);
if (base->isKind(ParseNodeKind::DotExpr)) {
ParseNode* global = DotBase(base);
const ParserName* math = DotMember(base);
PropertyName* math = DotMember(base);
const ParserName* globalName = m.globalArgumentName();
PropertyName* globalName = m.globalArgumentName();
if (!globalName) {
return m.fail(
base, "import statement requires the module have a stdlib parameter");
@ -3042,7 +3032,7 @@ static bool CheckModuleGlobal(ModuleValidatorShared& m, ParseNode* decl,
return m.fail(var, "import variable is not a plain name");
}
const ParserName* varName = var->as<NameNode>().name();
PropertyName* varName = var->as<NameNode>().name();
if (!CheckModuleLevelName(m, var, varName)) {
return false;
}
@ -3119,7 +3109,7 @@ static bool CheckModuleGlobals(ModuleValidator<Unit>& m) {
return true;
}
static bool ArgFail(FunctionValidatorShared& f, const ParserName* argName,
static bool ArgFail(FunctionValidatorShared& f, PropertyName* argName,
ParseNode* stmt) {
return f.failName(stmt,
"expecting argument type declaration for '%s' of the "
@ -3128,7 +3118,7 @@ static bool ArgFail(FunctionValidatorShared& f, const ParserName* argName,
}
static bool CheckArgumentType(FunctionValidatorShared& f, ParseNode* stmt,
const ParserName* name, Type* type) {
PropertyName* name, Type* type) {
if (!stmt || !IsExpressionStatement(stmt)) {
return ArgFail(f, name, stmt ? stmt : f.fn());
}
@ -3182,7 +3172,7 @@ static bool CheckArguments(FunctionValidatorShared& f, ParseNode** stmtIter,
for (unsigned i = 0; i < numFormals;
i++, argpn = NextNode(argpn), stmt = NextNode(stmt)) {
const ParserName* name = nullptr;
PropertyName* name;
if (!CheckArgument(f.m(), argpn, &name)) {
return false;
}
@ -3262,7 +3252,7 @@ static bool CheckVariable(FunctionValidatorShared& f, ParseNode* decl,
return f.fail(var, "local variable is not a plain name");
}
const ParserName* name = var->as<NameNode>().name();
PropertyName* name = var->as<NameNode>().name();
if (!CheckIdentifier(f.m(), var, name)) {
return false;
@ -3345,7 +3335,7 @@ static bool CheckNumericLiteral(FunctionValidator<Unit>& f, ParseNode* num,
static bool CheckVarRef(FunctionValidatorShared& f, ParseNode* varRef,
Type* type) {
const ParserName* name = varRef->as<NameNode>().name();
PropertyName* name = varRef->as<NameNode>().name();
if (const FunctionValidatorShared::Local* local = f.lookupLocal(name)) {
if (!f.encoder().writeOp(Op::GetLocal)) {
@ -3661,7 +3651,7 @@ static bool CheckStoreArray(FunctionValidator<Unit>& f, ParseNode* lhs,
template <typename Unit>
static bool CheckAssignName(FunctionValidator<Unit>& f, ParseNode* lhs,
ParseNode* rhs, Type* type) {
const ParserName* name = lhs->as<NameNode>().name();
RootedPropertyName name(f.cx(), lhs->as<NameNode>().name());
if (const FunctionValidatorShared::Local* lhsVar = f.lookupLocal(name)) {
Type rhsType;
@ -3943,7 +3933,7 @@ static bool CheckSignatureAgainstExisting(ModuleValidatorShared& m,
template <typename Unit>
static bool CheckFunctionSignature(ModuleValidator<Unit>& m, ParseNode* usepn,
FuncType&& sig, const ParserName* name,
FuncType&& sig, PropertyName* name,
ModuleValidatorShared::Func** func) {
if (sig.args().length() > MaxParams) {
return m.failf(usepn, "too many parameters");
@ -3979,8 +3969,7 @@ static bool CheckIsArgType(FunctionValidatorShared& f, ParseNode* argNode,
template <typename Unit>
static bool CheckInternalCall(FunctionValidator<Unit>& f, ParseNode* callNode,
const ParserName* calleeName, Type ret,
Type* type) {
PropertyName* calleeName, Type ret, Type* type) {
MOZ_ASSERT(ret.isCanonical());
ValTypeVector args;
@ -4017,8 +4006,8 @@ static bool CheckInternalCall(FunctionValidator<Unit>& f, ParseNode* callNode,
template <typename Unit>
static bool CheckFuncPtrTableAgainstExisting(ModuleValidator<Unit>& m,
ParseNode* usepn,
const ParserName* name,
FuncType&& sig, unsigned mask,
PropertyName* name, FuncType&& sig,
unsigned mask,
uint32_t* tableIndex) {
if (const ModuleValidatorShared::Global* existing = m.lookupGlobal(name)) {
if (existing->which() != ModuleValidatorShared::Global::Table) {
@ -4065,7 +4054,7 @@ static bool CheckFuncPtrCall(FunctionValidator<Unit>& f, ParseNode* callNode,
return f.fail(tableNode, "expecting name of function-pointer array");
}
const ParserName* name = tableNode->as<NameNode>().name();
PropertyName* name = tableNode->as<NameNode>().name();
if (const ModuleValidatorShared::Global* existing = f.lookupGlobal(name)) {
if (existing->which() != ModuleValidatorShared::Global::Table) {
return f.failName(
@ -4144,7 +4133,7 @@ static bool CheckFFICall(FunctionValidator<Unit>& f, ParseNode* callNode,
unsigned ffiIndex, Type ret, Type* type) {
MOZ_ASSERT(ret.isCanonical());
const ParserName* calleeName = CallCallee(callNode)->as<NameNode>().name();
PropertyName* calleeName = CallCallee(callNode)->as<NameNode>().name();
if (ret.isFloat()) {
return f.fail(callNode, "FFI calls can't return float");
@ -4511,7 +4500,7 @@ static bool CheckCoercedCall(FunctionValidator<Unit>& f, ParseNode* call,
return f.fail(callee, "unexpected callee expression type");
}
const ParserName* calleeName = callee->as<NameNode>().name();
PropertyName* calleeName = callee->as<NameNode>().name();
if (const ModuleValidatorShared::Global* global =
f.lookupGlobal(calleeName)) {
@ -5939,7 +5928,7 @@ static bool CheckLexicalScope(FunctionValidator<Unit>& f, ParseNode* node) {
static bool CheckBreakOrContinue(FunctionValidatorShared& f, bool isBreak,
ParseNode* stmt) {
if (const ParserName* maybeLabel = LoopControlMaybeLabel(stmt)) {
if (PropertyName* maybeLabel = LoopControlMaybeLabel(stmt)) {
return f.writeLabeledBreakOrContinue(maybeLabel, isBreak);
}
return f.writeUnlabeledBreakOrContinue(isBreak);
@ -6008,7 +5997,7 @@ static bool ParseFunction(ModuleValidator<Unit>& m, FunctionNode** funNodeOut,
// m.fail.
}
const ParserName* name = m.parser().bindingIdentifier(YieldIsName);
RootedPropertyName name(m.cx(), m.parser().bindingIdentifier(YieldIsName));
if (!name) {
return false;
}
@ -6196,7 +6185,7 @@ static bool CheckFuncPtrTable(ModuleValidator<Unit>& m, ParseNode* decl) {
elem, "function-pointer table's elements must be names of functions");
}
const ParserName* funcName = elem->as<NameNode>().name();
PropertyName* funcName = elem->as<NameNode>().name();
const ModuleValidatorShared::Func* func = m.lookupFuncDef(funcName);
if (!func) {
return m.fail(
@ -6264,14 +6253,13 @@ static bool CheckFuncPtrTables(ModuleValidator<Unit>& m) {
return true;
}
static bool CheckModuleExportFunction(
ModuleValidatorShared& m, ParseNode* pn,
const ParserName* maybeFieldName = nullptr) {
static bool CheckModuleExportFunction(ModuleValidatorShared& m, ParseNode* pn,
PropertyName* maybeFieldName = nullptr) {
if (!pn->isKind(ParseNodeKind::Name)) {
return m.fail(pn, "expected name of exported function");
}
const ParserName* funcName = pn->as<NameNode>().name();
PropertyName* funcName = pn->as<NameNode>().name();
const ModuleValidatorShared::Func* func = m.lookupFuncDef(funcName);
if (!func) {
return m.failName(pn, "function '%s' not found", funcName);
@ -6291,7 +6279,7 @@ static bool CheckModuleExportObject(ModuleValidatorShared& m,
"object literal");
}
const ParserName* fieldName = ObjectNormalFieldName(pn);
PropertyName* fieldName = ObjectNormalFieldName(pn);
ParseNode* initNode = ObjectNormalFieldInitializer(pn);
if (!initNode->isKind(ParseNodeKind::Name)) {
@ -6363,14 +6351,13 @@ static bool CheckModuleEnd(ModuleValidator<Unit>& m) {
}
template <typename Unit>
static SharedModule CheckModule(JSContext* cx, CompilationInfo& compilationInfo,
AsmJSParser<Unit>& parser, ParseNode* stmtList,
unsigned* time) {
static SharedModule CheckModule(JSContext* cx, AsmJSParser<Unit>& parser,
ParseNode* stmtList, unsigned* time) {
int64_t before = PRMJ_Now();
FunctionNode* moduleFunctionNode = parser.pc_->functionBox()->functionNode;
ModuleValidator<Unit> m(cx, compilationInfo, parser, moduleFunctionNode);
ModuleValidator<Unit> m(cx, parser, moduleFunctionNode);
if (!m.init()) {
return nullptr;
}
@ -7058,9 +7045,8 @@ static bool EstablishPreconditions(JSContext* cx,
}
template <typename Unit>
static bool DoCompileAsmJS(JSContext* cx, CompilationInfo& compilationInfo,
AsmJSParser<Unit>& parser, ParseNode* stmtList,
bool* validated) {
static bool DoCompileAsmJS(JSContext* cx, AsmJSParser<Unit>& parser,
ParseNode* stmtList, bool* validated) {
*validated = false;
// Various conditions disable asm.js optimizations.
@ -7071,8 +7057,7 @@ static bool DoCompileAsmJS(JSContext* cx, CompilationInfo& compilationInfo,
// "Checking" parses, validates and compiles, producing a fully compiled
// WasmModuleObject as result.
unsigned time;
SharedModule module =
CheckModule(cx, compilationInfo, parser, stmtList, &time);
SharedModule module = CheckModule(cx, parser, stmtList, &time);
if (!module) {
return NoExceptionPending(cx);
}
@ -7092,16 +7077,14 @@ static bool DoCompileAsmJS(JSContext* cx, CompilationInfo& compilationInfo,
return NoExceptionPending(cx);
}
bool js::CompileAsmJS(JSContext* cx, CompilationInfo& compilationInfo,
AsmJSParser<char16_t>& parser, ParseNode* stmtList,
bool* validated) {
return DoCompileAsmJS(cx, compilationInfo, parser, stmtList, validated);
bool js::CompileAsmJS(JSContext* cx, AsmJSParser<char16_t>& parser,
ParseNode* stmtList, bool* validated) {
return DoCompileAsmJS(cx, parser, stmtList, validated);
}
bool js::CompileAsmJS(JSContext* cx, CompilationInfo& compilationInfo,
AsmJSParser<Utf8Unit>& parser, ParseNode* stmtList,
bool* validated) {
return DoCompileAsmJS(cx, compilationInfo, parser, stmtList, validated);
bool js::CompileAsmJS(JSContext* cx, AsmJSParser<Utf8Unit>& parser,
ParseNode* stmtList, bool* validated) {
return DoCompileAsmJS(cx, parser, stmtList, validated);
}
/*****************************************************************************/

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

@ -43,8 +43,6 @@ namespace js {
namespace frontend {
struct CompilationInfo;
class ParseContext;
class ParseNode;
@ -64,14 +62,14 @@ using AsmJSParser = frontend::Parser<frontend::FullParseHandler, Unit>;
// indeterminate amount and the entire function should be reparsed from the
// beginning.
extern MOZ_MUST_USE bool CompileAsmJS(
JSContext* cx, frontend::CompilationInfo& compilationInfo,
AsmJSParser<mozilla::Utf8Unit>& parser, frontend::ParseNode* stmtList,
extern MOZ_MUST_USE bool CompileAsmJS(JSContext* cx,
AsmJSParser<mozilla::Utf8Unit>& parser,
frontend::ParseNode* stmtList,
bool* validated);
extern MOZ_MUST_USE bool CompileAsmJS(
JSContext* cx, frontend::CompilationInfo& compilationInfo,
AsmJSParser<char16_t>& parser, frontend::ParseNode* stmtList,
extern MOZ_MUST_USE bool CompileAsmJS(JSContext* cx,
AsmJSParser<char16_t>& parser,
frontend::ParseNode* stmtList,
bool* validated);
// asm.js module/export queries: