1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 09:58:11 +00:00

LibJS: Add support for async functions

This commit adds support for the most bare bones version of async
functions, support for async generator functions, async arrow functions
and await expressions are TODO.
This commit is contained in:
Idan Horowitz 2021-11-09 20:39:22 +02:00 committed by Linus Groh
parent 05c3320da3
commit 681787de76
17 changed files with 399 additions and 36 deletions

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibJS/Interpreter.h>
#include <LibJS/Runtime/AsyncFunctionConstructor.h>
#include <LibJS/Runtime/ECMAScriptFunctionObject.h>
#include <LibJS/Runtime/FunctionConstructor.h>
#include <LibJS/Runtime/FunctionObject.h>
#include <LibJS/Runtime/GlobalObject.h>
namespace JS {
AsyncFunctionConstructor::AsyncFunctionConstructor(GlobalObject& global_object)
: NativeFunction(vm().names.AsyncFunction.as_string(), *global_object.function_prototype())
{
}
void AsyncFunctionConstructor::initialize(GlobalObject& global_object)
{
auto& vm = this->vm();
NativeFunction::initialize(global_object);
// 27.7.2.2 AsyncFunction.prototype, https://tc39.es/ecma262/#sec-async-function-constructor-prototype
define_direct_property(vm.names.prototype, global_object.async_function_prototype(), 0);
define_direct_property(vm.names.length, Value(1), Attribute::Configurable);
}
// 27.7.1.1 AsyncFunction ( p1, p2, … , pn, body ), https://tc39.es/ecma262/#sec-async-function-constructor-arguments
ThrowCompletionOr<Value> AsyncFunctionConstructor::call()
{
return TRY(construct(*this));
}
// 27.7.1.1 AsyncFunction ( p1, p2, … , pn, body ), https://tc39.es/ecma262/#sec-async-function-constructor-arguments
ThrowCompletionOr<Object*> AsyncFunctionConstructor::construct(FunctionObject& new_target)
{
auto& vm = this->vm();
auto function = TRY(FunctionConstructor::create_dynamic_function_node(global_object(), new_target, FunctionKind::Async));
OwnPtr<Interpreter> local_interpreter;
Interpreter* interpreter = vm.interpreter_if_exists();
if (!interpreter) {
local_interpreter = Interpreter::create_with_existing_realm(*realm());
interpreter = local_interpreter.ptr();
}
VM::InterpreterExecutionScope scope(*interpreter);
auto result = function->execute(*interpreter, global_object());
if (auto* exception = vm.exception())
return throw_completion(exception->value());
VERIFY(result.is_object() && is<ECMAScriptFunctionObject>(result.as_object()));
return &result.as_object();
}
}