blob: 0d5e3be3176cb9e5a5fbe3b5e9daee4d3c29587a [file] [log] [blame]
// Copyright 2016 The Chromium 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 THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCRIPT_ITERATOR_H_
#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCRIPT_ITERATOR_H_
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "v8/include/v8.h"
namespace blink {
class ExceptionState;
class ExecutionContext;
// This class provides a wrapper for iterating over any ES object that
// implements the iterable and iterator protocols. Namely:
// * The object or an object in its prototype chain has an @@iterator property
// that is a function that returns an iterator object.
// * The iterator object has a next() method that returns an object with at
// least two properties:
// 1. done: A boolean indicating whether iteration should stop. Can be
// omitted when false.
// 2. value: Any object. Can be omitted when |done| is true.
//
// In general, this class should be preferred over using the
// GetEsIteratorMethod() and GetEsIteratorWithMethod() functions directly.
//
// Usage:
// v8::Local<v8::Object> es_object = ...;
// auto script_iterator = ScriptIterator::FromIterable(
// isolate, es_object, exception_state,
// ScriptIterator::ConversionFailureMode::kDoNotThrowTypeError);
// if (exception_state.HadException())
// return;
// if (!script_iterator.IsNull()) {
// while (script_iterator.Next(execution_context, exception_state)) {
// // V8 may have thrown an exception.
// if (exception_state.HadException())
// return;
// v8::Local<v8::Value> value =
// script_iterator.GetValue().ToLocalChecked();
// // Do something with |value|.
// }
// }
// // If the very first call to Next() throws, the loop above will not be
// // entered, so we need to catch any exceptions here.
// if (exception_state.HadException())
// return;
class CORE_EXPORT ScriptIterator {
STACK_ALLOCATED();
public:
// Creates a ScriptIterator out of an ES object that implements the iterable
// and iterator protocols.
// Both the return value and the ExceptionState should be checked:
// - The ExceptionState will contain an exception if V8 throws one, or if the
// ES objects do not conform to the expected protocols. In this case, the
// returned ScriptIterator will be null.
// - ScriptIterator can be null even if there is no exception. In this case,
// it indicates that the given ES object does not have an @@iterator
// property.
static ScriptIterator FromIterable(v8::Isolate*,
v8::Local<v8::Object>,
ExceptionState&);
// Constructs a ScriptIterator from an ES object that implements the iterator
// protocol: |iterator| is supposed to have a next() method that returns an
// object with two properties, "done" and "value".
ScriptIterator(v8::Isolate*, v8::Local<v8::Object> iterator);
ScriptIterator() = default;
ScriptIterator(ScriptIterator&&) noexcept = default;
ScriptIterator& operator=(ScriptIterator&&) noexcept = default;
ScriptIterator(const ScriptIterator&) = delete;
ScriptIterator& operator=(const ScriptIterator&) = delete;
bool IsNull() const { return iterator_.IsEmpty(); }
// Returns true if the iterator is still not done.
bool Next(ExecutionContext*,
ExceptionState&,
v8::Local<v8::Value> next_value = v8::Local<v8::Value>());
v8::MaybeLocal<v8::Value> GetValue() { return value_; }
private:
v8::Isolate* isolate_ = nullptr;
v8::Local<v8::Object> iterator_;
v8::Local<v8::String> next_key_;
v8::Local<v8::String> done_key_;
v8::Local<v8::String> value_key_;
bool done_ = true;
v8::MaybeLocal<v8::Value> value_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCRIPT_ITERATOR_H_