Skip to content

Commit

Permalink
Bug 1670044 - Part 8: Use null for star-imports and exports. r=yulia,…
Browse files Browse the repository at this point in the history
…tcampbell

The "Arbitrary module namespace identifier names" spec PR allows to use "*" as
a module export name, so we can no longer use that specific string to denote
star-imports/exports. Probably the easiest way to work around this new
restriction is to replace "*" with a nullptr string.

Spec change: tc39/ecma262#2155

Differential Revision: https://phabricator.services.mozilla.com/D101013
  • Loading branch information
anba committed Feb 9, 2021
1 parent 12e83c9 commit a1657af
Show file tree
Hide file tree
Showing 15 changed files with 128 additions and 152 deletions.
6 changes: 4 additions & 2 deletions js/src/builtin/Module.js
Expand Up @@ -101,6 +101,8 @@ function ModuleSetStatus(module, newStatus)
//
function ModuleResolveExport(exportName, resolveSet = [])
{
assert(typeof exportName === "string", "ModuleResolveExport");

if (!IsObject(this) || !IsModule(this)) {
return callFunction(CallModuleMethodIfWrapped, this, exportName, resolveSet,
"ModuleResolveExport");
Expand Down Expand Up @@ -136,7 +138,7 @@ function ModuleResolveExport(exportName, resolveSet = [])
if (exportName === e.exportName) {
let importedModule = CallModuleResolveHook(module, e.moduleRequest,
MODULE_STATUS_UNLINKED);
if (e.importName === "*") {
if (e.importName === null) {
return {module: importedModule, bindingName: "*namespace*"};
}
return callFunction(importedModule.resolveExport, importedModule, e.importName,
Expand Down Expand Up @@ -476,7 +478,7 @@ function InitializeEnvironment()
let importedModule = CallModuleResolveHook(module, imp.moduleRequest,
MODULE_STATUS_LINKING);
// Step 9.c-9.d
if (imp.importName === "*") {
if (imp.importName === null) {
let namespace = GetModuleNamespace(importedModule);
CreateNamespaceBinding(env, imp.localName, namespace);
} else {
Expand Down
96 changes: 49 additions & 47 deletions js/src/builtin/ModuleObject.cpp
Expand Up @@ -86,6 +86,10 @@ static bool ModuleValueGetter(JSContext* cx, unsigned argc, Value* vp) {
return JS::ToUint32(value.toDouble()); \
}

static Value StringOrNullValue(JSString* maybeString) {
return maybeString ? StringValue(maybeString) : NullValue();
}

///////////////////////////////////////////////////////////////////////////
// ImportEntryObject

Expand All @@ -99,7 +103,7 @@ DEFINE_GETTER_FUNCTIONS(ImportEntryObject, lineNumber, LineNumberSlot)
DEFINE_GETTER_FUNCTIONS(ImportEntryObject, columnNumber, ColumnNumberSlot)

DEFINE_ATOM_ACCESSOR_METHOD(ImportEntryObject, moduleRequest)
DEFINE_ATOM_ACCESSOR_METHOD(ImportEntryObject, importName)
DEFINE_ATOM_OR_NULL_ACCESSOR_METHOD(ImportEntryObject, importName)
DEFINE_ATOM_ACCESSOR_METHOD(ImportEntryObject, localName)
DEFINE_UINT32_ACCESSOR_METHOD(ImportEntryObject, lineNumber)
DEFINE_UINT32_ACCESSOR_METHOD(ImportEntryObject, columnNumber)
Expand Down Expand Up @@ -136,7 +140,7 @@ bool GlobalObject::initImportEntryProto(JSContext* cx,

/* static */
ImportEntryObject* ImportEntryObject::create(
JSContext* cx, HandleAtom moduleRequest, HandleAtom importName,
JSContext* cx, HandleAtom moduleRequest, HandleAtom maybeImportName,
HandleAtom localName, uint32_t lineNumber, uint32_t columnNumber) {
RootedObject proto(
cx, GlobalObject::getOrCreateImportEntryPrototype(cx, cx->global()));
Expand All @@ -151,7 +155,7 @@ ImportEntryObject* ImportEntryObject::create(
}

self->initReservedSlot(ModuleRequestSlot, StringValue(moduleRequest));
self->initReservedSlot(ImportNameSlot, StringValue(importName));
self->initReservedSlot(ImportNameSlot, StringOrNullValue(maybeImportName));
self->initReservedSlot(LocalNameSlot, StringValue(localName));
self->initReservedSlot(LineNumberSlot, NumberValue(lineNumber));
self->initReservedSlot(ColumnNumberSlot, NumberValue(columnNumber));
Expand Down Expand Up @@ -209,10 +213,6 @@ bool GlobalObject::initExportEntryProto(JSContext* cx,
return true;
}

static Value StringOrNullValue(JSString* maybeString) {
return maybeString ? StringValue(maybeString) : NullValue();
}

/* static */
ExportEntryObject* ExportEntryObject::create(
JSContext* cx, HandleAtom maybeExportName, HandleAtom maybeModuleRequest,
Expand Down Expand Up @@ -1343,8 +1343,7 @@ bool ModuleBuilder::buildTables(frontend::StencilModuleMetadata& metadata) {
return false;
}
} else {
if (importEntry->importName ==
frontend::TaggedParserAtomIndex::WellKnown::star()) {
if (!importEntry->importName) {
if (!metadata.localExportEntries.append(exp)) {
js::ReportOutOfMemory(cx_);
return false;
Expand All @@ -1360,9 +1359,7 @@ bool ModuleBuilder::buildTables(frontend::StencilModuleMetadata& metadata) {
}
}
}
} else if (exp.importName ==
frontend::TaggedParserAtomIndex::WellKnown::star() &&
!exp.exportName) {
} else if (!exp.importName && !exp.exportName) {
if (!metadata.starExportEntries.append(exp)) {
js::ReportOutOfMemory(cx_);
return false;
Expand Down Expand Up @@ -1413,31 +1410,38 @@ static ArrayObject* ModuleBuilderInitArray(
if (entry.specifier) {
specifier = atomCache.getExistingAtomAt(cx, entry.specifier);
MOZ_ASSERT(specifier);
} else {
MOZ_ASSERT(!specifier);
}

if (entry.localName) {
localName = atomCache.getExistingAtomAt(cx, entry.localName);
MOZ_ASSERT(localName);
} else {
MOZ_ASSERT(!localName);
}

if (entry.importName) {
importName = atomCache.getExistingAtomAt(cx, entry.importName);
MOZ_ASSERT(importName);
} else {
importName = nullptr;
}

if (entry.exportName) {
exportName = atomCache.getExistingAtomAt(cx, entry.exportName);
MOZ_ASSERT(exportName);
} else {
MOZ_ASSERT(!exportName);
}

switch (arrayType) {
case ModuleArrayType::ImportEntryObject:
MOZ_ASSERT(localName && importName);
MOZ_ASSERT(localName);
req = ImportEntryObject::create(cx, specifier, importName, localName,
entry.lineno, entry.column);
break;
case ModuleArrayType::ExportEntryObject:
MOZ_ASSERT(localName || importName || exportName);
req = ExportEntryObject::create(cx, exportName, specifier, importName,
localName, entry.lineno, entry.column);
break;
Expand Down Expand Up @@ -1532,10 +1536,10 @@ bool ModuleBuilder::processImport(frontend::BinaryNode* importNode) {

MOZ_ASSERT(importNode->isKind(ParseNodeKind::ImportDecl));

ListNode* specList = &importNode->left()->as<ListNode>();
auto* specList = &importNode->left()->as<ListNode>();
MOZ_ASSERT(specList->isKind(ParseNodeKind::ImportSpecList));

NameNode* moduleSpec = &importNode->right()->as<NameNode>();
auto* moduleSpec = &importNode->right()->as<NameNode>();
MOZ_ASSERT(moduleSpec->isKind(ParseNodeKind::StringExpr));

auto module = moduleSpec->atom();
Expand All @@ -1544,34 +1548,39 @@ bool ModuleBuilder::processImport(frontend::BinaryNode* importNode) {
}

for (ParseNode* item : specList->contents()) {
BinaryNode* spec = &item->as<BinaryNode>();
MOZ_ASSERT(spec->isKind(ParseNodeKind::ImportSpec) ||
spec->isKind(ParseNodeKind::ImportNamespaceSpec));

NameNode* importNameNode = &spec->left()->as<NameNode>();
NameNode* localNameNode = &spec->right()->as<NameNode>();

auto importName = importNameNode->atom();
auto localName = localNameNode->atom();

uint32_t line;
uint32_t column;
eitherParser_.computeLineAndColumn(importNameNode->pn_pos.begin, &line,
&column);

markUsedByStencil(module);
markUsedByStencil(localName);
markUsedByStencil(importName);
eitherParser_.computeLineAndColumn(item->pn_pos.begin, &line, &column);

StencilModuleEntry entry;
if (spec->isKind(ParseNodeKind::ImportSpec)) {
TaggedParserAtomIndex localName;
if (item->isKind(ParseNodeKind::ImportSpec)) {
auto* spec = &item->as<BinaryNode>();

auto* importNameNode = &spec->left()->as<NameNode>();
auto* localNameNode = &spec->right()->as<NameNode>();

auto importName = importNameNode->atom();
localName = localNameNode->atom();

markUsedByStencil(module);
markUsedByStencil(localName);
markUsedByStencil(importName);
entry = StencilModuleEntry::importEntry(module, localName, importName,
line, column);
} else {
entry = StencilModuleEntry::importNamespaceEntry(
module, localName, importName, line, column);
}
MOZ_ASSERT(item->isKind(ParseNodeKind::ImportNamespaceSpec));
auto* spec = &item->as<UnaryNode>();

auto* localNameNode = &spec->kid()->as<NameNode>();

localName = localNameNode->atom();

markUsedByStencil(module);
markUsedByStencil(localName);
entry = StencilModuleEntry::importNamespaceEntry(module, localName, line,
column);
}
if (!importEntries_.put(localName, entry)) {
return false;
}
Expand Down Expand Up @@ -1791,26 +1800,19 @@ bool ModuleBuilder::processExportFrom(frontend::BinaryNode* exportNode) {
entry = StencilModuleEntry::exportFromEntry(module, importName,
exportName, line, column);
} else if (spec->isKind(ParseNodeKind::ExportNamespaceSpec)) {
auto* importNameNode = &spec->as<BinaryNode>().left()->as<NameNode>();
auto* exportNameNode = &spec->as<BinaryNode>().right()->as<NameNode>();
auto* exportNameNode = &spec->as<UnaryNode>().kid()->as<NameNode>();

auto importName = importNameNode->atom();
exportName = exportNameNode->atom();

markUsedByStencil(module);
markUsedByStencil(importName);
markUsedByStencil(exportName);
entry = StencilModuleEntry::exportNamespaceFromEntry(
module, importName, exportName, line, column);
entry = StencilModuleEntry::exportNamespaceFromEntry(module, exportName,
line, column);
} else {
MOZ_ASSERT(spec->isKind(ParseNodeKind::ExportBatchSpecStmt));

auto importName = TaggedParserAtomIndex::WellKnown::star();

markUsedByStencil(module);
markUsedByStencil(importName);
entry = StencilModuleEntry::exportBatchFromEntry(module, importName, line,
column);
entry = StencilModuleEntry::exportBatchFromEntry(module, line, column);
}

if (!exportEntries_.append(entry)) {
Expand Down
5 changes: 3 additions & 2 deletions js/src/builtin/ModuleObject.h
Expand Up @@ -68,8 +68,9 @@ class ImportEntryObject : public NativeObject {
static const JSClass class_;
static bool isInstance(HandleValue value);
static ImportEntryObject* create(JSContext* cx, HandleAtom moduleRequest,
HandleAtom importName, HandleAtom localName,
uint32_t lineNumber, uint32_t columnNumber);
HandleAtom maybeImportName,
HandleAtom localName, uint32_t lineNumber,
uint32_t columnNumber);
JSAtom* moduleRequest() const;
JSAtom* importName() const;
JSAtom* localName() const;
Expand Down

0 comments on commit a1657af

Please sign in to comment.