// Copyright 2017 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_WASM_STREAMING_DECODER_H_
#define V8_WASM_STREAMING_DECODER_H_

#include <vector>
#include "src/isolate.h"
#include "src/wasm/module-decoder.h"
#include "src/wasm/wasm-objects.h"

namespace v8 {
namespace internal {
namespace wasm {

// This class is an interface for the StreamingDecoder to start the processing
// of the incoming module bytes.
class V8_EXPORT_PRIVATE StreamingProcessor {
 public:
  virtual ~StreamingProcessor() = default;
  // Process the first 8 bytes of a WebAssembly module. Returns true if the
  // processing finished successfully and the decoding should continue.
  virtual bool ProcessModuleHeader(Vector<const uint8_t> bytes,
                                   uint32_t offset) = 0;

  // Process all sections but the code section. Returns true if the processing
  // finished successfully and the decoding should continue.
  virtual bool ProcessSection(SectionCode section_code,
                              Vector<const uint8_t> bytes, uint32_t offset) = 0;

  // Process the start of the code section. Returns true if the processing
  // finished successfully and the decoding should continue.
  virtual bool ProcessCodeSectionHeader(size_t num_functions,
                                        uint32_t offset) = 0;

  // Process a function body. Returns true if the processing finished
  // successfully and the decoding should continue.
  virtual bool ProcessFunctionBody(Vector<const uint8_t> bytes,
                                   uint32_t offset) = 0;

  // Report the end of a chunk.
  virtual void OnFinishedChunk() = 0;
  // Report the end of the stream. If the stream was successful, all
  // received bytes are passed by parameter. If there has been an error, an
  // empty array is passed.
  virtual void OnFinishedStream(std::unique_ptr<uint8_t[]> bytes,
                                size_t length) = 0;
  // Report an error detected in the StreamingDecoder.
  virtual void OnError(DecodeResult result) = 0;
  // Report the abortion of the stream.
  virtual void OnAbort() = 0;
};

// The StreamingDecoder takes a sequence of byte arrays, each received by a call
// of {OnBytesReceived}, and extracts the bytes which belong to section payloads
// and function bodies.
class V8_EXPORT_PRIVATE StreamingDecoder {
 public:
  explicit StreamingDecoder(std::unique_ptr<StreamingProcessor> processor);

  // The buffer passed into OnBytesReceived is owned by the caller.
  void OnBytesReceived(Vector<const uint8_t> bytes);

  void Finish();

  void Abort();

  // Notify the StreamingDecoder that there has been an compilation error.
  void NotifyError() { ok_ = false; }

 private:
  // TODO(ahaas): Put the whole private state of the StreamingDecoder into the
  // cc file (PIMPL design pattern).

  // The SectionBuffer is the data object for the content of a single section.
  // It stores all bytes of the section (including section id and section
  // length), and the offset where the actual payload starts.
  class SectionBuffer {
   public:
    // id: The section id.
    // payload_length: The length of the payload.
    // length_bytes: The section length, as it is encoded in the module bytes.
    SectionBuffer(uint32_t module_offset, uint8_t id, size_t payload_length,
                  Vector<const uint8_t> length_bytes)
        :  // ID + length + payload
          module_offset_(module_offset),
          length_(1 + length_bytes.length() + payload_length),
          bytes_(new uint8_t[length_]),
          payload_offset_(1 + length_bytes.length()) {
      bytes_[0] = id;
      memcpy(bytes_.get() + 1, &length_bytes.first(), length_bytes.length());
    }

    SectionCode section_code() const {
      return static_cast<SectionCode>(bytes_[0]);
    }

    uint32_t module_offset() const { return module_offset_; }
    uint8_t* bytes() const { return bytes_.get(); }
    size_t length() const { return length_; }
    size_t payload_offset() const { return payload_offset_; }
    size_t payload_length() const { return length_ - payload_offset_; }
    Vector<const uint8_t> payload() const {
      return Vector<const uint8_t>(bytes() + payload_offset(),
                                   payload_length());
    }

   private:
    uint32_t module_offset_;
    size_t length_;
    std::unique_ptr<uint8_t[]> bytes_;
    size_t payload_offset_;
  };

  // The decoding of a stream of wasm module bytes is organized in states. Each
  // state provides a buffer to store the bytes required for the current state,
  // information on how many bytes have already been received, how many bytes
  // are needed, and a {Next} function which starts the next state once all
  // bytes of the current state were received.
  //
  // The states change according to the following state diagram:
  //
  //       Start
  //         |
  //         |
  //         v
  // DecodeModuleHeader
  //         |   _________________________________________
  //         |   |                                        |
  //         v   v                                        |
  //  DecodeSectionID --> DecodeSectionLength --> DecodeSectionPayload
  //         A                  |
  //         |                  | (if the section id == code)
  //         |                  v
  //         |      DecodeNumberOfFunctions -- > DecodeFunctionLength
  //         |                                          A    |
  //         |                                          |    |
  //         |  (after all functions were read)         |    v
  //         ------------------------------------- DecodeFunctionBody
  //
  class DecodingState {
   public:
    virtual ~DecodingState() = default;

    // Reads the bytes for the current state and returns the number of read
    // bytes.
    virtual size_t ReadBytes(StreamingDecoder* streaming,
                             Vector<const uint8_t> bytes);

    // Returns the next state of the streaming decoding.
    virtual std::unique_ptr<DecodingState> Next(
        StreamingDecoder* streaming) = 0;
    // The number of bytes to be received.
    virtual size_t size() const = 0;
    // The buffer to store the received bytes.
    virtual uint8_t* buffer() = 0;
    // The number of bytes which were already received.
    size_t offset() const { return offset_; }
    void set_offset(size_t value) { offset_ = value; }
    // The number of bytes which are still needed.
    size_t remaining() const { return size() - offset(); }
    bool is_finished() const { return offset() == size(); }
    // A flag to indicate if finishing the streaming decoder is allowed without
    // error.
    virtual bool is_finishing_allowed() const { return false; }

   private:
    size_t offset_ = 0;
  };

  // Forward declarations of the concrete states. This is needed so that they
  // can access private members of the StreamingDecoder.
  class DecodeVarInt32;
  class DecodeModuleHeader;
  class DecodeSectionID;
  class DecodeSectionLength;
  class DecodeSectionPayload;
  class DecodeNumberOfFunctions;
  class DecodeFunctionLength;
  class DecodeFunctionBody;

  // Creates a buffer for the next section of the module.
  SectionBuffer* CreateNewBuffer(uint32_t module_offset, uint8_t id,
                                 size_t length,
                                 Vector<const uint8_t> length_bytes) {
    // Check the order of sections. Unknown sections can appear at any position.
    if (id != kUnknownSectionCode) {
      if (id < next_section_id_) {
        Error("Unexpected section");
        return nullptr;
      }
      next_section_id_ = id + 1;
    }
    section_buffers_.emplace_back(
        new SectionBuffer(module_offset, id, length, length_bytes));
    return section_buffers_.back().get();
  }

  std::unique_ptr<DecodingState> Error(DecodeResult result) {
    if (ok_) processor_->OnError(std::move(result));
    ok_ = false;
    return std::unique_ptr<DecodingState>(nullptr);
  }

  std::unique_ptr<DecodingState> Error(std::string message) {
    DecodeResult result(nullptr);
    result.error(module_offset_ - 1, std::move(message));
    return Error(std::move(result));
  }

  void ProcessModuleHeader() {
    if (!ok_) return;
    if (!processor_->ProcessModuleHeader(
            Vector<const uint8_t>(state_->buffer(),
                                  static_cast<int>(state_->size())),
            0)) {
      ok_ = false;
    }
  }

  void ProcessSection(SectionBuffer* buffer) {
    if (!ok_) return;
    if (!processor_->ProcessSection(
            buffer->section_code(), buffer->payload(),
            buffer->module_offset() +
                static_cast<uint32_t>(buffer->payload_offset()))) {
      ok_ = false;
    }
  }

  void StartCodeSection(size_t num_functions) {
    if (!ok_) return;
    // The offset passed to {ProcessCodeSectionHeader} is an error offset and
    // not the start offset of a buffer. Therefore we need the -1 here.
    if (!processor_->ProcessCodeSectionHeader(num_functions,
                                              module_offset() - 1)) {
      ok_ = false;
    }
  }

  void ProcessFunctionBody(Vector<const uint8_t> bytes,
                           uint32_t module_offset) {
    if (!ok_) return;
    if (!processor_->ProcessFunctionBody(bytes, module_offset)) ok_ = false;
  }

  bool ok() const { return ok_; }

  uint32_t module_offset() const { return module_offset_; }

  std::unique_ptr<StreamingProcessor> processor_;
  bool ok_ = true;
  std::unique_ptr<DecodingState> state_;
  std::vector<std::unique_ptr<SectionBuffer>> section_buffers_;
  uint32_t module_offset_ = 0;
  size_t total_size_ = 0;
  uint8_t next_section_id_ = kFirstSectionInModule;

  DISALLOW_COPY_AND_ASSIGN(StreamingDecoder);
};

}  // namespace wasm
}  // namespace internal
}  // namespace v8

#endif  // V8_WASM_STREAMING_DECODER_H_
