asmjit 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/Rakefile +5 -3
  4. data/asmjit.gemspec +1 -3
  5. data/ext/asmjit/asmjit/.editorconfig +10 -0
  6. data/ext/asmjit/asmjit/.github/FUNDING.yml +1 -0
  7. data/ext/asmjit/asmjit/.github/workflows/build-config.json +47 -0
  8. data/ext/asmjit/asmjit/.github/workflows/build.yml +156 -0
  9. data/ext/asmjit/asmjit/.gitignore +6 -0
  10. data/ext/asmjit/asmjit/CMakeLists.txt +611 -0
  11. data/ext/asmjit/asmjit/LICENSE.md +17 -0
  12. data/ext/asmjit/asmjit/README.md +69 -0
  13. data/ext/asmjit/asmjit/src/asmjit/a64.h +62 -0
  14. data/ext/asmjit/asmjit/src/asmjit/arm/a64archtraits_p.h +81 -0
  15. data/ext/asmjit/asmjit/src/asmjit/arm/a64assembler.cpp +5115 -0
  16. data/ext/asmjit/asmjit/src/asmjit/arm/a64assembler.h +72 -0
  17. data/ext/asmjit/asmjit/src/asmjit/arm/a64builder.cpp +51 -0
  18. data/ext/asmjit/asmjit/src/asmjit/arm/a64builder.h +57 -0
  19. data/ext/asmjit/asmjit/src/asmjit/arm/a64compiler.cpp +60 -0
  20. data/ext/asmjit/asmjit/src/asmjit/arm/a64compiler.h +247 -0
  21. data/ext/asmjit/asmjit/src/asmjit/arm/a64emithelper.cpp +464 -0
  22. data/ext/asmjit/asmjit/src/asmjit/arm/a64emithelper_p.h +50 -0
  23. data/ext/asmjit/asmjit/src/asmjit/arm/a64emitter.h +1228 -0
  24. data/ext/asmjit/asmjit/src/asmjit/arm/a64formatter.cpp +298 -0
  25. data/ext/asmjit/asmjit/src/asmjit/arm/a64formatter_p.h +59 -0
  26. data/ext/asmjit/asmjit/src/asmjit/arm/a64func.cpp +189 -0
  27. data/ext/asmjit/asmjit/src/asmjit/arm/a64func_p.h +33 -0
  28. data/ext/asmjit/asmjit/src/asmjit/arm/a64globals.h +1894 -0
  29. data/ext/asmjit/asmjit/src/asmjit/arm/a64instapi.cpp +278 -0
  30. data/ext/asmjit/asmjit/src/asmjit/arm/a64instapi_p.h +41 -0
  31. data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb.cpp +1957 -0
  32. data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb.h +74 -0
  33. data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb_p.h +876 -0
  34. data/ext/asmjit/asmjit/src/asmjit/arm/a64operand.cpp +85 -0
  35. data/ext/asmjit/asmjit/src/asmjit/arm/a64operand.h +312 -0
  36. data/ext/asmjit/asmjit/src/asmjit/arm/a64rapass.cpp +852 -0
  37. data/ext/asmjit/asmjit/src/asmjit/arm/a64rapass_p.h +105 -0
  38. data/ext/asmjit/asmjit/src/asmjit/arm/a64utils.h +179 -0
  39. data/ext/asmjit/asmjit/src/asmjit/arm/armformatter.cpp +143 -0
  40. data/ext/asmjit/asmjit/src/asmjit/arm/armformatter_p.h +44 -0
  41. data/ext/asmjit/asmjit/src/asmjit/arm/armglobals.h +21 -0
  42. data/ext/asmjit/asmjit/src/asmjit/arm/armoperand.h +621 -0
  43. data/ext/asmjit/asmjit/src/asmjit/arm.h +62 -0
  44. data/ext/asmjit/asmjit/src/asmjit/asmjit-scope-begin.h +17 -0
  45. data/ext/asmjit/asmjit/src/asmjit/asmjit-scope-end.h +9 -0
  46. data/ext/asmjit/asmjit/src/asmjit/asmjit.h +33 -0
  47. data/ext/asmjit/asmjit/src/asmjit/core/api-build_p.h +55 -0
  48. data/ext/asmjit/asmjit/src/asmjit/core/api-config.h +613 -0
  49. data/ext/asmjit/asmjit/src/asmjit/core/archcommons.h +229 -0
  50. data/ext/asmjit/asmjit/src/asmjit/core/archtraits.cpp +160 -0
  51. data/ext/asmjit/asmjit/src/asmjit/core/archtraits.h +290 -0
  52. data/ext/asmjit/asmjit/src/asmjit/core/assembler.cpp +406 -0
  53. data/ext/asmjit/asmjit/src/asmjit/core/assembler.h +129 -0
  54. data/ext/asmjit/asmjit/src/asmjit/core/builder.cpp +889 -0
  55. data/ext/asmjit/asmjit/src/asmjit/core/builder.h +1391 -0
  56. data/ext/asmjit/asmjit/src/asmjit/core/codebuffer.h +113 -0
  57. data/ext/asmjit/asmjit/src/asmjit/core/codeholder.cpp +1149 -0
  58. data/ext/asmjit/asmjit/src/asmjit/core/codeholder.h +1035 -0
  59. data/ext/asmjit/asmjit/src/asmjit/core/codewriter.cpp +175 -0
  60. data/ext/asmjit/asmjit/src/asmjit/core/codewriter_p.h +179 -0
  61. data/ext/asmjit/asmjit/src/asmjit/core/compiler.cpp +582 -0
  62. data/ext/asmjit/asmjit/src/asmjit/core/compiler.h +737 -0
  63. data/ext/asmjit/asmjit/src/asmjit/core/compilerdefs.h +173 -0
  64. data/ext/asmjit/asmjit/src/asmjit/core/constpool.cpp +363 -0
  65. data/ext/asmjit/asmjit/src/asmjit/core/constpool.h +250 -0
  66. data/ext/asmjit/asmjit/src/asmjit/core/cpuinfo.cpp +1162 -0
  67. data/ext/asmjit/asmjit/src/asmjit/core/cpuinfo.h +813 -0
  68. data/ext/asmjit/asmjit/src/asmjit/core/emithelper.cpp +323 -0
  69. data/ext/asmjit/asmjit/src/asmjit/core/emithelper_p.h +58 -0
  70. data/ext/asmjit/asmjit/src/asmjit/core/emitter.cpp +333 -0
  71. data/ext/asmjit/asmjit/src/asmjit/core/emitter.h +741 -0
  72. data/ext/asmjit/asmjit/src/asmjit/core/emitterutils.cpp +129 -0
  73. data/ext/asmjit/asmjit/src/asmjit/core/emitterutils_p.h +89 -0
  74. data/ext/asmjit/asmjit/src/asmjit/core/environment.cpp +46 -0
  75. data/ext/asmjit/asmjit/src/asmjit/core/environment.h +508 -0
  76. data/ext/asmjit/asmjit/src/asmjit/core/errorhandler.cpp +14 -0
  77. data/ext/asmjit/asmjit/src/asmjit/core/errorhandler.h +228 -0
  78. data/ext/asmjit/asmjit/src/asmjit/core/formatter.cpp +584 -0
  79. data/ext/asmjit/asmjit/src/asmjit/core/formatter.h +247 -0
  80. data/ext/asmjit/asmjit/src/asmjit/core/formatter_p.h +34 -0
  81. data/ext/asmjit/asmjit/src/asmjit/core/func.cpp +286 -0
  82. data/ext/asmjit/asmjit/src/asmjit/core/func.h +1445 -0
  83. data/ext/asmjit/asmjit/src/asmjit/core/funcargscontext.cpp +293 -0
  84. data/ext/asmjit/asmjit/src/asmjit/core/funcargscontext_p.h +199 -0
  85. data/ext/asmjit/asmjit/src/asmjit/core/globals.cpp +133 -0
  86. data/ext/asmjit/asmjit/src/asmjit/core/globals.h +393 -0
  87. data/ext/asmjit/asmjit/src/asmjit/core/inst.cpp +113 -0
  88. data/ext/asmjit/asmjit/src/asmjit/core/inst.h +772 -0
  89. data/ext/asmjit/asmjit/src/asmjit/core/jitallocator.cpp +1242 -0
  90. data/ext/asmjit/asmjit/src/asmjit/core/jitallocator.h +261 -0
  91. data/ext/asmjit/asmjit/src/asmjit/core/jitruntime.cpp +80 -0
  92. data/ext/asmjit/asmjit/src/asmjit/core/jitruntime.h +89 -0
  93. data/ext/asmjit/asmjit/src/asmjit/core/logger.cpp +69 -0
  94. data/ext/asmjit/asmjit/src/asmjit/core/logger.h +198 -0
  95. data/ext/asmjit/asmjit/src/asmjit/core/misc_p.h +33 -0
  96. data/ext/asmjit/asmjit/src/asmjit/core/operand.cpp +132 -0
  97. data/ext/asmjit/asmjit/src/asmjit/core/operand.h +1611 -0
  98. data/ext/asmjit/asmjit/src/asmjit/core/osutils.cpp +84 -0
  99. data/ext/asmjit/asmjit/src/asmjit/core/osutils.h +61 -0
  100. data/ext/asmjit/asmjit/src/asmjit/core/osutils_p.h +68 -0
  101. data/ext/asmjit/asmjit/src/asmjit/core/raassignment_p.h +418 -0
  102. data/ext/asmjit/asmjit/src/asmjit/core/rabuilders_p.h +612 -0
  103. data/ext/asmjit/asmjit/src/asmjit/core/radefs_p.h +1204 -0
  104. data/ext/asmjit/asmjit/src/asmjit/core/ralocal.cpp +1166 -0
  105. data/ext/asmjit/asmjit/src/asmjit/core/ralocal_p.h +254 -0
  106. data/ext/asmjit/asmjit/src/asmjit/core/rapass.cpp +1969 -0
  107. data/ext/asmjit/asmjit/src/asmjit/core/rapass_p.h +1183 -0
  108. data/ext/asmjit/asmjit/src/asmjit/core/rastack.cpp +184 -0
  109. data/ext/asmjit/asmjit/src/asmjit/core/rastack_p.h +171 -0
  110. data/ext/asmjit/asmjit/src/asmjit/core/string.cpp +559 -0
  111. data/ext/asmjit/asmjit/src/asmjit/core/string.h +372 -0
  112. data/ext/asmjit/asmjit/src/asmjit/core/support.cpp +494 -0
  113. data/ext/asmjit/asmjit/src/asmjit/core/support.h +1773 -0
  114. data/ext/asmjit/asmjit/src/asmjit/core/target.cpp +14 -0
  115. data/ext/asmjit/asmjit/src/asmjit/core/target.h +53 -0
  116. data/ext/asmjit/asmjit/src/asmjit/core/type.cpp +74 -0
  117. data/ext/asmjit/asmjit/src/asmjit/core/type.h +419 -0
  118. data/ext/asmjit/asmjit/src/asmjit/core/virtmem.cpp +722 -0
  119. data/ext/asmjit/asmjit/src/asmjit/core/virtmem.h +242 -0
  120. data/ext/asmjit/asmjit/src/asmjit/core/zone.cpp +353 -0
  121. data/ext/asmjit/asmjit/src/asmjit/core/zone.h +615 -0
  122. data/ext/asmjit/asmjit/src/asmjit/core/zonehash.cpp +309 -0
  123. data/ext/asmjit/asmjit/src/asmjit/core/zonehash.h +186 -0
  124. data/ext/asmjit/asmjit/src/asmjit/core/zonelist.cpp +163 -0
  125. data/ext/asmjit/asmjit/src/asmjit/core/zonelist.h +209 -0
  126. data/ext/asmjit/asmjit/src/asmjit/core/zonestack.cpp +176 -0
  127. data/ext/asmjit/asmjit/src/asmjit/core/zonestack.h +239 -0
  128. data/ext/asmjit/asmjit/src/asmjit/core/zonestring.h +120 -0
  129. data/ext/asmjit/asmjit/src/asmjit/core/zonetree.cpp +99 -0
  130. data/ext/asmjit/asmjit/src/asmjit/core/zonetree.h +380 -0
  131. data/ext/asmjit/asmjit/src/asmjit/core/zonevector.cpp +356 -0
  132. data/ext/asmjit/asmjit/src/asmjit/core/zonevector.h +690 -0
  133. data/ext/asmjit/asmjit/src/asmjit/core.h +1861 -0
  134. data/ext/asmjit/asmjit/src/asmjit/x86/x86archtraits_p.h +148 -0
  135. data/ext/asmjit/asmjit/src/asmjit/x86/x86assembler.cpp +5110 -0
  136. data/ext/asmjit/asmjit/src/asmjit/x86/x86assembler.h +685 -0
  137. data/ext/asmjit/asmjit/src/asmjit/x86/x86builder.cpp +52 -0
  138. data/ext/asmjit/asmjit/src/asmjit/x86/x86builder.h +351 -0
  139. data/ext/asmjit/asmjit/src/asmjit/x86/x86compiler.cpp +61 -0
  140. data/ext/asmjit/asmjit/src/asmjit/x86/x86compiler.h +721 -0
  141. data/ext/asmjit/asmjit/src/asmjit/x86/x86emithelper.cpp +619 -0
  142. data/ext/asmjit/asmjit/src/asmjit/x86/x86emithelper_p.h +60 -0
  143. data/ext/asmjit/asmjit/src/asmjit/x86/x86emitter.h +4315 -0
  144. data/ext/asmjit/asmjit/src/asmjit/x86/x86formatter.cpp +944 -0
  145. data/ext/asmjit/asmjit/src/asmjit/x86/x86formatter_p.h +58 -0
  146. data/ext/asmjit/asmjit/src/asmjit/x86/x86func.cpp +503 -0
  147. data/ext/asmjit/asmjit/src/asmjit/x86/x86func_p.h +33 -0
  148. data/ext/asmjit/asmjit/src/asmjit/x86/x86globals.h +2169 -0
  149. data/ext/asmjit/asmjit/src/asmjit/x86/x86instapi.cpp +1732 -0
  150. data/ext/asmjit/asmjit/src/asmjit/x86/x86instapi_p.h +41 -0
  151. data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb.cpp +4427 -0
  152. data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb.h +563 -0
  153. data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb_p.h +311 -0
  154. data/ext/asmjit/asmjit/src/asmjit/x86/x86opcode_p.h +436 -0
  155. data/ext/asmjit/asmjit/src/asmjit/x86/x86operand.cpp +231 -0
  156. data/ext/asmjit/asmjit/src/asmjit/x86/x86operand.h +1085 -0
  157. data/ext/asmjit/asmjit/src/asmjit/x86/x86rapass.cpp +1509 -0
  158. data/ext/asmjit/asmjit/src/asmjit/x86/x86rapass_p.h +94 -0
  159. data/ext/asmjit/asmjit/src/asmjit/x86.h +93 -0
  160. data/ext/asmjit/asmjit/src/asmjit.natvis +245 -0
  161. data/ext/asmjit/asmjit/test/asmjit_test_assembler.cpp +84 -0
  162. data/ext/asmjit/asmjit/test/asmjit_test_assembler.h +85 -0
  163. data/ext/asmjit/asmjit/test/asmjit_test_assembler_a64.cpp +4006 -0
  164. data/ext/asmjit/asmjit/test/asmjit_test_assembler_x64.cpp +17833 -0
  165. data/ext/asmjit/asmjit/test/asmjit_test_assembler_x86.cpp +8300 -0
  166. data/ext/asmjit/asmjit/test/asmjit_test_compiler.cpp +253 -0
  167. data/ext/asmjit/asmjit/test/asmjit_test_compiler.h +73 -0
  168. data/ext/asmjit/asmjit/test/asmjit_test_compiler_a64.cpp +690 -0
  169. data/ext/asmjit/asmjit/test/asmjit_test_compiler_x86.cpp +4317 -0
  170. data/ext/asmjit/asmjit/test/asmjit_test_emitters.cpp +197 -0
  171. data/ext/asmjit/asmjit/test/asmjit_test_instinfo.cpp +181 -0
  172. data/ext/asmjit/asmjit/test/asmjit_test_misc.h +257 -0
  173. data/ext/asmjit/asmjit/test/asmjit_test_perf.cpp +62 -0
  174. data/ext/asmjit/asmjit/test/asmjit_test_perf.h +61 -0
  175. data/ext/asmjit/asmjit/test/asmjit_test_perf_a64.cpp +699 -0
  176. data/ext/asmjit/asmjit/test/asmjit_test_perf_x86.cpp +5032 -0
  177. data/ext/asmjit/asmjit/test/asmjit_test_unit.cpp +172 -0
  178. data/ext/asmjit/asmjit/test/asmjit_test_x86_sections.cpp +172 -0
  179. data/ext/asmjit/asmjit/test/asmjitutils.h +38 -0
  180. data/ext/asmjit/asmjit/test/broken.cpp +312 -0
  181. data/ext/asmjit/asmjit/test/broken.h +148 -0
  182. data/ext/asmjit/asmjit/test/cmdline.h +61 -0
  183. data/ext/asmjit/asmjit/test/performancetimer.h +41 -0
  184. data/ext/asmjit/asmjit/tools/configure-makefiles.sh +13 -0
  185. data/ext/asmjit/asmjit/tools/configure-ninja.sh +13 -0
  186. data/ext/asmjit/asmjit/tools/configure-sanitizers.sh +13 -0
  187. data/ext/asmjit/asmjit/tools/configure-vs2019-x64.bat +2 -0
  188. data/ext/asmjit/asmjit/tools/configure-vs2019-x86.bat +2 -0
  189. data/ext/asmjit/asmjit/tools/configure-vs2022-x64.bat +2 -0
  190. data/ext/asmjit/asmjit/tools/configure-vs2022-x86.bat +2 -0
  191. data/ext/asmjit/asmjit/tools/configure-xcode.sh +8 -0
  192. data/ext/asmjit/asmjit/tools/enumgen.js +417 -0
  193. data/ext/asmjit/asmjit/tools/enumgen.sh +3 -0
  194. data/ext/asmjit/asmjit/tools/tablegen-arm.js +365 -0
  195. data/ext/asmjit/asmjit/tools/tablegen-arm.sh +3 -0
  196. data/ext/asmjit/asmjit/tools/tablegen-x86.js +2638 -0
  197. data/ext/asmjit/asmjit/tools/tablegen-x86.sh +3 -0
  198. data/ext/asmjit/asmjit/tools/tablegen.js +947 -0
  199. data/ext/asmjit/asmjit/tools/tablegen.sh +4 -0
  200. data/ext/asmjit/asmjit.cc +167 -30
  201. data/ext/asmjit/extconf.rb +9 -9
  202. data/lib/asmjit/version.rb +1 -1
  203. data/lib/asmjit.rb +14 -4
  204. metadata +198 -17
@@ -0,0 +1,889 @@
1
+ // This file is part of AsmJit project <https://asmjit.com>
2
+ //
3
+ // See asmjit.h or LICENSE.md for license and copyright information
4
+ // SPDX-License-Identifier: Zlib
5
+
6
+ #include "../core/api-build_p.h"
7
+ #ifndef ASMJIT_NO_BUILDER
8
+
9
+ #include "../core/builder.h"
10
+ #include "../core/emitterutils_p.h"
11
+ #include "../core/errorhandler.h"
12
+ #include "../core/formatter.h"
13
+ #include "../core/logger.h"
14
+ #include "../core/support.h"
15
+
16
+ ASMJIT_BEGIN_NAMESPACE
17
+
18
+ // PostponedErrorHandler (Internal)
19
+ // ================================
20
+
21
+ //! Postponed error handler that never throws. Used as a temporal error handler
22
+ //! to run passes. If error occurs, the caller is notified and will call the
23
+ //! real error handler, that can throw.
24
+ class PostponedErrorHandler : public ErrorHandler {
25
+ public:
26
+ void handleError(Error err, const char* message, BaseEmitter* origin) override {
27
+ DebugUtils::unused(err, origin);
28
+ _message.assign(message);
29
+ }
30
+
31
+ StringTmp<128> _message;
32
+ };
33
+
34
+ // BaseBuilder - Utilities
35
+ // =======================
36
+
37
+ static void BaseBuilder_deletePasses(BaseBuilder* self) noexcept {
38
+ for (Pass* pass : self->_passes)
39
+ pass->~Pass();
40
+ self->_passes.reset();
41
+ }
42
+
43
+ // BaseBuilder - Construction & Destruction
44
+ // ========================================
45
+
46
+ BaseBuilder::BaseBuilder() noexcept
47
+ : BaseEmitter(EmitterType::kBuilder),
48
+ _codeZone(32768 - Zone::kBlockOverhead),
49
+ _dataZone(16384 - Zone::kBlockOverhead),
50
+ _passZone(65536 - Zone::kBlockOverhead),
51
+ _allocator(&_codeZone) {}
52
+
53
+ BaseBuilder::~BaseBuilder() noexcept {
54
+ BaseBuilder_deletePasses(this);
55
+ }
56
+
57
+ // BaseBuilder - Node Management
58
+ // =============================
59
+
60
+ Error BaseBuilder::newInstNode(InstNode** out, InstId instId, InstOptions instOptions, uint32_t opCount) {
61
+ uint32_t opCapacity = InstNode::capacityOfOpCount(opCount);
62
+ ASMJIT_ASSERT(opCapacity >= InstNode::kBaseOpCapacity);
63
+
64
+ InstNode* node = _allocator.allocT<InstNode>(InstNode::nodeSizeOfOpCapacity(opCapacity));
65
+ if (ASMJIT_UNLIKELY(!node))
66
+ return reportError(DebugUtils::errored(kErrorOutOfMemory));
67
+
68
+ *out = new(node) InstNode(this, instId, instOptions, opCount, opCapacity);
69
+ return kErrorOk;
70
+ }
71
+
72
+
73
+ Error BaseBuilder::newLabelNode(LabelNode** out) {
74
+ *out = nullptr;
75
+
76
+ ASMJIT_PROPAGATE(_newNodeT<LabelNode>(out));
77
+ return registerLabelNode(*out);
78
+ }
79
+
80
+ Error BaseBuilder::newAlignNode(AlignNode** out, AlignMode alignMode, uint32_t alignment) {
81
+ *out = nullptr;
82
+ return _newNodeT<AlignNode>(out, alignMode, alignment);
83
+ }
84
+
85
+ Error BaseBuilder::newEmbedDataNode(EmbedDataNode** out, TypeId typeId, const void* data, size_t itemCount, size_t repeatCount) {
86
+ *out = nullptr;
87
+
88
+ uint32_t deabstractDelta = TypeUtils::deabstractDeltaOfSize(registerSize());
89
+ TypeId finalTypeId = TypeUtils::deabstract(typeId, deabstractDelta);
90
+
91
+ if (ASMJIT_UNLIKELY(!TypeUtils::isValid(finalTypeId)))
92
+ return reportError(DebugUtils::errored(kErrorInvalidArgument));
93
+
94
+ uint32_t typeSize = TypeUtils::sizeOf(finalTypeId);
95
+ Support::FastUInt8 of = 0;
96
+
97
+ size_t dataSize = Support::mulOverflow(itemCount, size_t(typeSize), &of);
98
+ if (ASMJIT_UNLIKELY(of))
99
+ return reportError(DebugUtils::errored(kErrorOutOfMemory));
100
+
101
+ EmbedDataNode* node;
102
+ ASMJIT_PROPAGATE(_newNodeT<EmbedDataNode>(&node));
103
+
104
+ node->_embed._typeId = typeId;
105
+ node->_embed._typeSize = uint8_t(typeSize);
106
+ node->_itemCount = itemCount;
107
+ node->_repeatCount = repeatCount;
108
+
109
+ uint8_t* dstData = node->_inlineData;
110
+ if (dataSize > EmbedDataNode::kInlineBufferSize) {
111
+ dstData = static_cast<uint8_t*>(_dataZone.alloc(dataSize, 8));
112
+ if (ASMJIT_UNLIKELY(!dstData))
113
+ return reportError(DebugUtils::errored(kErrorOutOfMemory));
114
+ node->_externalData = dstData;
115
+ }
116
+
117
+ if (data)
118
+ memcpy(dstData, data, dataSize);
119
+
120
+ *out = node;
121
+ return kErrorOk;
122
+ }
123
+
124
+ Error BaseBuilder::newConstPoolNode(ConstPoolNode** out) {
125
+ *out = nullptr;
126
+
127
+ ASMJIT_PROPAGATE(_newNodeT<ConstPoolNode>(out));
128
+ return registerLabelNode(*out);
129
+ }
130
+
131
+ Error BaseBuilder::newCommentNode(CommentNode** out, const char* data, size_t size) {
132
+ *out = nullptr;
133
+
134
+ if (data) {
135
+ if (size == SIZE_MAX)
136
+ size = strlen(data);
137
+
138
+ if (size > 0) {
139
+ data = static_cast<char*>(_dataZone.dup(data, size, true));
140
+ if (ASMJIT_UNLIKELY(!data))
141
+ return reportError(DebugUtils::errored(kErrorOutOfMemory));
142
+ }
143
+ }
144
+
145
+ return _newNodeT<CommentNode>(out, data);
146
+ }
147
+
148
+ BaseNode* BaseBuilder::addNode(BaseNode* node) noexcept {
149
+ ASMJIT_ASSERT(!node->_prev);
150
+ ASMJIT_ASSERT(!node->_next);
151
+ ASMJIT_ASSERT(!node->isActive());
152
+
153
+ if (!_cursor) {
154
+ if (!_firstNode) {
155
+ _firstNode = node;
156
+ _lastNode = node;
157
+ }
158
+ else {
159
+ node->_next = _firstNode;
160
+ _firstNode->_prev = node;
161
+ _firstNode = node;
162
+ }
163
+ }
164
+ else {
165
+ BaseNode* prev = _cursor;
166
+ BaseNode* next = _cursor->next();
167
+
168
+ node->_prev = prev;
169
+ node->_next = next;
170
+
171
+ prev->_next = node;
172
+ if (next)
173
+ next->_prev = node;
174
+ else
175
+ _lastNode = node;
176
+ }
177
+
178
+ node->addFlags(NodeFlags::kIsActive);
179
+ if (node->isSection())
180
+ _dirtySectionLinks = true;
181
+
182
+ _cursor = node;
183
+ return node;
184
+ }
185
+
186
+ BaseNode* BaseBuilder::addAfter(BaseNode* node, BaseNode* ref) noexcept {
187
+ ASMJIT_ASSERT(!node->_prev);
188
+ ASMJIT_ASSERT(!node->_next);
189
+
190
+ BaseNode* prev = ref;
191
+ BaseNode* next = ref->next();
192
+
193
+ node->_prev = prev;
194
+ node->_next = next;
195
+
196
+ node->addFlags(NodeFlags::kIsActive);
197
+ if (node->isSection())
198
+ _dirtySectionLinks = true;
199
+
200
+ prev->_next = node;
201
+ if (next)
202
+ next->_prev = node;
203
+ else
204
+ _lastNode = node;
205
+
206
+ return node;
207
+ }
208
+
209
+ BaseNode* BaseBuilder::addBefore(BaseNode* node, BaseNode* ref) noexcept {
210
+ ASMJIT_ASSERT(!node->_prev);
211
+ ASMJIT_ASSERT(!node->_next);
212
+ ASMJIT_ASSERT(!node->isActive());
213
+ ASMJIT_ASSERT(ref->isActive());
214
+
215
+ BaseNode* prev = ref->prev();
216
+ BaseNode* next = ref;
217
+
218
+ node->_prev = prev;
219
+ node->_next = next;
220
+
221
+ node->addFlags(NodeFlags::kIsActive);
222
+ if (node->isSection())
223
+ _dirtySectionLinks = true;
224
+
225
+ next->_prev = node;
226
+ if (prev)
227
+ prev->_next = node;
228
+ else
229
+ _firstNode = node;
230
+
231
+ return node;
232
+ }
233
+
234
+ BaseNode* BaseBuilder::removeNode(BaseNode* node) noexcept {
235
+ if (!node->isActive())
236
+ return node;
237
+
238
+ BaseNode* prev = node->prev();
239
+ BaseNode* next = node->next();
240
+
241
+ if (_firstNode == node)
242
+ _firstNode = next;
243
+ else
244
+ prev->_next = next;
245
+
246
+ if (_lastNode == node)
247
+ _lastNode = prev;
248
+ else
249
+ next->_prev = prev;
250
+
251
+ node->_prev = nullptr;
252
+ node->_next = nullptr;
253
+ node->clearFlags(NodeFlags::kIsActive);
254
+ if (node->isSection())
255
+ _dirtySectionLinks = true;
256
+
257
+ if (_cursor == node)
258
+ _cursor = prev;
259
+
260
+ return node;
261
+ }
262
+
263
+ void BaseBuilder::removeNodes(BaseNode* first, BaseNode* last) noexcept {
264
+ if (first == last) {
265
+ removeNode(first);
266
+ return;
267
+ }
268
+
269
+ if (!first->isActive())
270
+ return;
271
+
272
+ BaseNode* prev = first->prev();
273
+ BaseNode* next = last->next();
274
+
275
+ if (_firstNode == first)
276
+ _firstNode = next;
277
+ else
278
+ prev->_next = next;
279
+
280
+ if (_lastNode == last)
281
+ _lastNode = prev;
282
+ else
283
+ next->_prev = prev;
284
+
285
+ BaseNode* node = first;
286
+ uint32_t didRemoveSection = false;
287
+
288
+ for (;;) {
289
+ next = node->next();
290
+ ASMJIT_ASSERT(next != nullptr);
291
+
292
+ node->_prev = nullptr;
293
+ node->_next = nullptr;
294
+ node->clearFlags(NodeFlags::kIsActive);
295
+ didRemoveSection |= uint32_t(node->isSection());
296
+
297
+ if (_cursor == node)
298
+ _cursor = prev;
299
+
300
+ if (node == last)
301
+ break;
302
+ node = next;
303
+ }
304
+
305
+ if (didRemoveSection)
306
+ _dirtySectionLinks = true;
307
+ }
308
+
309
+ BaseNode* BaseBuilder::setCursor(BaseNode* node) noexcept {
310
+ BaseNode* old = _cursor;
311
+ _cursor = node;
312
+ return old;
313
+ }
314
+
315
+ // BaseBuilder - Sections
316
+ // ======================
317
+
318
+ Error BaseBuilder::sectionNodeOf(SectionNode** out, uint32_t sectionId) {
319
+ *out = nullptr;
320
+
321
+ if (ASMJIT_UNLIKELY(!_code))
322
+ return DebugUtils::errored(kErrorNotInitialized);
323
+
324
+ if (ASMJIT_UNLIKELY(!_code->isSectionValid(sectionId)))
325
+ return reportError(DebugUtils::errored(kErrorInvalidSection));
326
+
327
+ if (sectionId >= _sectionNodes.size()) {
328
+ Error err = _sectionNodes.reserve(&_allocator, sectionId + 1);
329
+ if (ASMJIT_UNLIKELY(err != kErrorOk))
330
+ return reportError(err);
331
+ }
332
+
333
+ SectionNode* node = nullptr;
334
+ if (sectionId < _sectionNodes.size())
335
+ node = _sectionNodes[sectionId];
336
+
337
+ if (!node) {
338
+ ASMJIT_PROPAGATE(_newNodeT<SectionNode>(&node, sectionId));
339
+
340
+ // We have already reserved enough space, this cannot fail now.
341
+ if (sectionId >= _sectionNodes.size())
342
+ _sectionNodes.resize(&_allocator, sectionId + 1);
343
+
344
+ _sectionNodes[sectionId] = node;
345
+ }
346
+
347
+ *out = node;
348
+ return kErrorOk;
349
+ }
350
+
351
+ Error BaseBuilder::section(Section* section) {
352
+ SectionNode* node;
353
+ ASMJIT_PROPAGATE(sectionNodeOf(&node, section->id()));
354
+ ASMJIT_ASSUME(node != nullptr);
355
+
356
+ if (!node->isActive()) {
357
+ // Insert the section at the end if it was not part of the code.
358
+ addAfter(node, lastNode());
359
+ _cursor = node;
360
+ }
361
+ else {
362
+ // This is a bit tricky. We cache section links to make sure that
363
+ // switching sections doesn't involve traversal in linked-list unless
364
+ // the position of the section has changed.
365
+ if (hasDirtySectionLinks())
366
+ updateSectionLinks();
367
+
368
+ if (node->_nextSection)
369
+ _cursor = node->_nextSection->_prev;
370
+ else
371
+ _cursor = _lastNode;
372
+ }
373
+
374
+ return kErrorOk;
375
+ }
376
+
377
+ void BaseBuilder::updateSectionLinks() noexcept {
378
+ if (!_dirtySectionLinks)
379
+ return;
380
+
381
+ BaseNode* node_ = _firstNode;
382
+ SectionNode* currentSection = nullptr;
383
+
384
+ while (node_) {
385
+ if (node_->isSection()) {
386
+ if (currentSection)
387
+ currentSection->_nextSection = node_->as<SectionNode>();
388
+ currentSection = node_->as<SectionNode>();
389
+ }
390
+ node_ = node_->next();
391
+ }
392
+
393
+ if (currentSection)
394
+ currentSection->_nextSection = nullptr;
395
+
396
+ _dirtySectionLinks = false;
397
+ }
398
+
399
+ // BaseBuilder - Labels
400
+ // ====================
401
+
402
+ Error BaseBuilder::labelNodeOf(LabelNode** out, uint32_t labelId) {
403
+ *out = nullptr;
404
+
405
+ if (ASMJIT_UNLIKELY(!_code))
406
+ return DebugUtils::errored(kErrorNotInitialized);
407
+
408
+ uint32_t index = labelId;
409
+ if (ASMJIT_UNLIKELY(index >= _code->labelCount()))
410
+ return DebugUtils::errored(kErrorInvalidLabel);
411
+
412
+ if (index >= _labelNodes.size())
413
+ ASMJIT_PROPAGATE(_labelNodes.resize(&_allocator, index + 1));
414
+
415
+ LabelNode* node = _labelNodes[index];
416
+ if (!node) {
417
+ ASMJIT_PROPAGATE(_newNodeT<LabelNode>(&node, labelId));
418
+ _labelNodes[index] = node;
419
+ }
420
+
421
+ *out = node;
422
+ return kErrorOk;
423
+ }
424
+
425
+ Error BaseBuilder::registerLabelNode(LabelNode* node) {
426
+ if (ASMJIT_UNLIKELY(!_code))
427
+ return DebugUtils::errored(kErrorNotInitialized);
428
+
429
+ LabelEntry* le;
430
+ ASMJIT_PROPAGATE(_code->newLabelEntry(&le));
431
+ uint32_t labelId = le->id();
432
+
433
+ // We just added one label so it must be true.
434
+ ASMJIT_ASSERT(_labelNodes.size() < labelId + 1);
435
+ ASMJIT_PROPAGATE(_labelNodes.resize(&_allocator, labelId + 1));
436
+
437
+ _labelNodes[labelId] = node;
438
+ node->_labelId = labelId;
439
+
440
+ return kErrorOk;
441
+ }
442
+
443
+ static Error BaseBuilder_newLabelInternal(BaseBuilder* self, uint32_t labelId) {
444
+ ASMJIT_ASSERT(self->_labelNodes.size() < labelId + 1);
445
+
446
+ uint32_t growBy = labelId - self->_labelNodes.size();
447
+ Error err = self->_labelNodes.willGrow(&self->_allocator, growBy);
448
+
449
+ if (ASMJIT_UNLIKELY(err))
450
+ return self->reportError(err);
451
+
452
+ LabelNode* node;
453
+ ASMJIT_PROPAGATE(self->_newNodeT<LabelNode>(&node, labelId));
454
+
455
+ self->_labelNodes.resize(&self->_allocator, labelId + 1);
456
+ self->_labelNodes[labelId] = node;
457
+ node->_labelId = labelId;
458
+ return kErrorOk;
459
+ }
460
+
461
+ Label BaseBuilder::newLabel() {
462
+ uint32_t labelId = Globals::kInvalidId;
463
+ LabelEntry* le;
464
+
465
+ if (_code &&
466
+ _code->newLabelEntry(&le) == kErrorOk &&
467
+ BaseBuilder_newLabelInternal(this, le->id()) == kErrorOk) {
468
+ labelId = le->id();
469
+ }
470
+
471
+ return Label(labelId);
472
+ }
473
+
474
+ Label BaseBuilder::newNamedLabel(const char* name, size_t nameSize, LabelType type, uint32_t parentId) {
475
+ uint32_t labelId = Globals::kInvalidId;
476
+ LabelEntry* le;
477
+
478
+ if (_code &&
479
+ _code->newNamedLabelEntry(&le, name, nameSize, type, parentId) == kErrorOk &&
480
+ BaseBuilder_newLabelInternal(this, le->id()) == kErrorOk) {
481
+ labelId = le->id();
482
+ }
483
+
484
+ return Label(labelId);
485
+ }
486
+
487
+ Error BaseBuilder::bind(const Label& label) {
488
+ LabelNode* node;
489
+ ASMJIT_PROPAGATE(labelNodeOf(&node, label));
490
+
491
+ addNode(node);
492
+ return kErrorOk;
493
+ }
494
+
495
+ // BaseBuilder - Passes
496
+ // ====================
497
+
498
+ ASMJIT_FAVOR_SIZE Pass* BaseBuilder::passByName(const char* name) const noexcept {
499
+ for (Pass* pass : _passes)
500
+ if (strcmp(pass->name(), name) == 0)
501
+ return pass;
502
+ return nullptr;
503
+ }
504
+
505
+ ASMJIT_FAVOR_SIZE Error BaseBuilder::addPass(Pass* pass) noexcept {
506
+ if (ASMJIT_UNLIKELY(!_code))
507
+ return DebugUtils::errored(kErrorNotInitialized);
508
+
509
+ if (ASMJIT_UNLIKELY(pass == nullptr)) {
510
+ // Since this is directly called by `addPassT()` we treat `null` argument
511
+ // as out-of-memory condition. Otherwise it would be API misuse.
512
+ return DebugUtils::errored(kErrorOutOfMemory);
513
+ }
514
+ else if (ASMJIT_UNLIKELY(pass->_cb)) {
515
+ // Kinda weird, but okay...
516
+ if (pass->_cb == this)
517
+ return kErrorOk;
518
+ return DebugUtils::errored(kErrorInvalidState);
519
+ }
520
+
521
+ ASMJIT_PROPAGATE(_passes.append(&_allocator, pass));
522
+ pass->_cb = this;
523
+ return kErrorOk;
524
+ }
525
+
526
+ ASMJIT_FAVOR_SIZE Error BaseBuilder::deletePass(Pass* pass) noexcept {
527
+ if (ASMJIT_UNLIKELY(!_code))
528
+ return DebugUtils::errored(kErrorNotInitialized);
529
+
530
+ if (ASMJIT_UNLIKELY(pass == nullptr))
531
+ return DebugUtils::errored(kErrorInvalidArgument);
532
+
533
+ if (pass->_cb != nullptr) {
534
+ if (pass->_cb != this)
535
+ return DebugUtils::errored(kErrorInvalidState);
536
+
537
+ uint32_t index = _passes.indexOf(pass);
538
+ ASMJIT_ASSERT(index != Globals::kNotFound);
539
+
540
+ pass->_cb = nullptr;
541
+ _passes.removeAt(index);
542
+ }
543
+
544
+ pass->~Pass();
545
+ return kErrorOk;
546
+ }
547
+
548
+ Error BaseBuilder::runPasses() {
549
+ if (ASMJIT_UNLIKELY(!_code))
550
+ return DebugUtils::errored(kErrorNotInitialized);
551
+
552
+ if (_passes.empty())
553
+ return kErrorOk;
554
+
555
+ ErrorHandler* prev = errorHandler();
556
+ PostponedErrorHandler postponed;
557
+
558
+ Error err = kErrorOk;
559
+ setErrorHandler(&postponed);
560
+
561
+ for (Pass* pass : _passes) {
562
+ _passZone.reset();
563
+ err = pass->run(&_passZone, _logger);
564
+ if (err)
565
+ break;
566
+ }
567
+ _passZone.reset();
568
+ setErrorHandler(prev);
569
+
570
+ if (ASMJIT_UNLIKELY(err))
571
+ return reportError(err, !postponed._message.empty() ? postponed._message.data() : nullptr);
572
+
573
+ return kErrorOk;
574
+ }
575
+
576
+ // BaseBuilder - Emit
577
+ // ==================
578
+
579
+ Error BaseBuilder::_emit(InstId instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) {
580
+ uint32_t opCount = EmitterUtils::opCountFromEmitArgs(o0, o1, o2, opExt);
581
+ InstOptions options = instOptions() | forcedInstOptions();
582
+
583
+ if (Support::test(options, InstOptions::kReserved)) {
584
+ if (ASMJIT_UNLIKELY(!_code))
585
+ return DebugUtils::errored(kErrorNotInitialized);
586
+
587
+ #ifndef ASMJIT_NO_VALIDATION
588
+ // Strict validation.
589
+ if (hasDiagnosticOption(DiagnosticOptions::kValidateIntermediate)) {
590
+ Operand_ opArray[Globals::kMaxOpCount];
591
+ EmitterUtils::opArrayFromEmitArgs(opArray, o0, o1, o2, opExt);
592
+
593
+ ValidationFlags validationFlags = isCompiler() ? ValidationFlags::kEnableVirtRegs : ValidationFlags::kNone;
594
+ Error err = _funcs.validate(arch(), BaseInst(instId, options, _extraReg), opArray, opCount, validationFlags);
595
+
596
+ if (ASMJIT_UNLIKELY(err)) {
597
+ resetInstOptions();
598
+ resetExtraReg();
599
+ resetInlineComment();
600
+ return reportError(err);
601
+ }
602
+ }
603
+ #endif
604
+
605
+ // Clear instruction options that should never be part of a regular instruction.
606
+ options &= ~InstOptions::kReserved;
607
+ }
608
+
609
+ uint32_t opCapacity = InstNode::capacityOfOpCount(opCount);
610
+ ASMJIT_ASSERT(opCapacity >= InstNode::kBaseOpCapacity);
611
+
612
+ InstNode* node = _allocator.allocT<InstNode>(InstNode::nodeSizeOfOpCapacity(opCapacity));
613
+ const char* comment = inlineComment();
614
+
615
+ resetInstOptions();
616
+ resetInlineComment();
617
+
618
+ if (ASMJIT_UNLIKELY(!node)) {
619
+ resetExtraReg();
620
+ return reportError(DebugUtils::errored(kErrorOutOfMemory));
621
+ }
622
+
623
+ node = new(node) InstNode(this, instId, options, opCount, opCapacity);
624
+ node->setExtraReg(extraReg());
625
+ node->setOp(0, o0);
626
+ node->setOp(1, o1);
627
+ node->setOp(2, o2);
628
+ for (uint32_t i = 3; i < opCount; i++)
629
+ node->setOp(i, opExt[i - 3]);
630
+ node->resetOpRange(opCount, opCapacity);
631
+
632
+ if (comment)
633
+ node->setInlineComment(static_cast<char*>(_dataZone.dup(comment, strlen(comment), true)));
634
+
635
+ addNode(node);
636
+ resetExtraReg();
637
+ return kErrorOk;
638
+ }
639
+
640
+ // BaseBuilder - Align
641
+ // ===================
642
+
643
+ Error BaseBuilder::align(AlignMode alignMode, uint32_t alignment) {
644
+ if (ASMJIT_UNLIKELY(!_code))
645
+ return DebugUtils::errored(kErrorNotInitialized);
646
+
647
+ AlignNode* node;
648
+ ASMJIT_PROPAGATE(newAlignNode(&node, alignMode, alignment));
649
+ ASMJIT_ASSUME(node != nullptr);
650
+
651
+ addNode(node);
652
+ return kErrorOk;
653
+ }
654
+
655
+ // BaseBuilder - Embed
656
+ // ===================
657
+
658
+ Error BaseBuilder::embed(const void* data, size_t dataSize) {
659
+ if (ASMJIT_UNLIKELY(!_code))
660
+ return DebugUtils::errored(kErrorNotInitialized);
661
+
662
+ EmbedDataNode* node;
663
+ ASMJIT_PROPAGATE(newEmbedDataNode(&node, TypeId::kUInt8, data, dataSize));
664
+ ASMJIT_ASSUME(node != nullptr);
665
+
666
+ addNode(node);
667
+ return kErrorOk;
668
+ }
669
+
670
+ Error BaseBuilder::embedDataArray(TypeId typeId, const void* data, size_t itemCount, size_t itemRepeat) {
671
+ if (ASMJIT_UNLIKELY(!_code))
672
+ return DebugUtils::errored(kErrorNotInitialized);
673
+
674
+ EmbedDataNode* node;
675
+ ASMJIT_PROPAGATE(newEmbedDataNode(&node, typeId, data, itemCount, itemRepeat));
676
+ ASMJIT_ASSUME(node != nullptr);
677
+
678
+ addNode(node);
679
+ return kErrorOk;
680
+ }
681
+
682
+ Error BaseBuilder::embedConstPool(const Label& label, const ConstPool& pool) {
683
+ if (ASMJIT_UNLIKELY(!_code))
684
+ return DebugUtils::errored(kErrorNotInitialized);
685
+
686
+ if (!isLabelValid(label))
687
+ return reportError(DebugUtils::errored(kErrorInvalidLabel));
688
+
689
+ ASMJIT_PROPAGATE(align(AlignMode::kData, uint32_t(pool.alignment())));
690
+ ASMJIT_PROPAGATE(bind(label));
691
+
692
+ EmbedDataNode* node;
693
+ ASMJIT_PROPAGATE(newEmbedDataNode(&node, TypeId::kUInt8, nullptr, pool.size()));
694
+ ASMJIT_ASSUME(node != nullptr);
695
+
696
+ pool.fill(node->data());
697
+ addNode(node);
698
+ return kErrorOk;
699
+ }
700
+
701
+ // BaseBuilder - EmbedLabel & EmbedLabelDelta
702
+ // ==========================================
703
+ //
704
+ // If dataSize is zero it means that the size is the same as target register width, however,
705
+ // if it's provided we really want to validate whether it's within the possible range.
706
+
707
+ static inline bool BaseBuilder_checkDataSize(size_t dataSize) noexcept {
708
+ return !dataSize || (Support::isPowerOf2(dataSize) && dataSize <= 8);
709
+ }
710
+
711
+ Error BaseBuilder::embedLabel(const Label& label, size_t dataSize) {
712
+ if (ASMJIT_UNLIKELY(!_code))
713
+ return DebugUtils::errored(kErrorNotInitialized);
714
+
715
+ if (!BaseBuilder_checkDataSize(dataSize))
716
+ return reportError(DebugUtils::errored(kErrorInvalidArgument));
717
+
718
+ EmbedLabelNode* node;
719
+ ASMJIT_PROPAGATE(_newNodeT<EmbedLabelNode>(&node, label.id(), uint32_t(dataSize)));
720
+
721
+ addNode(node);
722
+ return kErrorOk;
723
+ }
724
+
725
+ Error BaseBuilder::embedLabelDelta(const Label& label, const Label& base, size_t dataSize) {
726
+ if (ASMJIT_UNLIKELY(!_code))
727
+ return DebugUtils::errored(kErrorNotInitialized);
728
+
729
+ if (!BaseBuilder_checkDataSize(dataSize))
730
+ return reportError(DebugUtils::errored(kErrorInvalidArgument));
731
+
732
+ EmbedLabelDeltaNode* node;
733
+ ASMJIT_PROPAGATE(_newNodeT<EmbedLabelDeltaNode>(&node, label.id(), base.id(), uint32_t(dataSize)));
734
+
735
+ addNode(node);
736
+ return kErrorOk;
737
+ }
738
+
739
+ // BaseBuilder - Comment
740
+ // =====================
741
+
742
+ Error BaseBuilder::comment(const char* data, size_t size) {
743
+ if (ASMJIT_UNLIKELY(!_code))
744
+ return DebugUtils::errored(kErrorNotInitialized);
745
+
746
+ CommentNode* node;
747
+ ASMJIT_PROPAGATE(newCommentNode(&node, data, size));
748
+ ASMJIT_ASSUME(node != nullptr);
749
+
750
+ addNode(node);
751
+ return kErrorOk;
752
+ }
753
+
754
+ // BaseBuilder - SerializeTo
755
+ // =========================
756
+
757
+ Error BaseBuilder::serializeTo(BaseEmitter* dst) {
758
+ Error err = kErrorOk;
759
+ BaseNode* node_ = _firstNode;
760
+
761
+ Operand_ opArray[Globals::kMaxOpCount];
762
+
763
+ do {
764
+ dst->setInlineComment(node_->inlineComment());
765
+
766
+ if (node_->isInst()) {
767
+ InstNode* node = node_->as<InstNode>();
768
+
769
+ // NOTE: Inlined to remove one additional call per instruction.
770
+ dst->setInstOptions(node->options());
771
+ dst->setExtraReg(node->extraReg());
772
+
773
+ const Operand_* op = node->operands();
774
+ const Operand_* opExt = EmitterUtils::noExt;
775
+
776
+ uint32_t opCount = node->opCount();
777
+ if (opCount > 3) {
778
+ uint32_t i = 4;
779
+ opArray[3] = op[3];
780
+
781
+ while (i < opCount) {
782
+ opArray[i].copyFrom(op[i]);
783
+ i++;
784
+ }
785
+ while (i < Globals::kMaxOpCount) {
786
+ opArray[i].reset();
787
+ i++;
788
+ }
789
+ opExt = opArray + 3;
790
+ }
791
+
792
+ err = dst->_emit(node->id(), op[0], op[1], op[2], opExt);
793
+ }
794
+ else if (node_->isLabel()) {
795
+ if (node_->isConstPool()) {
796
+ ConstPoolNode* node = node_->as<ConstPoolNode>();
797
+ err = dst->embedConstPool(node->label(), node->constPool());
798
+ }
799
+ else {
800
+ LabelNode* node = node_->as<LabelNode>();
801
+ err = dst->bind(node->label());
802
+ }
803
+ }
804
+ else if (node_->isAlign()) {
805
+ AlignNode* node = node_->as<AlignNode>();
806
+ err = dst->align(node->alignMode(), node->alignment());
807
+ }
808
+ else if (node_->isEmbedData()) {
809
+ EmbedDataNode* node = node_->as<EmbedDataNode>();
810
+ err = dst->embedDataArray(node->typeId(), node->data(), node->itemCount(), node->repeatCount());
811
+ }
812
+ else if (node_->isEmbedLabel()) {
813
+ EmbedLabelNode* node = node_->as<EmbedLabelNode>();
814
+ err = dst->embedLabel(node->label(), node->dataSize());
815
+ }
816
+ else if (node_->isEmbedLabelDelta()) {
817
+ EmbedLabelDeltaNode* node = node_->as<EmbedLabelDeltaNode>();
818
+ err = dst->embedLabelDelta(node->label(), node->baseLabel(), node->dataSize());
819
+ }
820
+ else if (node_->isSection()) {
821
+ SectionNode* node = node_->as<SectionNode>();
822
+ err = dst->section(_code->sectionById(node->id()));
823
+ }
824
+ else if (node_->isComment()) {
825
+ CommentNode* node = node_->as<CommentNode>();
826
+ err = dst->comment(node->inlineComment());
827
+ }
828
+
829
+ if (err) break;
830
+ node_ = node_->next();
831
+ } while (node_);
832
+
833
+ return err;
834
+ }
835
+
836
+ // BaseBuilder - Events
837
+ // ====================
838
+
839
+ Error BaseBuilder::onAttach(CodeHolder* code) noexcept {
840
+ ASMJIT_PROPAGATE(Base::onAttach(code));
841
+
842
+ SectionNode* initialSection;
843
+ Error err = sectionNodeOf(&initialSection, 0);
844
+
845
+ if (!err)
846
+ err = _passes.willGrow(&_allocator, 8);
847
+
848
+ if (ASMJIT_UNLIKELY(err)) {
849
+ onDetach(code);
850
+ return err;
851
+ }
852
+
853
+ ASMJIT_ASSUME(initialSection != nullptr);
854
+ _cursor = initialSection;
855
+ _firstNode = initialSection;
856
+ _lastNode = initialSection;
857
+ initialSection->setFlags(NodeFlags::kIsActive);
858
+
859
+ return kErrorOk;
860
+ }
861
+
862
+ Error BaseBuilder::onDetach(CodeHolder* code) noexcept {
863
+ BaseBuilder_deletePasses(this);
864
+ _sectionNodes.reset();
865
+ _labelNodes.reset();
866
+
867
+ _allocator.reset(&_codeZone);
868
+ _codeZone.reset();
869
+ _dataZone.reset();
870
+ _passZone.reset();
871
+
872
+ _nodeFlags = NodeFlags::kNone;
873
+ _cursor = nullptr;
874
+ _firstNode = nullptr;
875
+ _lastNode = nullptr;
876
+
877
+ return Base::onDetach(code);
878
+ }
879
+
880
+ // Pass - Construction & Destruction
881
+ // =================================
882
+
883
+ Pass::Pass(const char* name) noexcept
884
+ : _name(name) {}
885
+ Pass::~Pass() noexcept {}
886
+
887
+ ASMJIT_END_NAMESPACE
888
+
889
+ #endif // !ASMJIT_NO_BUILDER