Bug 1788882 - Check module status on entry to JS::ModuleLink API r=yulia

Checks the module status unconditionally and throws an error if it is not as
expected.

This now includes the unexpected status in the error to help debugging and bug
reported.

Differential Revision: https://phabricator.services.mozilla.com/D156293
This commit is contained in:
Jon Coppeard 2022-09-05 09:43:09 +00:00
Родитель 80f20bf0da
Коммит 654ee53dc9
2 изменённых файлов: 37 добавлений и 10 удалений

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

@ -691,7 +691,7 @@ MSG_DEF(JSMSG_AMBIGUOUS_INDIRECT_EXPORT, 0, JSEXN_SYNTAXERR, "ambiguous indirect
MSG_DEF(JSMSG_MISSING_IMPORT, 0, JSEXN_SYNTAXERR, "import not found")
MSG_DEF(JSMSG_AMBIGUOUS_IMPORT, 0, JSEXN_SYNTAXERR, "ambiguous import")
MSG_DEF(JSMSG_MISSING_EXPORT, 1, JSEXN_SYNTAXERR, "local binding for export '{0}' not found")
MSG_DEF(JSMSG_BAD_MODULE_STATUS, 0, JSEXN_INTERNALERR, "module record has unexpected status")
MSG_DEF(JSMSG_BAD_MODULE_STATUS, 1, JSEXN_INTERNALERR, "module record has unexpected status: {0}")
MSG_DEF(JSMSG_DYNAMIC_IMPORT_FAILED, 0, JSEXN_TYPEERR, "error loading dynamically imported module")
// Import maps

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

@ -331,6 +331,25 @@ static bool GatherAvailableModuleAncestors(
JSContext* cx, Handle<ModuleObject*> module,
MutableHandle<ModuleVector> execList);
static const char* ModuleStatusName(ModuleStatus status) {
switch (status) {
case ModuleStatus::Unlinked:
return "Unlinked";
case ModuleStatus::Linking:
return "Linking";
case ModuleStatus::Linked:
return "Linked";
case ModuleStatus::Evaluating:
return "Evaluating";
case ModuleStatus::EvaluatingAsync:
return "EvaluatingAsync";
case ModuleStatus::Evaluated:
return "Evaluated";
default:
MOZ_CRASH("Unexpected ModuleStatus");
}
}
static ArrayObject* NewList(JSContext* cx) {
// Note that this creates an ArrayObject, not a ListObject (see vm/List.h).
// Self hosted code currently depends on the length property being present.
@ -484,7 +503,8 @@ static ModuleObject* HostResolveImportedModule(
if (requestedModule->status() < expectedMinimumStatus) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_BAD_MODULE_STATUS);
JSMSG_BAD_MODULE_STATUS,
ModuleStatusName(requestedModule->status()));
return nullptr;
}
@ -1047,8 +1067,13 @@ bool js::ModuleInitializeEnvironment(JSContext* cx,
// ES2023 16.2.1.5.1 Link
bool js::ModuleLink(JSContext* cx, Handle<ModuleObject*> module) {
// Step 1. Assert: module.[[Status]] is not linking or evaluating.
MOZ_ASSERT(module->status() != ModuleStatus::Linking &&
module->status() != ModuleStatus::Evaluating);
ModuleStatus status = module->status();
if (status == ModuleStatus::Linking || status == ModuleStatus::Evaluating) {
JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
JSMSG_BAD_MODULE_STATUS,
ModuleStatusName(status));
return false;
}
// Step 2. Let stack be a new empty List.
Rooted<ModuleVector> stack(cx);
@ -1106,8 +1131,9 @@ static bool InnerModuleLinking(JSContext* cx, Handle<ModuleObject*> module,
// Step 3. Assert: module.[[Status]] is unlinked.
if (module->status() != ModuleStatus::Unlinked) {
JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
JSMSG_BAD_MODULE_STATUS);
JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
JSMSG_BAD_MODULE_STATUS,
ModuleStatusName(module->status()));
return false;
}
@ -1222,11 +1248,12 @@ bool js::ModuleEvaluate(JSContext* cx, Handle<ModuleObject*> moduleArg,
// Step 2. Assert: module.[[Status]] is linked, evaluating-async, or
// evaluated.
if (module->status() != ModuleStatus::Linked &&
module->status() != ModuleStatus::EvaluatingAsync &&
module->status() != ModuleStatus::Evaluated) {
ModuleStatus status = module->status();
if (status != ModuleStatus::Linked &&
status != ModuleStatus::EvaluatingAsync &&
status != ModuleStatus::Evaluated) {
JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
JSMSG_BAD_MODULE_STATUS);
JSMSG_BAD_MODULE_STATUS, ModuleStatusName(status));
return false;
}