blob: 048a509ab48c4185aea369decb92553206ae1702 [file]
// Copyright 2023 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_OBJECTS_JS_ITERATOR_HELPERS_H_
#define V8_OBJECTS_JS_ITERATOR_HELPERS_H_
#include "src/objects/js-objects.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
namespace v8 {
namespace internal {
class Boolean;
enum class JSIteratorHelperState {
kSuspendedStart,
kSuspendedYield,
kExecuting,
kCompleted
};
enum class JSIteratorZipHelperMode { kShortest, kLongest, kStrict };
V8_EXPORT_PRIVATE const char* JSIteratorHelperStateToString(
JSIteratorHelperState state);
V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
JSIteratorHelperState state);
V8_EXPORT_PRIVATE const char* JSIteratorZipHelperModeToString(
JSIteratorZipHelperMode mode);
V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
JSIteratorZipHelperMode mode);
// Iterator helpers are iterators that transform an underlying iterator in some
// way. They are specified as spec generators. That is, the spec defines the
// body of iterator helpers using algorithm steps with yields (like JS
// generators) packaged in an Abstract Closure, and then makes a generator
// object internally. Generator machinery such as GeneratorResume [1] are then
// used to specify %IteratorHelperPrototype%.{next,return}. While this aids
// understandability of the specification, it is not conducive to ease of
// implementation or performance in V8.
//
// Instead, each iterator helper is implemented as an iterator directly, with
// JSIteratorHelper acting as a superclass to multiplex the various kinds of
// helpers.
//
// Each helper has its own Torque class to hold the state it needs. (In the
// spec, the state is captured in the Abstract Closures.) The classes are named
// after the name of the method that produces them. E.g., the iterator helper
// returned by Iterator.prototype.map is named JSIteratorMapHelper, and has
// fields for the underlying iterator, the mapper function, and a counter.
//
// The algorithm steps in the body Abstract Closure in the specification is
// implemented directly as next() (and return(), if necessary) builtin
// methods. E.g., the map helper's body is implemented as
// Builtin::kIteratorMapHelperNext.
//
// All iterator helper objects have %IteratorHelperPrototype% as their
// [[Prototype]]. The implementations of %IteratorHelperPrototype%.{next,return}
// multiplex, typeswitching over all known iterator helpers and manually calling
// their next() (and return(), if necessary) builtins. E.g., Calling next() on
// JSIteratorMapHelper would ultimately call Builtin::kIteratorMapHelperNext.
//
// [1] https://tc39.es/ecma262/#sec-generatorresume
// The superclass of all iterator helpers.
V8_OBJECT class JSIteratorHelper : public JSObject {
V8_IT_ABSTRACT;
public:
inline JSIteratorHelperState state() const;
inline void set_state(JSIteratorHelperState value);
void JSIteratorHelperPrintHeader(std::ostream& os, const char* helper_name);
DECL_VERIFIER(JSIteratorHelper)
public:
// SmiTagged<JSIteratorHelperState>.
TaggedMember<Smi> state_;
} V8_OBJECT_END;
// The superclass of iterator helpers that have a single underlying iterator.
V8_OBJECT class JSIteratorHelperSimple : public JSIteratorHelper {
V8_IT_ABSTRACT;
public:
inline Tagged<JSReceiver> underlying_iterator_object() const;
inline void set_underlying_iterator_object(
Tagged<JSReceiver> value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
inline Tagged<JSAny> underlying_iterator_next() const;
inline void set_underlying_iterator_next(
Tagged<JSAny> value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
void JSIteratorHelperSimplePrintHeader(std::ostream& os,
const char* helper_name);
DECL_VERIFIER(JSIteratorHelperSimple)
public:
TaggedMember<JSReceiver> underlying_iterator_object_;
TaggedMember<JSAny> underlying_iterator_next_;
} V8_OBJECT_END;
// The iterator helper returned by Iterator.prototype.map.
V8_OBJECT class JSIteratorMapHelper final : public JSIteratorHelperSimple {
public:
inline Tagged<JSReceiver> mapper() const;
inline void set_mapper(Tagged<JSReceiver> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
inline Tagged<Number> counter() const;
inline void set_counter(Tagged<Number> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
DECL_PRINTER(JSIteratorMapHelper)
DECL_VERIFIER(JSIteratorMapHelper)
public:
TaggedMember<JSReceiver> mapper_;
TaggedMember<Number> counter_;
} V8_OBJECT_END;
// The iterator helper returned by Iterator.prototype.filter.
V8_OBJECT class JSIteratorFilterHelper final : public JSIteratorHelperSimple {
public:
inline Tagged<JSReceiver> predicate() const;
inline void set_predicate(Tagged<JSReceiver> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
inline Tagged<Number> counter() const;
inline void set_counter(Tagged<Number> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
DECL_PRINTER(JSIteratorFilterHelper)
DECL_VERIFIER(JSIteratorFilterHelper)
public:
TaggedMember<JSReceiver> predicate_;
TaggedMember<Number> counter_;
} V8_OBJECT_END;
// The iterator helper returned by Iterator.prototype.take.
V8_OBJECT class JSIteratorTakeHelper final : public JSIteratorHelperSimple {
public:
inline Tagged<Number> remaining() const;
inline void set_remaining(Tagged<Number> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
DECL_PRINTER(JSIteratorTakeHelper)
DECL_VERIFIER(JSIteratorTakeHelper)
public:
TaggedMember<Number> remaining_;
} V8_OBJECT_END;
// The iterator helper returned by Iterator.prototype.drop.
V8_OBJECT class JSIteratorDropHelper final : public JSIteratorHelperSimple {
public:
inline Tagged<Number> remaining() const;
inline void set_remaining(Tagged<Number> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
DECL_PRINTER(JSIteratorDropHelper)
DECL_VERIFIER(JSIteratorDropHelper)
public:
TaggedMember<Number> remaining_;
} V8_OBJECT_END;
// The iterator helper returned by Iterator.prototype.flatMap.
V8_OBJECT class JSIteratorFlatMapHelper final : public JSIteratorHelperSimple {
public:
inline Tagged<JSReceiver> mapper() const;
inline void set_mapper(Tagged<JSReceiver> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
inline Tagged<Number> counter() const;
inline void set_counter(Tagged<Number> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
inline Tagged<JSReceiver> inner_iterator_object() const;
inline void set_inner_iterator_object(
Tagged<JSReceiver> value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
inline Tagged<JSAny> inner_iterator_next() const;
inline void set_inner_iterator_next(
Tagged<JSAny> value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
DECL_PRINTER(JSIteratorFlatMapHelper)
DECL_VERIFIER(JSIteratorFlatMapHelper)
public:
TaggedMember<JSReceiver> mapper_;
TaggedMember<Number> counter_;
TaggedMember<JSReceiver> inner_iterator_object_;
TaggedMember<JSAny> inner_iterator_next_;
} V8_OBJECT_END;
// The iterator helper returned by Iterator.concat.
V8_OBJECT class JSIteratorConcatHelper final : public JSIteratorHelperSimple {
public:
inline Tagged<FixedArray> iterables() const;
inline void set_iterables(Tagged<FixedArray> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
inline Tagged<Smi> current() const;
inline void set_current(Tagged<Smi> value);
DECL_PRINTER(JSIteratorConcatHelper)
DECL_VERIFIER(JSIteratorConcatHelper)
public:
TaggedMember<FixedArray> iterables_;
TaggedMember<Smi> current_;
} V8_OBJECT_END;
// The iterator helper returned by Iterator.zip and Iterator.zipKeyed.
V8_OBJECT class JSIteratorZipHelper : public JSIteratorHelper {
V8_IT_OWN_TYPE;
public:
inline Tagged<FixedArray> underlying_iterators() const;
inline void set_underlying_iterators(
Tagged<FixedArray> value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
inline JSIteratorZipHelperMode mode() const;
inline void set_mode(JSIteratorZipHelperMode value);
inline Tagged<Smi> active_count() const;
inline void set_active_count(Tagged<Smi> value);
inline Tagged<FixedArray> padding() const;
inline void set_padding(Tagged<FixedArray> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
void JSIteratorZipHelperPrintHeader(std::ostream& os,
const char* helper_name);
DECL_PRINTER(JSIteratorZipHelper)
DECL_VERIFIER(JSIteratorZipHelper)
public:
TaggedMember<FixedArray> underlying_iterators_;
// SmiTagged<JSIteratorZipHelperMode>.
TaggedMember<Smi> mode_;
TaggedMember<Smi> active_count_;
TaggedMember<FixedArray> padding_;
} V8_OBJECT_END;
V8_OBJECT class JSIteratorZipKeyedHelper final : public JSIteratorZipHelper {
public:
inline Tagged<FixedArray> keys() const;
inline void set_keys(Tagged<FixedArray> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
DECL_PRINTER(JSIteratorZipKeyedHelper)
DECL_VERIFIER(JSIteratorZipKeyedHelper)
public:
TaggedMember<FixedArray> keys_;
} V8_OBJECT_END;
} // namespace internal
} // namespace v8
#include "src/objects/object-macros-undef.h"
#endif // V8_OBJECTS_JS_ITERATOR_HELPERS_H_