Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion Source/JavaScriptCore/aot/passes/AOTCallModules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -780,6 +780,10 @@ void callModules(ProgramEditor& editor, const FlowResults& flow, BuildContext& b
Vector<ModuleID> moduleWithBody(program.functions.size());
bool loadsTwoGraphsAtOnce = mayLoadTwoGraphsAtOnce(program, loops);
bool somebodyAsksWhoRequiredWhom = asksWhoRequiredWhom(program, flow);
// Code that the build has not compiled calls import() with the name of one of these while a require() evaluates it. The module order of flow knows the same names.
BitVector isNamedByUnseenCode(modules.size());
if (flow.unseenCodeCanRun())
isNamedByUnseenCode = modulesThatUnseenCodeNames(program, flow.findsFilesOfProgramByName(), build.options().admitsUnseenCode());
for (size_t index = 0; index < modules.size(); ++index) {
const Module& module = modules[index];
if (!isEvaluatedWithImporter(program, module) || needsLoader.quickGet(index))
Expand All @@ -790,7 +794,9 @@ void callModules(ProgramEditor& editor, const FlowResults& flow, BuildContext& b
// A file that the loader has asked for has no parent, and the run time knows which of several files it has asked for.
bool loaderIsSeenToAsk = somebodyAsksWhoRequiredWhom && module.requests.size() > 1 && module.requests[1].isHoisted;
bool isListedFromRequireOn = module.kind == ModuleKind::SourceText && module.flags.contains(ModuleFlags::IsListedInCache);
if (!needsLink.quickGet(index) && isRequiredBetweenLoads && !loaderIsSeenToAsk && !isListedFromRequireOn)
// The run time settles the promise of an import() of a module that a require() still evaluates where that evaluation ends: Modules::evaluateWithOwnStack(). A start that is called has no such end.
bool isImportedWhileRequired = module.kind == ModuleKind::SourceText && isNamedByUnseenCode.quickGet(index);
if (!needsLink.quickGet(index) && isRequiredBetweenLoads && !loaderIsSeenToAsk && !isListedFromRequireOn && !isImportedWhileRequired)
plan.isCalledWhereRequired.quickSet(index);
if (!hasCode(program, module))
continue;
Expand Down
5 changes: 4 additions & 1 deletion Source/JavaScriptCore/aot/runtime/AOTModuleEvaluation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2731,10 +2731,13 @@ void Modules::evaluateWithOwnStack(ModuleID root)
Exception* exception = scope.exception();
ASSERT(exception || stack.isEmpty());
// An import() of the root that was called while the root ran has given it a capability, which CyclicModuleRecord::evaluate() would settle here.
ModuleRecord* record = recordIfExists(root);
// The table has the status of a root that compiled code began and of a root without a body, so recordIfExists() does not find the record that the import() made: that record takes the status now.
ModuleRecord* record = m_records.get(root);
JSPromise* capability = record ? record->topLevelCapability() : nullptr;
if (capability && capability->status() != JSPromise::Status::Pending)
capability = nullptr;
if (capability) [[unlikely]]
record->takeStatus();
if (!exception) {
if (capability) [[unlikely]]
capability->fulfill(vm, jsUndefined());
Expand Down
Loading
Loading