blob: 393779c44c34bad72e9189c9cf4d9e3b62043c81 [file] [log] [blame]
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// 15.2.1.16.2 GetExportedNames(exportStarSet)
function ModuleGetExportedNames(exportStarSet = [])
{
if (!IsObject(this) || !IsModule(this)) {
return callFunction(CallModuleMethodIfWrapped, this, exportStarSet,
"ModuleGetExportedNames");
}
// Step 1
let module = this;
// Step 2
if (callFunction(ArrayIncludes, exportStarSet, module))
return [];
// Step 3
_DefineDataProperty(exportStarSet, exportStarSet.length, module);
// Step 4
let exportedNames = [];
let namesCount = 0;
// Step 5
let localExportEntries = module.localExportEntries;
for (let i = 0; i < localExportEntries.length; i++) {
let e = localExportEntries[i];
_DefineDataProperty(exportedNames, namesCount++, e.exportName);
}
// Step 6
let indirectExportEntries = module.indirectExportEntries;
for (let i = 0; i < indirectExportEntries.length; i++) {
let e = indirectExportEntries[i];
_DefineDataProperty(exportedNames, namesCount++, e.exportName);
}
// Step 7
let starExportEntries = module.starExportEntries;
for (let i = 0; i < starExportEntries.length; i++) {
let e = starExportEntries[i];
let requestedModule = HostResolveImportedModule(module, e.moduleRequest);
let starNames = callFunction(requestedModule.getExportedNames, requestedModule,
exportStarSet);
for (let j = 0; j < starNames.length; j++) {
let n = starNames[j];
if (n !== "default" && !callFunction(ArrayIncludes, exportedNames, n))
_DefineDataProperty(exportedNames, namesCount++, n);
}
}
return exportedNames;
}
// 15.2.1.16.3 ResolveExport(exportName, resolveSet, exportStarSet)
function ModuleResolveExport(exportName, resolveSet = [], exportStarSet = [])
{
if (!IsObject(this) || !IsModule(this)) {
return callFunction(CallModuleMethodIfWrapped, this, exportName, resolveSet,
exportStarSet, "ModuleResolveExport");
}
// Step 1
let module = this;
// Step 2
for (let i = 0; i < resolveSet.length; i++) {
let r = resolveSet[i];
if (r.module === module && r.exportName === exportName)
return null;
}
// Step 3
_DefineDataProperty(resolveSet, resolveSet.length, {module: module, exportName: exportName});
// Step 4
let localExportEntries = module.localExportEntries;
for (let i = 0; i < localExportEntries.length; i++) {
let e = localExportEntries[i];
if (exportName === e.exportName)
return {module: module, bindingName: e.localName};
}
// Step 5
let indirectExportEntries = module.indirectExportEntries;
for (let i = 0; i < indirectExportEntries.length; i++) {
let e = indirectExportEntries[i];
if (exportName === e.exportName) {
let importedModule = HostResolveImportedModule(module, e.moduleRequest);
let indirectResolution = callFunction(importedModule.resolveExport, importedModule,
e.importName, resolveSet, exportStarSet);
if (indirectResolution !== null)
return indirectResolution;
}
}
// Step 6
if (exportName === "default") {
// A default export cannot be provided by an export *.
ThrowSyntaxError(JSMSG_BAD_DEFAULT_EXPORT);
}
// Step 7
if (callFunction(ArrayIncludes, exportStarSet, module))
return null;
// Step 8
_DefineDataProperty(exportStarSet, exportStarSet.length, module);
// Step 9
let starResolution = null;
// Step 10
let starExportEntries = module.starExportEntries;
for (let i = 0; i < starExportEntries.length; i++) {
let e = starExportEntries[i];
let importedModule = HostResolveImportedModule(module, e.moduleRequest);
let resolution = callFunction(importedModule.resolveExport, importedModule,
exportName, resolveSet, exportStarSet);
if (resolution === "ambiguous")
return resolution;
if (resolution !== null) {
if (starResolution === null) {
starResolution = resolution;
} else {
if (resolution.module !== starResolution.module ||
resolution.exportName !== starResolution.exportName)
{
return "ambiguous";
}
}
}
}
return starResolution;
}
// 15.2.1.18 GetModuleNamespace(module)
function GetModuleNamespace(module)
{
// Step 2
let namespace = module.namespace;
// Step 3
if (typeof namespace === "undefined") {
let exportedNames = callFunction(module.getExportedNames, module);
let unambiguousNames = [];
for (let i = 0; i < exportedNames.length; i++) {
let name = exportedNames[i];
let resolution = callFunction(module.resolveExport, module, name);
if (resolution === null)
ThrowSyntaxError(JSMSG_MISSING_NAMESPACE_EXPORT);
if (resolution !== "ambiguous")
_DefineDataProperty(unambiguousNames, unambiguousNames.length, name);
}
namespace = ModuleNamespaceCreate(module, unambiguousNames);
}
// Step 4
return namespace;
}
// 9.4.6.13 ModuleNamespaceCreate(module, exports)
function ModuleNamespaceCreate(module, exports)
{
callFunction(std_Array_sort, exports);
let ns = NewModuleNamespace(module, exports);
// Pre-compute all bindings now rather than calling ResolveExport() on every
// access.
for (let i = 0; i < exports.length; i++) {
let name = exports[i];
let binding = callFunction(module.resolveExport, module, name);
assert(binding !== null && binding !== "ambiguous", "Failed to resolve binding");
AddModuleNamespaceBinding(ns, name, binding.module, binding.bindingName);
}
return ns;
}
// 15.2.1.16.4 ModuleDeclarationInstantiation()
function ModuleDeclarationInstantiation()
{
if (!IsObject(this) || !IsModule(this))
return callFunction(CallModuleMethodIfWrapped, this, "ModuleDeclarationInstantiation");
// Step 1
let module = this;
// Step 5
if (GetModuleEnvironment(module) !== undefined)
return;
// Step 7
CreateModuleEnvironment(module);
let env = GetModuleEnvironment(module);
// Step 8
let requestedModules = module.requestedModules;
for (let i = 0; i < requestedModules.length; i++) {
let required = requestedModules[i];
let requiredModule = HostResolveImportedModule(module, required);
callFunction(requiredModule.declarationInstantiation, requiredModule);
}
// Step 9
let indirectExportEntries = module.indirectExportEntries;
for (let i = 0; i < indirectExportEntries.length; i++) {
let e = indirectExportEntries[i];
let resolution = callFunction(module.resolveExport, module, e.exportName);
if (resolution === null)
ThrowSyntaxError(JSMSG_MISSING_INDIRECT_EXPORT, e.exportName);
if (resolution === "ambiguous")
ThrowSyntaxError(JSMSG_AMBIGUOUS_INDIRECT_EXPORT, e.exportName);
}
// Step 12
let importEntries = module.importEntries;
for (let i = 0; i < importEntries.length; i++) {
let imp = importEntries[i];
let importedModule = HostResolveImportedModule(module, imp.moduleRequest);
if (imp.importName === "*") {
let namespace = GetModuleNamespace(importedModule);
CreateNamespaceBinding(env, imp.localName, namespace);
} else {
let resolution = callFunction(importedModule.resolveExport, importedModule,
imp.importName);
if (resolution === null)
ThrowSyntaxError(JSMSG_MISSING_IMPORT, imp.importName);
if (resolution === "ambiguous")
ThrowSyntaxError(JSMSG_AMBIGUOUS_IMPORT, imp.importName);
CreateImportBinding(env, imp.localName, resolution.module, resolution.bindingName);
}
}
// Step 16.iv
InstantiateModuleFunctionDeclarations(module);
}
// 15.2.1.16.5 ModuleEvaluation()
function ModuleEvaluation()
{
if (!IsObject(this) || !IsModule(this))
return callFunction(CallModuleMethodIfWrapped, this, "ModuleEvaluation");
// Step 1
let module = this;
// Step 4
if (module.evaluated)
return undefined;
// Step 5
SetModuleEvaluated(this);
// Step 6
let requestedModules = module.requestedModules;
for (let i = 0; i < requestedModules.length; i++) {
let required = requestedModules[i];
let requiredModule = HostResolveImportedModule(module, required);
callFunction(requiredModule.evaluation, requiredModule);
}
return EvaluateModule(module);
}
function ModuleNamespaceEnumerate()
{
if (!IsObject(this) || !IsModuleNamespace(this))
return callFunction(CallModuleMethodIfWrapped, this, "ModuleNamespaceEnumerate");
return CreateListIterator(ModuleNamespaceExports(this));
}