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