mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 23:50:19 +00:00
LibJS: No longer assume there is a cycle root when module failed before
This issue could be triggered by evaluating a module twice. If it failed during evaluation the cycle root was never set but that status is evaluated. This failed in step 3 of Evaluate which assumes it has a cycle root. This is a spec issue see: https://github.com/tc39/ecma262/issues/2823 To fix this we check if the module itself has a top level capability first before going to the cycle root. Co-authored-by: Jamie Mansfield <jmansfield@cadixdev.org>
This commit is contained in:
parent
d87676de8a
commit
1dc9769f7d
Notes:
sideshowbarker
2024-07-17 04:00:45 +09:00
Author: https://github.com/davidot Commit: https://github.com/SerenityOS/serenity/commit/1dc9769f7d Pull-request: https://github.com/SerenityOS/serenity/pull/16217 Reviewed-by: https://github.com/linusg
1 changed files with 10 additions and 1 deletions
|
@ -191,10 +191,19 @@ ThrowCompletionOr<Promise*> CyclicModule::evaluate(VM& vm)
|
|||
// 2. Assert: module.[[Status]] is linked, evaluating-async, or evaluated.
|
||||
VERIFY(m_status == ModuleStatus::Linked || m_status == ModuleStatus::EvaluatingAsync || m_status == ModuleStatus::Evaluated);
|
||||
|
||||
// NOTE: The spec does not catch the case where evaluate is called twice on a script which failed
|
||||
// during evaluation. This means the script is evaluated but does not have a cycle root.
|
||||
// In that case we first check if this module itself has a top level capability.
|
||||
// See also: https://github.com/tc39/ecma262/issues/2823 .
|
||||
if (m_top_level_capability != nullptr)
|
||||
return verify_cast<Promise>(m_top_level_capability->promise().ptr());
|
||||
|
||||
// 3. If module.[[Status]] is evaluating-async or evaluated, set module to module.[[CycleRoot]].
|
||||
if (m_status == ModuleStatus::EvaluatingAsync || m_status == ModuleStatus::Evaluated) {
|
||||
// Note: This will continue this function with module.[[CycleRoot]]
|
||||
VERIFY(m_cycle_root && m_cycle_root->m_status == ModuleStatus::Linked && this != m_cycle_root);
|
||||
VERIFY(m_cycle_root);
|
||||
VERIFY(this != m_cycle_root);
|
||||
VERIFY(m_cycle_root->m_status == ModuleStatus::Linked);
|
||||
dbgln_if(JS_MODULE_DEBUG, "[JS MODULE] evaluate[{}](vm) deferring to cycle root at {}", this, m_cycle_root);
|
||||
return m_cycle_root->evaluate(vm);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue