| Index: src/wasm/ast-decoder.h | 
| diff --git a/src/wasm/ast-decoder.h b/src/wasm/ast-decoder.h | 
| index dfdc377f76ae7e64cfee1a8842679f3c48ac634f..4911de3802b030c67743a51193c5d73a44d20240 100644 | 
| --- a/src/wasm/ast-decoder.h | 
| +++ b/src/wasm/ast-decoder.h | 
| @@ -5,7 +5,10 @@ | 
| #ifndef V8_WASM_AST_DECODER_H_ | 
| #define V8_WASM_AST_DECODER_H_ | 
|  | 
| +#include <iterator> | 
| + | 
| #include "src/base/compiler-specific.h" | 
| +#include "src/base/iterator.h" | 
| #include "src/globals.h" | 
| #include "src/signature.h" | 
| #include "src/wasm/decoder.h" | 
| @@ -382,31 +385,59 @@ V8_EXPORT_PRIVATE unsigned OpcodeLength(const byte* pc, const byte* end); | 
|  | 
| // A simple forward iterator for bytecodes. | 
| class V8_EXPORT_PRIVATE BytecodeIterator : public NON_EXPORTED_BASE(Decoder) { | 
| - public: | 
| -  // If one wants to iterate over the bytecode without looking at {pc_offset()}. | 
| -  class iterator { | 
| +  // Base class for both iterators defined below. | 
| +  class iterator_base { | 
| public: | 
| -    inline iterator& operator++() { | 
| +    inline iterator_base& operator++() { | 
| DCHECK_LT(ptr_, end_); | 
| ptr_ += OpcodeLength(ptr_, end_); | 
| return *this; | 
| } | 
| +    inline bool operator==(const iterator_base& that) { | 
| +      return this->ptr_ == that.ptr_; | 
| +    } | 
| +    inline bool operator!=(const iterator_base& that) { | 
| +      return this->ptr_ != that.ptr_; | 
| +    } | 
| + | 
| +   protected: | 
| +    const byte* ptr_; | 
| +    const byte* end_; | 
| +    iterator_base(const byte* ptr, const byte* end) : ptr_(ptr), end_(end) {} | 
| +  }; | 
| + | 
| + public: | 
| +  // If one wants to iterate over the bytecode without looking at {pc_offset()}. | 
| +  class opcode_iterator | 
| +      : public iterator_base, | 
| +        public std::iterator<std::input_iterator_tag, WasmOpcode> { | 
| +   public: | 
| inline WasmOpcode operator*() { | 
| DCHECK_LT(ptr_, end_); | 
| return static_cast<WasmOpcode>(*ptr_); | 
| } | 
| -    inline bool operator==(const iterator& that) { | 
| -      return this->ptr_ == that.ptr_; | 
| -    } | 
| -    inline bool operator!=(const iterator& that) { | 
| -      return this->ptr_ != that.ptr_; | 
| + | 
| +   private: | 
| +    friend class BytecodeIterator; | 
| +    opcode_iterator(const byte* ptr, const byte* end) | 
| +        : iterator_base(ptr, end) {} | 
| +  }; | 
| +  // If one wants to iterate over the instruction offsets without looking at | 
| +  // opcodes. | 
| +  class offset_iterator | 
| +      : public iterator_base, | 
| +        public std::iterator<std::input_iterator_tag, uint32_t> { | 
| +   public: | 
| +    inline uint32_t operator*() { | 
| +      DCHECK_LT(ptr_, end_); | 
| +      return static_cast<uint32_t>(ptr_ - start_); | 
| } | 
|  | 
| private: | 
| +    const byte* start_; | 
| friend class BytecodeIterator; | 
| -    const byte* ptr_; | 
| -    const byte* end_; | 
| -    iterator(const byte* ptr, const byte* end) : ptr_(ptr), end_(end) {} | 
| +    offset_iterator(const byte* start, const byte* ptr, const byte* end) | 
| +        : iterator_base(ptr, end), start_(start) {} | 
| }; | 
|  | 
| // Create a new {BytecodeIterator}. If the {decls} pointer is non-null, | 
| @@ -415,8 +446,16 @@ class V8_EXPORT_PRIVATE BytecodeIterator : public NON_EXPORTED_BASE(Decoder) { | 
| BytecodeIterator(const byte* start, const byte* end, | 
| AstLocalDecls* decls = nullptr); | 
|  | 
| -  inline iterator begin() const { return iterator(pc_, end_); } | 
| -  inline iterator end() const { return iterator(end_, end_); } | 
| +  base::iterator_range<opcode_iterator> opcodes() { | 
| +    return base::iterator_range<opcode_iterator>(opcode_iterator(pc_, end_), | 
| +                                                 opcode_iterator(end_, end_)); | 
| +  } | 
| + | 
| +  base::iterator_range<offset_iterator> offsets() { | 
| +    return base::iterator_range<offset_iterator>( | 
| +        offset_iterator(start_, pc_, end_), | 
| +        offset_iterator(start_, end_, end_)); | 
| +  } | 
|  | 
| WasmOpcode current() { | 
| return static_cast<WasmOpcode>( | 
|  |