Mana
CodeBuffer.h
Go to the documentation of this file.
1 
8 #pragma once
9 #include "../runner/common/Platform.h"
10 #include "../runner/common/FileFormat.h"
11 #include "../runner/common/Memory.h"
12 #include "../runner/common/Noncopyable.h"
13 #include <memory>
14 #include <vector>
15 
16 namespace mana
17 {
18  class OutputStream;
19 
20  /*
21  Code Section
22  コードセクション
23  */
24  class CodeBuffer final : Noncopyable
25  {
26  public:
27  CodeBuffer() = default;
28  ~CodeBuffer() = default;
29 
30  void Reduce(const address_t reduceSize);
31 
32  template <typename T>
33  void Add(const T value);
34 
35  template <typename T>
36  T Get(const address_t address) const;
37 
38  void AddOpecode(const IntermediateLanguage code);
39 
40  address_t AddOpecodeAndOperand(const IntermediateLanguage code, const address_t address = InvalidAddress);
41 
42  address_t AddOpecodeAndTwoOperands(const IntermediateLanguage code, const address_t address, const address_t size);
43 
44  void ReplaceOpecode(const address_t address, const IntermediateLanguage code);
45 
46  void ReplaceAddress(const address_t address, const address_t newAddress);
47 
48  void ReplaceAddressAll(const address_t baseAddress, const address_t newAddress);
49 
50  std::unique_ptr<void, decltype(&std::free)> Copy() const;
51 
52  address_t GetSize() const;
53 
54  void Write(OutputStream& stream) const;
55 
56  template <typename T>
57  static T Raw(const void* program, const address_t address);
58 
59  private:
60  address_t AddCommand(const IntermediateLanguage code, const address_t nextCommand);
61  address_t AddCommand(const uint8_t code, const address_t nextCommand);
62 
63  template <typename T>
64  void Replace(const address_t address, const T value);
65 
66  private:
67  struct Command final
68  {
69  uint8_t mCode = 0;
70  address_t mNextCommand = 0;
71 
72  Command() = default;
73 
74  Command(const IntermediateLanguage code, const address_t nextCommand) noexcept
75  : mCode(static_cast<uint8_t>(code))
76  , mNextCommand(nextCommand)
77  {
78  }
79 
80  Command(const uint8_t data, const address_t nextCommand) noexcept
81  : mCode(data)
82  , mNextCommand(nextCommand)
83  {
84  }
85 
86  void Replace(const IntermediateLanguage code) noexcept
87  {
88  mCode = static_cast<uint8_t>(code);
89  }
90 
91  void Replace(const uint8_t data) noexcept
92  {
93  mCode = data;
94  }
95  };
96 
97  std::vector<Command> mCommand;
98  };
99 
100  template <typename T>
101  void CodeBuffer::Add(const T value)
102  {
103  // Stored in BigEndian in CodeBuffer
104  if (IsBigEndian())
105  {
106  for (uint_fast8_t i = 0; i < static_cast<uint_fast8_t>(sizeof(T)); ++i)
107  AddCommand(reinterpret_cast<const uint8_t*>(&value)[i], InvalidAddress);
108  }
109  else
110  {
111  for (int_fast8_t i = static_cast<uint_fast8_t>(sizeof(T) - 1); i >= 0; --i)
112  AddCommand(reinterpret_cast<const uint8_t*>(&value)[i], InvalidAddress);
113  }
114  }
115 
116  template <typename T>
117  void CodeBuffer::Replace(const address_t address, const T value){
118  const uint8_t* pointer = reinterpret_cast<const uint8_t*>(&value);
119  // Stored in BigEndian in CodeBuffer
120  if (IsBigEndian())
121  {
122  for (uint_fast8_t i = 0; i < static_cast<uint_fast8_t>(sizeof(T)); ++i)
123  mCommand[address + i].mCode = pointer[i];
124  }
125  else
126  {
127  for (uint_fast8_t i = 0; i < static_cast<uint_fast8_t>(sizeof(T)); ++i)
128  mCommand[address + i].mCode = pointer[static_cast<uint_fast8_t>(sizeof(T) - 1) - i];
129  }
130  }
131 
132  /*
133  runner\common\FileFormat.h getと重複
134  */
135  template <typename T>
136  T CodeBuffer::Get(const address_t address) const
137  {
138  T value;
139  uint8_t* pointer = reinterpret_cast<uint8_t*>(&value);
140  // Stored in BigEndian in CodeBuffer
141  if (IsBigEndian())
142  {
143  for (uint_fast8_t i = 0; i < static_cast<uint_fast8_t>(sizeof(T)); ++i)
144  pointer[i] = mCommand[address + i].mCode;
145  }
146  else
147  {
148  for (uint_fast8_t i = 0; i < static_cast<uint_fast8_t>(sizeof(T)); ++i)
149  pointer[i] = mCommand[address + static_cast<uint_fast8_t>(sizeof(T) - 1) - i].mCode;
150  }
151  return value;
152  }
153 
154  template <typename T>
155  T CodeBuffer::Raw(const void* program, const address_t address)
156  {
157  T value;
158  uint8_t* pointer = reinterpret_cast<uint8_t*>(&value);
159  const uint8_t* source = static_cast<const uint8_t*>(program) + address;
160  // Stored in BigEndian in CodeBuffer
161  if (IsBigEndian())
162  {
163  for (uint_fast8_t i = 0; i < static_cast<uint_fast8_t>(sizeof(T)); ++i)
164  pointer[i] = source[i];
165  }
166  else
167  {
168  for (uint_fast8_t i = 0; i < static_cast<uint_fast8_t>(sizeof(T)); ++i)
169  pointer[i] = source[static_cast<int_fast16_t>(sizeof(T) - 1) - i];
170  }
171  return value;
172  }
173 }
Definition: CodeBuffer.h:25
CodeBuffer()=default
void AddOpecode(const IntermediateLanguage code)
Definition: CodeBuffer.cpp:18
std::unique_ptr< void, decltype(&std::free)> Copy() const
Definition: CodeBuffer.cpp:62
~CodeBuffer()=default
void Reduce(const address_t reduceSize)
Definition: CodeBuffer.cpp:13
static T Raw(const void *program, const address_t address)
Definition: CodeBuffer.h:155
void ReplaceOpecode(const address_t address, const IntermediateLanguage code)
Definition: CodeBuffer.cpp:40
address_t GetSize() const
Definition: CodeBuffer.cpp:76
address_t AddOpecodeAndTwoOperands(const IntermediateLanguage code, const address_t address, const address_t size)
Definition: CodeBuffer.cpp:31
void ReplaceAddressAll(const address_t baseAddress, const address_t newAddress)
Definition: CodeBuffer.cpp:50
void ReplaceAddress(const address_t address, const address_t newAddress)
Definition: CodeBuffer.cpp:45
void Add(const T value)
Definition: CodeBuffer.h:101
address_t AddOpecodeAndOperand(const IntermediateLanguage code, const address_t address=InvalidAddress)
Definition: CodeBuffer.cpp:23
T Get(const address_t address) const
Definition: CodeBuffer.h:136
void Write(OutputStream &stream) const
Definition: CodeBuffer.cpp:81
Definition: OutputStream.h:15
Definition: CodeBuffer.cpp:12
std::uint32_t address_t
Definition: Type.h:30
IntermediateLanguage
Definition: FileFormat.h:79
bool IsBigEndian()
Definition: Memory.h:17
Definition: Noncopyable.h:18