// Copyright 2019 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_SNAPSHOT_EMBEDDED_PLATFORM_EMBEDDED_FILE_WRITER_BASE_H_
#define V8_SNAPSHOT_EMBEDDED_PLATFORM_EMBEDDED_FILE_WRITER_BASE_H_

#include <cinttypes>
#if !defined(V8_OS_STARBOARD)
#include <cstdio>  // For FILE.
#endif
#include <memory>

namespace v8 {
namespace internal {

class EmbeddedData;

enum DataDirective {
  kByte,
  kLong,
  kQuad,
  kOcta,
};

DataDirective PointerSizeDirective();
int DataDirectiveSize(DataDirective directive);

enum class EmbeddedTargetOs {
  kAIX,
  kChromeOS,
  kFuchsia,
  kMac,
  kWin,
  kStarboard,
  kGeneric,  // Everything not covered above falls in here.
};

enum class EmbeddedTargetArch {
  kArm,
  kArm64,
  kIA32,
  kX64,
  kGeneric,  // Everything not covered above falls in here.
};

// The platform-dependent logic for emitting assembly code for the generated
// embedded.S file.
class PlatformEmbeddedFileWriterBase {
 public:
  virtual ~PlatformEmbeddedFileWriterBase() = default;

  void SetFile(FILE* fp) { fp_ = fp; }
  FILE* fp() const { return fp_; }

  virtual void SectionText() = 0;
  virtual void SectionData() = 0;
  virtual void SectionRoData() = 0;

  virtual void AlignToCodeAlignment() = 0;
  virtual void AlignToDataAlignment() = 0;

  virtual void DeclareUint32(const char* name, uint32_t value) = 0;
  virtual void DeclarePointerToSymbol(const char* name, const char* target) = 0;

  virtual void DeclareLabel(const char* name) = 0;

  virtual void SourceInfo(int fileid, const char* filename, int line) = 0;
  virtual void DeclareFunctionBegin(const char* name) = 0;
  virtual void DeclareFunctionEnd(const char* name) = 0;

  // Returns the number of printed characters.
  virtual int HexLiteral(uint64_t value) = 0;

  virtual void Comment(const char* string) = 0;
  virtual void Newline() { fprintf(fp_, "\n"); }

  virtual void FilePrologue() = 0;
  virtual void DeclareExternalFilename(int fileid, const char* filename) = 0;
  virtual void FileEpilogue() = 0;

  virtual int IndentedDataDirective(DataDirective directive) = 0;

  virtual DataDirective ByteChunkDataDirective() const { return kOcta; }
  virtual int WriteByteChunk(const uint8_t* data);

  // This awkward interface works around the fact that unwind data emission
  // is both high-level and platform-dependent. The former implies it should
  // live in EmbeddedFileWriter, but code there should be platform-independent.
  //
  // Emits unwinding data on x64 Windows, and does nothing otherwise.
  virtual void MaybeEmitUnwindData(const char* unwind_info_symbol,
                                   const char* embedded_blob_data_symbol,
                                   const EmbeddedData* blob,
                                   const void* unwind_infos) {}

 protected:
  FILE* fp_ = nullptr;
};

// The factory function. Returns the appropriate platform-specific instance.
std::unique_ptr<PlatformEmbeddedFileWriterBase> NewPlatformEmbeddedFileWriter(
    const char* target_arch, const char* target_os);

}  // namespace internal
}  // namespace v8

#endif  // V8_SNAPSHOT_EMBEDDED_PLATFORM_EMBEDDED_FILE_WRITER_BASE_H_
