LibJS: Allow constructing generator from function with null "prototype"

Fixes 4 test262 tests and simplifies some upcoming stuff.
This commit is contained in:
Andreas Kling 2025-11-17 10:23:56 +01:00 committed by Andreas Kling
parent acce880359
commit d8f5971ddf
Notes: github-actions[bot] 2025-11-17 22:44:21 +00:00
5 changed files with 13 additions and 9 deletions

View file

@ -24,15 +24,17 @@ ThrowCompletionOr<GC::Ref<AsyncGenerator>> AsyncGenerator::create(Realm& realm,
// This is "g1.prototype" in figure-2 (https://tc39.es/ecma262/img/figure-2.png)
static Bytecode::PropertyLookupCache cache;
auto generating_function_prototype = TRY(generating_function->get(vm.names.prototype, cache));
auto generating_function_prototype_object = TRY(generating_function_prototype.to_object(vm));
GC::Ptr<Object> generating_function_prototype_object = nullptr;
if (!generating_function_prototype.is_nullish())
generating_function_prototype_object = MUST(generating_function_prototype.to_object(vm));
auto object = realm.create<AsyncGenerator>(realm, generating_function_prototype_object, move(execution_context));
object->m_generating_function = generating_function;
object->m_previous_value = initial_value;
return object;
}
AsyncGenerator::AsyncGenerator(Realm&, Object& prototype, NonnullOwnPtr<ExecutionContext> context)
: Object(ConstructWithPrototypeTag::Tag, prototype)
AsyncGenerator::AsyncGenerator(Realm& realm, Object* prototype, NonnullOwnPtr<ExecutionContext> context)
: Object(realm, prototype)
, m_async_generator_context(move(context))
{
}

View file

@ -44,7 +44,7 @@ public:
Optional<String> const& generator_brand() const { return m_generator_brand; }
private:
AsyncGenerator(Realm&, Object& prototype, NonnullOwnPtr<ExecutionContext>);
AsyncGenerator(Realm&, Object* prototype, NonnullOwnPtr<ExecutionContext>);
virtual void visit_edges(Cell::Visitor&) override;

View file

@ -32,15 +32,17 @@ ThrowCompletionOr<GC::Ref<GeneratorObject>> GeneratorObject::create(Realm& realm
static Bytecode::PropertyLookupCache cache;
generating_function_prototype = TRY(generating_function->get(vm.names.prototype, cache));
}
auto generating_function_prototype_object = TRY(generating_function_prototype.to_object(vm));
GC::Ptr<Object> generating_function_prototype_object = nullptr;
if (!generating_function_prototype.is_nullish())
generating_function_prototype_object = MUST(generating_function_prototype.to_object(vm));
auto object = realm.create<GeneratorObject>(realm, generating_function_prototype_object, move(execution_context));
object->m_generating_function = generating_function;
object->m_previous_value = initial_value;
return object;
}
GeneratorObject::GeneratorObject(Realm&, Object& prototype, NonnullOwnPtr<ExecutionContext> context, Optional<StringView> generator_brand)
: Object(ConstructWithPrototypeTag::Tag, prototype)
GeneratorObject::GeneratorObject(Realm& realm, Object* prototype, NonnullOwnPtr<ExecutionContext> context, Optional<StringView> generator_brand)
: Object(realm, prototype)
, m_execution_context(move(context))
, m_generator_brand(move(generator_brand))
{

View file

@ -46,7 +46,7 @@ public:
void set_generator_state(GeneratorState generator_state) { m_generator_state = generator_state; }
protected:
GeneratorObject(Realm&, Object& prototype, NonnullOwnPtr<ExecutionContext>, Optional<StringView> generator_brand = {});
GeneratorObject(Realm&, Object* prototype, NonnullOwnPtr<ExecutionContext>, Optional<StringView> generator_brand = {});
ThrowCompletionOr<GeneratorState> validate(VM&, Optional<StringView> const& generator_brand);
virtual ThrowCompletionOr<IterationResult> execute(VM&, JS::Completion const& completion);

View file

@ -19,7 +19,7 @@ ThrowCompletionOr<GC::Ref<IteratorHelper>> IteratorHelper::create(Realm& realm,
}
IteratorHelper::IteratorHelper(Realm& realm, Object& prototype, GC::Ref<IteratorRecord> underlying_iterator, GC::Ref<Closure> closure, GC::Ptr<AbruptClosure> abrupt_closure)
: GeneratorObject(realm, prototype, realm.vm().running_execution_context().copy(), "Iterator Helper"sv)
: GeneratorObject(realm, &prototype, realm.vm().running_execution_context().copy(), "Iterator Helper"sv)
, m_underlying_iterator(move(underlying_iterator))
, m_closure(closure)
, m_abrupt_closure(abrupt_closure)