Преглед изворни кода

LibJS: Have AsyncFunctionDriverWrapper unwrap promises before returning

24 new passes on test262. :^)
Andreas Kling пре 2 година
родитељ
комит
1dc7f03137
1 измењених фајлова са 17 додато и 3 уклоњено
  1. 17 3
      Userland/Libraries/LibJS/Runtime/AsyncFunctionDriverWrapper.cpp

+ 17 - 3
Userland/Libraries/LibJS/Runtime/AsyncFunctionDriverWrapper.cpp

@@ -72,12 +72,26 @@ void AsyncFunctionDriverWrapper::continue_async_execution(VM& vm, Value value, b
             auto promise_value = TRY(result.get(vm, vm.names.value));
             auto promise_value = TRY(result.get(vm, vm.names.value));
 
 
             if (TRY(result.get(vm, vm.names.done)).to_boolean()) {
             if (TRY(result.get(vm, vm.names.done)).to_boolean()) {
-                // We hit a `return value;`
-                m_top_level_promise->fulfill(promise_value);
 
 
-                // We should not execute anymore, so we are safe to allow our selfs to be GC'd
+                // We should not execute anymore, so we are safe to allow ourselves to be GC'd.
                 m_self_handle = {};
                 m_self_handle = {};
 
 
+                // When returning a promise, we need to unwrap it.
+                if (promise_value.is_object() && is<Promise>(promise_value.as_object())) {
+                    auto& returned_promise = static_cast<Promise&>(promise_value.as_object());
+                    if (returned_promise.state() == Promise::State::Fulfilled) {
+                        m_top_level_promise->fulfill(returned_promise.result());
+                        return {};
+                    }
+                    if (returned_promise.state() == Promise::State::Rejected)
+                        return throw_completion(returned_promise.result());
+
+                    // The promise is still pending but there's nothing more to do here.
+                    return {};
+                }
+
+                // We hit a `return value;`
+                m_top_level_promise->fulfill(promise_value);
                 return {};
                 return {};
             }
             }