asmjit 0.2.0 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
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