diff --git a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp index 2a638dc0bf..3c4ae45323 100644 --- a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp @@ -101,10 +101,11 @@ void ECMAScriptFunctionObject::initialize(GlobalObject& global_object) MUST(prototype->define_property_or_throw(vm.names.constructor, { .value = this, .writable = true, .enumerable = false, .configurable = true })); break; case FunctionKind::Generator: - case FunctionKind::Async: // prototype is "g1.prototype" in figure-2 (https://tc39.es/ecma262/img/figure-2.png) prototype = global_object.generator_object_prototype(); break; + case FunctionKind::Async: + break; } define_direct_property(vm.names.prototype, prototype, Attribute::Writable); } diff --git a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h index 0868ebc55b..21ea05bc59 100644 --- a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h +++ b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h @@ -75,6 +75,8 @@ public: // Equivalent to absence of [[Construct]] virtual bool has_constructor() const override { return m_kind == FunctionKind::Regular && !m_is_arrow_function; } + FunctionKind kind() const { return m_kind; } + protected: virtual bool is_strict_mode() const final { return m_strict; } diff --git a/Userland/Libraries/LibJS/Runtime/GeneratorObject.cpp b/Userland/Libraries/LibJS/Runtime/GeneratorObject.cpp index e145f9422c..7f37c6d084 100644 --- a/Userland/Libraries/LibJS/Runtime/GeneratorObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/GeneratorObject.cpp @@ -16,7 +16,15 @@ namespace JS { ThrowCompletionOr GeneratorObject::create(GlobalObject& global_object, Value initial_value, ECMAScriptFunctionObject* generating_function, ExecutionContext execution_context, Bytecode::RegisterWindow frame) { // This is "g1.prototype" in figure-2 (https://tc39.es/ecma262/img/figure-2.png) - auto generating_function_prototype = TRY(generating_function->get(global_object.vm().names.prototype)); + Value generating_function_prototype; + if (generating_function->kind() == FunctionKind::Async) { + // We implement async functions by transforming them to generator function in the bytecode + // interpreter. However an async function does not have a prototype and should not be + // changed thus we hardcode the prototype. + generating_function_prototype = global_object.generator_object_prototype(); + } else { + generating_function_prototype = TRY(generating_function->get(global_object.vm().names.prototype)); + } auto* generating_function_prototype_object = TRY(generating_function_prototype.to_object(global_object)); auto object = global_object.heap().allocate(global_object, global_object, *generating_function_prototype_object, move(execution_context)); object->m_generating_function = generating_function;