asmjit 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (201) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/asmjit.gemspec +1 -1
  4. data/ext/asmjit/asmjit/.editorconfig +10 -0
  5. data/ext/asmjit/asmjit/.github/FUNDING.yml +1 -0
  6. data/ext/asmjit/asmjit/.github/workflows/build-config.json +47 -0
  7. data/ext/asmjit/asmjit/.github/workflows/build.yml +156 -0
  8. data/ext/asmjit/asmjit/.gitignore +6 -0
  9. data/ext/asmjit/asmjit/CMakeLists.txt +611 -0
  10. data/ext/asmjit/asmjit/LICENSE.md +17 -0
  11. data/ext/asmjit/asmjit/README.md +69 -0
  12. data/ext/asmjit/asmjit/src/asmjit/a64.h +62 -0
  13. data/ext/asmjit/asmjit/src/asmjit/arm/a64archtraits_p.h +81 -0
  14. data/ext/asmjit/asmjit/src/asmjit/arm/a64assembler.cpp +5115 -0
  15. data/ext/asmjit/asmjit/src/asmjit/arm/a64assembler.h +72 -0
  16. data/ext/asmjit/asmjit/src/asmjit/arm/a64builder.cpp +51 -0
  17. data/ext/asmjit/asmjit/src/asmjit/arm/a64builder.h +57 -0
  18. data/ext/asmjit/asmjit/src/asmjit/arm/a64compiler.cpp +60 -0
  19. data/ext/asmjit/asmjit/src/asmjit/arm/a64compiler.h +247 -0
  20. data/ext/asmjit/asmjit/src/asmjit/arm/a64emithelper.cpp +464 -0
  21. data/ext/asmjit/asmjit/src/asmjit/arm/a64emithelper_p.h +50 -0
  22. data/ext/asmjit/asmjit/src/asmjit/arm/a64emitter.h +1228 -0
  23. data/ext/asmjit/asmjit/src/asmjit/arm/a64formatter.cpp +298 -0
  24. data/ext/asmjit/asmjit/src/asmjit/arm/a64formatter_p.h +59 -0
  25. data/ext/asmjit/asmjit/src/asmjit/arm/a64func.cpp +189 -0
  26. data/ext/asmjit/asmjit/src/asmjit/arm/a64func_p.h +33 -0
  27. data/ext/asmjit/asmjit/src/asmjit/arm/a64globals.h +1894 -0
  28. data/ext/asmjit/asmjit/src/asmjit/arm/a64instapi.cpp +278 -0
  29. data/ext/asmjit/asmjit/src/asmjit/arm/a64instapi_p.h +41 -0
  30. data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb.cpp +1957 -0
  31. data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb.h +74 -0
  32. data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb_p.h +876 -0
  33. data/ext/asmjit/asmjit/src/asmjit/arm/a64operand.cpp +85 -0
  34. data/ext/asmjit/asmjit/src/asmjit/arm/a64operand.h +312 -0
  35. data/ext/asmjit/asmjit/src/asmjit/arm/a64rapass.cpp +852 -0
  36. data/ext/asmjit/asmjit/src/asmjit/arm/a64rapass_p.h +105 -0
  37. data/ext/asmjit/asmjit/src/asmjit/arm/a64utils.h +179 -0
  38. data/ext/asmjit/asmjit/src/asmjit/arm/armformatter.cpp +143 -0
  39. data/ext/asmjit/asmjit/src/asmjit/arm/armformatter_p.h +44 -0
  40. data/ext/asmjit/asmjit/src/asmjit/arm/armglobals.h +21 -0
  41. data/ext/asmjit/asmjit/src/asmjit/arm/armoperand.h +621 -0
  42. data/ext/asmjit/asmjit/src/asmjit/arm.h +62 -0
  43. data/ext/asmjit/asmjit/src/asmjit/asmjit-scope-begin.h +17 -0
  44. data/ext/asmjit/asmjit/src/asmjit/asmjit-scope-end.h +9 -0
  45. data/ext/asmjit/asmjit/src/asmjit/asmjit.h +33 -0
  46. data/ext/asmjit/asmjit/src/asmjit/core/api-build_p.h +55 -0
  47. data/ext/asmjit/asmjit/src/asmjit/core/api-config.h +613 -0
  48. data/ext/asmjit/asmjit/src/asmjit/core/archcommons.h +229 -0
  49. data/ext/asmjit/asmjit/src/asmjit/core/archtraits.cpp +160 -0
  50. data/ext/asmjit/asmjit/src/asmjit/core/archtraits.h +290 -0
  51. data/ext/asmjit/asmjit/src/asmjit/core/assembler.cpp +406 -0
  52. data/ext/asmjit/asmjit/src/asmjit/core/assembler.h +129 -0
  53. data/ext/asmjit/asmjit/src/asmjit/core/builder.cpp +889 -0
  54. data/ext/asmjit/asmjit/src/asmjit/core/builder.h +1391 -0
  55. data/ext/asmjit/asmjit/src/asmjit/core/codebuffer.h +113 -0
  56. data/ext/asmjit/asmjit/src/asmjit/core/codeholder.cpp +1149 -0
  57. data/ext/asmjit/asmjit/src/asmjit/core/codeholder.h +1035 -0
  58. data/ext/asmjit/asmjit/src/asmjit/core/codewriter.cpp +175 -0
  59. data/ext/asmjit/asmjit/src/asmjit/core/codewriter_p.h +179 -0
  60. data/ext/asmjit/asmjit/src/asmjit/core/compiler.cpp +582 -0
  61. data/ext/asmjit/asmjit/src/asmjit/core/compiler.h +737 -0
  62. data/ext/asmjit/asmjit/src/asmjit/core/compilerdefs.h +173 -0
  63. data/ext/asmjit/asmjit/src/asmjit/core/constpool.cpp +363 -0
  64. data/ext/asmjit/asmjit/src/asmjit/core/constpool.h +250 -0
  65. data/ext/asmjit/asmjit/src/asmjit/core/cpuinfo.cpp +1162 -0
  66. data/ext/asmjit/asmjit/src/asmjit/core/cpuinfo.h +813 -0
  67. data/ext/asmjit/asmjit/src/asmjit/core/emithelper.cpp +323 -0
  68. data/ext/asmjit/asmjit/src/asmjit/core/emithelper_p.h +58 -0
  69. data/ext/asmjit/asmjit/src/asmjit/core/emitter.cpp +333 -0
  70. data/ext/asmjit/asmjit/src/asmjit/core/emitter.h +741 -0
  71. data/ext/asmjit/asmjit/src/asmjit/core/emitterutils.cpp +129 -0
  72. data/ext/asmjit/asmjit/src/asmjit/core/emitterutils_p.h +89 -0
  73. data/ext/asmjit/asmjit/src/asmjit/core/environment.cpp +46 -0
  74. data/ext/asmjit/asmjit/src/asmjit/core/environment.h +508 -0
  75. data/ext/asmjit/asmjit/src/asmjit/core/errorhandler.cpp +14 -0
  76. data/ext/asmjit/asmjit/src/asmjit/core/errorhandler.h +228 -0
  77. data/ext/asmjit/asmjit/src/asmjit/core/formatter.cpp +584 -0
  78. data/ext/asmjit/asmjit/src/asmjit/core/formatter.h +247 -0
  79. data/ext/asmjit/asmjit/src/asmjit/core/formatter_p.h +34 -0
  80. data/ext/asmjit/asmjit/src/asmjit/core/func.cpp +286 -0
  81. data/ext/asmjit/asmjit/src/asmjit/core/func.h +1445 -0
  82. data/ext/asmjit/asmjit/src/asmjit/core/funcargscontext.cpp +293 -0
  83. data/ext/asmjit/asmjit/src/asmjit/core/funcargscontext_p.h +199 -0
  84. data/ext/asmjit/asmjit/src/asmjit/core/globals.cpp +133 -0
  85. data/ext/asmjit/asmjit/src/asmjit/core/globals.h +393 -0
  86. data/ext/asmjit/asmjit/src/asmjit/core/inst.cpp +113 -0
  87. data/ext/asmjit/asmjit/src/asmjit/core/inst.h +772 -0
  88. data/ext/asmjit/asmjit/src/asmjit/core/jitallocator.cpp +1242 -0
  89. data/ext/asmjit/asmjit/src/asmjit/core/jitallocator.h +261 -0
  90. data/ext/asmjit/asmjit/src/asmjit/core/jitruntime.cpp +80 -0
  91. data/ext/asmjit/asmjit/src/asmjit/core/jitruntime.h +89 -0
  92. data/ext/asmjit/asmjit/src/asmjit/core/logger.cpp +69 -0
  93. data/ext/asmjit/asmjit/src/asmjit/core/logger.h +198 -0
  94. data/ext/asmjit/asmjit/src/asmjit/core/misc_p.h +33 -0
  95. data/ext/asmjit/asmjit/src/asmjit/core/operand.cpp +132 -0
  96. data/ext/asmjit/asmjit/src/asmjit/core/operand.h +1611 -0
  97. data/ext/asmjit/asmjit/src/asmjit/core/osutils.cpp +84 -0
  98. data/ext/asmjit/asmjit/src/asmjit/core/osutils.h +61 -0
  99. data/ext/asmjit/asmjit/src/asmjit/core/osutils_p.h +68 -0
  100. data/ext/asmjit/asmjit/src/asmjit/core/raassignment_p.h +418 -0
  101. data/ext/asmjit/asmjit/src/asmjit/core/rabuilders_p.h +612 -0
  102. data/ext/asmjit/asmjit/src/asmjit/core/radefs_p.h +1204 -0
  103. data/ext/asmjit/asmjit/src/asmjit/core/ralocal.cpp +1166 -0
  104. data/ext/asmjit/asmjit/src/asmjit/core/ralocal_p.h +254 -0
  105. data/ext/asmjit/asmjit/src/asmjit/core/rapass.cpp +1969 -0
  106. data/ext/asmjit/asmjit/src/asmjit/core/rapass_p.h +1183 -0
  107. data/ext/asmjit/asmjit/src/asmjit/core/rastack.cpp +184 -0
  108. data/ext/asmjit/asmjit/src/asmjit/core/rastack_p.h +171 -0
  109. data/ext/asmjit/asmjit/src/asmjit/core/string.cpp +559 -0
  110. data/ext/asmjit/asmjit/src/asmjit/core/string.h +372 -0
  111. data/ext/asmjit/asmjit/src/asmjit/core/support.cpp +494 -0
  112. data/ext/asmjit/asmjit/src/asmjit/core/support.h +1773 -0
  113. data/ext/asmjit/asmjit/src/asmjit/core/target.cpp +14 -0
  114. data/ext/asmjit/asmjit/src/asmjit/core/target.h +53 -0
  115. data/ext/asmjit/asmjit/src/asmjit/core/type.cpp +74 -0
  116. data/ext/asmjit/asmjit/src/asmjit/core/type.h +419 -0
  117. data/ext/asmjit/asmjit/src/asmjit/core/virtmem.cpp +722 -0
  118. data/ext/asmjit/asmjit/src/asmjit/core/virtmem.h +242 -0
  119. data/ext/asmjit/asmjit/src/asmjit/core/zone.cpp +353 -0
  120. data/ext/asmjit/asmjit/src/asmjit/core/zone.h +615 -0
  121. data/ext/asmjit/asmjit/src/asmjit/core/zonehash.cpp +309 -0
  122. data/ext/asmjit/asmjit/src/asmjit/core/zonehash.h +186 -0
  123. data/ext/asmjit/asmjit/src/asmjit/core/zonelist.cpp +163 -0
  124. data/ext/asmjit/asmjit/src/asmjit/core/zonelist.h +209 -0
  125. data/ext/asmjit/asmjit/src/asmjit/core/zonestack.cpp +176 -0
  126. data/ext/asmjit/asmjit/src/asmjit/core/zonestack.h +239 -0
  127. data/ext/asmjit/asmjit/src/asmjit/core/zonestring.h +120 -0
  128. data/ext/asmjit/asmjit/src/asmjit/core/zonetree.cpp +99 -0
  129. data/ext/asmjit/asmjit/src/asmjit/core/zonetree.h +380 -0
  130. data/ext/asmjit/asmjit/src/asmjit/core/zonevector.cpp +356 -0
  131. data/ext/asmjit/asmjit/src/asmjit/core/zonevector.h +690 -0
  132. data/ext/asmjit/asmjit/src/asmjit/core.h +1861 -0
  133. data/ext/asmjit/asmjit/src/asmjit/x86/x86archtraits_p.h +148 -0
  134. data/ext/asmjit/asmjit/src/asmjit/x86/x86assembler.cpp +5110 -0
  135. data/ext/asmjit/asmjit/src/asmjit/x86/x86assembler.h +685 -0
  136. data/ext/asmjit/asmjit/src/asmjit/x86/x86builder.cpp +52 -0
  137. data/ext/asmjit/asmjit/src/asmjit/x86/x86builder.h +351 -0
  138. data/ext/asmjit/asmjit/src/asmjit/x86/x86compiler.cpp +61 -0
  139. data/ext/asmjit/asmjit/src/asmjit/x86/x86compiler.h +721 -0
  140. data/ext/asmjit/asmjit/src/asmjit/x86/x86emithelper.cpp +619 -0
  141. data/ext/asmjit/asmjit/src/asmjit/x86/x86emithelper_p.h +60 -0
  142. data/ext/asmjit/asmjit/src/asmjit/x86/x86emitter.h +4315 -0
  143. data/ext/asmjit/asmjit/src/asmjit/x86/x86formatter.cpp +944 -0
  144. data/ext/asmjit/asmjit/src/asmjit/x86/x86formatter_p.h +58 -0
  145. data/ext/asmjit/asmjit/src/asmjit/x86/x86func.cpp +503 -0
  146. data/ext/asmjit/asmjit/src/asmjit/x86/x86func_p.h +33 -0
  147. data/ext/asmjit/asmjit/src/asmjit/x86/x86globals.h +2169 -0
  148. data/ext/asmjit/asmjit/src/asmjit/x86/x86instapi.cpp +1732 -0
  149. data/ext/asmjit/asmjit/src/asmjit/x86/x86instapi_p.h +41 -0
  150. data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb.cpp +4427 -0
  151. data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb.h +563 -0
  152. data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb_p.h +311 -0
  153. data/ext/asmjit/asmjit/src/asmjit/x86/x86opcode_p.h +436 -0
  154. data/ext/asmjit/asmjit/src/asmjit/x86/x86operand.cpp +231 -0
  155. data/ext/asmjit/asmjit/src/asmjit/x86/x86operand.h +1085 -0
  156. data/ext/asmjit/asmjit/src/asmjit/x86/x86rapass.cpp +1509 -0
  157. data/ext/asmjit/asmjit/src/asmjit/x86/x86rapass_p.h +94 -0
  158. data/ext/asmjit/asmjit/src/asmjit/x86.h +93 -0
  159. data/ext/asmjit/asmjit/src/asmjit.natvis +245 -0
  160. data/ext/asmjit/asmjit/test/asmjit_test_assembler.cpp +84 -0
  161. data/ext/asmjit/asmjit/test/asmjit_test_assembler.h +85 -0
  162. data/ext/asmjit/asmjit/test/asmjit_test_assembler_a64.cpp +4006 -0
  163. data/ext/asmjit/asmjit/test/asmjit_test_assembler_x64.cpp +17833 -0
  164. data/ext/asmjit/asmjit/test/asmjit_test_assembler_x86.cpp +8300 -0
  165. data/ext/asmjit/asmjit/test/asmjit_test_compiler.cpp +253 -0
  166. data/ext/asmjit/asmjit/test/asmjit_test_compiler.h +73 -0
  167. data/ext/asmjit/asmjit/test/asmjit_test_compiler_a64.cpp +690 -0
  168. data/ext/asmjit/asmjit/test/asmjit_test_compiler_x86.cpp +4317 -0
  169. data/ext/asmjit/asmjit/test/asmjit_test_emitters.cpp +197 -0
  170. data/ext/asmjit/asmjit/test/asmjit_test_instinfo.cpp +181 -0
  171. data/ext/asmjit/asmjit/test/asmjit_test_misc.h +257 -0
  172. data/ext/asmjit/asmjit/test/asmjit_test_perf.cpp +62 -0
  173. data/ext/asmjit/asmjit/test/asmjit_test_perf.h +61 -0
  174. data/ext/asmjit/asmjit/test/asmjit_test_perf_a64.cpp +699 -0
  175. data/ext/asmjit/asmjit/test/asmjit_test_perf_x86.cpp +5032 -0
  176. data/ext/asmjit/asmjit/test/asmjit_test_unit.cpp +172 -0
  177. data/ext/asmjit/asmjit/test/asmjit_test_x86_sections.cpp +172 -0
  178. data/ext/asmjit/asmjit/test/asmjitutils.h +38 -0
  179. data/ext/asmjit/asmjit/test/broken.cpp +312 -0
  180. data/ext/asmjit/asmjit/test/broken.h +148 -0
  181. data/ext/asmjit/asmjit/test/cmdline.h +61 -0
  182. data/ext/asmjit/asmjit/test/performancetimer.h +41 -0
  183. data/ext/asmjit/asmjit/tools/configure-makefiles.sh +13 -0
  184. data/ext/asmjit/asmjit/tools/configure-ninja.sh +13 -0
  185. data/ext/asmjit/asmjit/tools/configure-sanitizers.sh +13 -0
  186. data/ext/asmjit/asmjit/tools/configure-vs2019-x64.bat +2 -0
  187. data/ext/asmjit/asmjit/tools/configure-vs2019-x86.bat +2 -0
  188. data/ext/asmjit/asmjit/tools/configure-vs2022-x64.bat +2 -0
  189. data/ext/asmjit/asmjit/tools/configure-vs2022-x86.bat +2 -0
  190. data/ext/asmjit/asmjit/tools/configure-xcode.sh +8 -0
  191. data/ext/asmjit/asmjit/tools/enumgen.js +417 -0
  192. data/ext/asmjit/asmjit/tools/enumgen.sh +3 -0
  193. data/ext/asmjit/asmjit/tools/tablegen-arm.js +365 -0
  194. data/ext/asmjit/asmjit/tools/tablegen-arm.sh +3 -0
  195. data/ext/asmjit/asmjit/tools/tablegen-x86.js +2638 -0
  196. data/ext/asmjit/asmjit/tools/tablegen-x86.sh +3 -0
  197. data/ext/asmjit/asmjit/tools/tablegen.js +947 -0
  198. data/ext/asmjit/asmjit/tools/tablegen.sh +4 -0
  199. data/ext/asmjit/asmjit.cc +18 -0
  200. data/lib/asmjit/version.rb +1 -1
  201. metadata +197 -2
@@ -0,0 +1,559 @@
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
+ #include "../core/string.h"
8
+ #include "../core/support.h"
9
+
10
+ ASMJIT_BEGIN_NAMESPACE
11
+
12
+ // String - Globals
13
+ // ================
14
+
15
+ static const char String_baseN[] = "0123456789ABCDEF";
16
+
17
+ constexpr size_t kMinAllocSize = 64;
18
+ constexpr size_t kMaxAllocSize = SIZE_MAX - Globals::kGrowThreshold;
19
+
20
+ // String - Clear & Reset
21
+ // ======================
22
+
23
+ Error String::reset() noexcept {
24
+ if (_type == kTypeLarge)
25
+ ::free(_large.data);
26
+
27
+ _resetInternal();
28
+ return kErrorOk;
29
+ }
30
+
31
+ Error String::clear() noexcept {
32
+ if (isLargeOrExternal()) {
33
+ _large.size = 0;
34
+ _large.data[0] = '\0';
35
+ }
36
+ else {
37
+ _raw.uptr[0] = 0;
38
+ }
39
+
40
+ return kErrorOk;
41
+ }
42
+
43
+ // String - Prepare
44
+ // ================
45
+
46
+ char* String::prepare(ModifyOp op, size_t size) noexcept {
47
+ char* curData;
48
+ size_t curSize;
49
+ size_t curCapacity;
50
+
51
+ if (isLargeOrExternal()) {
52
+ curData = this->_large.data;
53
+ curSize = this->_large.size;
54
+ curCapacity = this->_large.capacity;
55
+ }
56
+ else {
57
+ curData = this->_small.data;
58
+ curSize = this->_small.type;
59
+ curCapacity = kSSOCapacity;
60
+ }
61
+
62
+ if (op == ModifyOp::kAssign) {
63
+ if (size > curCapacity) {
64
+ // Prevent arithmetic overflow.
65
+ if (ASMJIT_UNLIKELY(size >= kMaxAllocSize))
66
+ return nullptr;
67
+
68
+ size_t newCapacity = Support::alignUp<size_t>(size + 1, kMinAllocSize);
69
+ char* newData = static_cast<char*>(::malloc(newCapacity));
70
+
71
+ if (ASMJIT_UNLIKELY(!newData))
72
+ return nullptr;
73
+
74
+ if (_type == kTypeLarge)
75
+ ::free(curData);
76
+
77
+ _large.type = kTypeLarge;
78
+ _large.size = size;
79
+ _large.capacity = newCapacity - 1;
80
+ _large.data = newData;
81
+
82
+ newData[size] = '\0';
83
+ return newData;
84
+ }
85
+ else {
86
+ _setSize(size);
87
+ curData[size] = '\0';
88
+ return curData;
89
+ }
90
+ }
91
+ else {
92
+ // Prevent arithmetic overflow.
93
+ if (ASMJIT_UNLIKELY(size >= kMaxAllocSize - curSize))
94
+ return nullptr;
95
+
96
+ size_t newSize = size + curSize;
97
+ size_t newSizePlusOne = newSize + 1;
98
+
99
+ if (newSizePlusOne > curCapacity) {
100
+ size_t newCapacity = Support::max<size_t>(curCapacity + 1, kMinAllocSize);
101
+
102
+ if (newCapacity < newSizePlusOne && newCapacity < Globals::kGrowThreshold)
103
+ newCapacity = Support::alignUpPowerOf2(newCapacity);
104
+
105
+ if (newCapacity < newSizePlusOne)
106
+ newCapacity = Support::alignUp(newSizePlusOne, Globals::kGrowThreshold);
107
+
108
+ if (ASMJIT_UNLIKELY(newCapacity < newSizePlusOne))
109
+ return nullptr;
110
+
111
+ char* newData = static_cast<char*>(::malloc(newCapacity));
112
+ if (ASMJIT_UNLIKELY(!newData))
113
+ return nullptr;
114
+
115
+ memcpy(newData, curData, curSize);
116
+
117
+ if (_type == kTypeLarge)
118
+ ::free(curData);
119
+
120
+ _large.type = kTypeLarge;
121
+ _large.size = newSize;
122
+ _large.capacity = newCapacity - 1;
123
+ _large.data = newData;
124
+
125
+ newData[newSize] = '\0';
126
+ return newData + curSize;
127
+ }
128
+ else {
129
+ _setSize(newSize);
130
+ curData[newSize] = '\0';
131
+ return curData + curSize;
132
+ }
133
+ }
134
+ }
135
+
136
+ // String - Assign
137
+ // ===============
138
+
139
+ Error String::assign(const char* data, size_t size) noexcept {
140
+ char* dst = nullptr;
141
+
142
+ // Null terminated string without `size` specified.
143
+ if (size == SIZE_MAX)
144
+ size = data ? strlen(data) : size_t(0);
145
+
146
+ if (isLargeOrExternal()) {
147
+ if (size <= _large.capacity) {
148
+ dst = _large.data;
149
+ _large.size = size;
150
+ }
151
+ else {
152
+ size_t capacityPlusOne = Support::alignUp(size + 1, 32);
153
+ if (ASMJIT_UNLIKELY(capacityPlusOne < size))
154
+ return DebugUtils::errored(kErrorOutOfMemory);
155
+
156
+ dst = static_cast<char*>(::malloc(capacityPlusOne));
157
+ if (ASMJIT_UNLIKELY(!dst))
158
+ return DebugUtils::errored(kErrorOutOfMemory);
159
+
160
+ if (_type == kTypeLarge)
161
+ ::free(_large.data);
162
+
163
+ _large.type = kTypeLarge;
164
+ _large.data = dst;
165
+ _large.size = size;
166
+ _large.capacity = capacityPlusOne - 1;
167
+ }
168
+ }
169
+ else {
170
+ if (size <= kSSOCapacity) {
171
+ ASMJIT_ASSERT(size < 0xFFu);
172
+
173
+ dst = _small.data;
174
+ _small.type = uint8_t(size);
175
+ }
176
+ else {
177
+ dst = static_cast<char*>(::malloc(size + 1));
178
+ if (ASMJIT_UNLIKELY(!dst))
179
+ return DebugUtils::errored(kErrorOutOfMemory);
180
+
181
+ _large.type = kTypeLarge;
182
+ _large.data = dst;
183
+ _large.size = size;
184
+ _large.capacity = size;
185
+ }
186
+ }
187
+
188
+ // Optionally copy data from `data` and null-terminate.
189
+ if (data && size) {
190
+ // NOTE: It's better to use `memmove()`. If, for any reason, somebody uses
191
+ // this function to substring the same string it would work as expected.
192
+ ::memmove(dst, data, size);
193
+ }
194
+
195
+ dst[size] = '\0';
196
+ return kErrorOk;
197
+ }
198
+
199
+ // String - Operations
200
+ // ===================
201
+
202
+ Error String::_opString(ModifyOp op, const char* str, size_t size) noexcept {
203
+ if (size == SIZE_MAX)
204
+ size = str ? strlen(str) : size_t(0);
205
+
206
+ if (!size)
207
+ return kErrorOk;
208
+
209
+ char* p = prepare(op, size);
210
+ if (!p)
211
+ return DebugUtils::errored(kErrorOutOfMemory);
212
+
213
+ memcpy(p, str, size);
214
+ return kErrorOk;
215
+ }
216
+
217
+ Error String::_opChar(ModifyOp op, char c) noexcept {
218
+ char* p = prepare(op, 1);
219
+ if (!p)
220
+ return DebugUtils::errored(kErrorOutOfMemory);
221
+
222
+ *p = c;
223
+ return kErrorOk;
224
+ }
225
+
226
+ Error String::_opChars(ModifyOp op, char c, size_t n) noexcept {
227
+ if (!n)
228
+ return kErrorOk;
229
+
230
+ char* p = prepare(op, n);
231
+ if (!p)
232
+ return DebugUtils::errored(kErrorOutOfMemory);
233
+
234
+ memset(p, c, n);
235
+ return kErrorOk;
236
+ }
237
+
238
+ Error String::padEnd(size_t n, char c) noexcept {
239
+ size_t size = this->size();
240
+ return n > size ? appendChars(c, n - size) : kErrorOk;
241
+ }
242
+
243
+ Error String::_opNumber(ModifyOp op, uint64_t i, uint32_t base, size_t width, StringFormatFlags flags) noexcept {
244
+ if (base == 0)
245
+ base = 10;
246
+
247
+ char buf[128];
248
+ char* p = buf + ASMJIT_ARRAY_SIZE(buf);
249
+
250
+ uint64_t orig = i;
251
+ char sign = '\0';
252
+
253
+ // Format Sign
254
+ // -----------
255
+
256
+ if (Support::test(flags, StringFormatFlags::kSigned) && int64_t(i) < 0) {
257
+ i = uint64_t(-int64_t(i));
258
+ sign = '-';
259
+ }
260
+ else if (Support::test(flags, StringFormatFlags::kShowSign)) {
261
+ sign = '+';
262
+ }
263
+ else if (Support::test(flags, StringFormatFlags::kShowSpace)) {
264
+ sign = ' ';
265
+ }
266
+
267
+ // Format Number
268
+ // -------------
269
+
270
+ switch (base) {
271
+ case 2:
272
+ case 8:
273
+ case 16: {
274
+ uint32_t shift = Support::ctz(base);
275
+ uint32_t mask = base - 1;
276
+
277
+ do {
278
+ uint64_t d = i >> shift;
279
+ size_t r = size_t(i & mask);
280
+
281
+ *--p = String_baseN[r];
282
+ i = d;
283
+ } while (i);
284
+
285
+ break;
286
+ }
287
+
288
+ case 10: {
289
+ do {
290
+ uint64_t d = i / 10;
291
+ uint64_t r = i % 10;
292
+
293
+ *--p = char(uint32_t('0') + uint32_t(r));
294
+ i = d;
295
+ } while (i);
296
+
297
+ break;
298
+ }
299
+
300
+ default:
301
+ return DebugUtils::errored(kErrorInvalidArgument);
302
+ }
303
+
304
+ size_t numberSize = (size_t)(buf + ASMJIT_ARRAY_SIZE(buf) - p);
305
+
306
+ // Alternate Form
307
+ // --------------
308
+
309
+ if (Support::test(flags, StringFormatFlags::kAlternate)) {
310
+ if (base == 8) {
311
+ if (orig != 0)
312
+ *--p = '0';
313
+ }
314
+ if (base == 16) {
315
+ *--p = 'x';
316
+ *--p = '0';
317
+ }
318
+ }
319
+
320
+ // String Width
321
+ // ------------
322
+
323
+ if (sign != 0)
324
+ *--p = sign;
325
+
326
+ if (width > 256)
327
+ width = 256;
328
+
329
+ if (width <= numberSize)
330
+ width = 0;
331
+ else
332
+ width -= numberSize;
333
+
334
+ // Finalize
335
+ // --------
336
+
337
+ size_t prefixSize = (size_t)(buf + ASMJIT_ARRAY_SIZE(buf) - p) - numberSize;
338
+ char* data = prepare(op, prefixSize + width + numberSize);
339
+
340
+ if (!data)
341
+ return DebugUtils::errored(kErrorOutOfMemory);
342
+
343
+ memcpy(data, p, prefixSize);
344
+ data += prefixSize;
345
+
346
+ memset(data, '0', width);
347
+ data += width;
348
+
349
+ memcpy(data, p + prefixSize, numberSize);
350
+ return kErrorOk;
351
+ }
352
+
353
+ Error String::_opHex(ModifyOp op, const void* data, size_t size, char separator) noexcept {
354
+ char* dst;
355
+ const uint8_t* src = static_cast<const uint8_t*>(data);
356
+
357
+ if (!size)
358
+ return kErrorOk;
359
+
360
+ if (separator) {
361
+ if (ASMJIT_UNLIKELY(size >= SIZE_MAX / 3))
362
+ return DebugUtils::errored(kErrorOutOfMemory);
363
+
364
+ dst = prepare(op, size * 3 - 1);
365
+ if (ASMJIT_UNLIKELY(!dst))
366
+ return DebugUtils::errored(kErrorOutOfMemory);
367
+
368
+ size_t i = 0;
369
+ for (;;) {
370
+ dst[0] = String_baseN[(src[0] >> 4) & 0xF];
371
+ dst[1] = String_baseN[(src[0] ) & 0xF];
372
+ if (++i == size)
373
+ break;
374
+ // This makes sure that the separator is only put between two hexadecimal bytes.
375
+ dst[2] = separator;
376
+ dst += 3;
377
+ src++;
378
+ }
379
+ }
380
+ else {
381
+ if (ASMJIT_UNLIKELY(size >= SIZE_MAX / 2))
382
+ return DebugUtils::errored(kErrorOutOfMemory);
383
+
384
+ dst = prepare(op, size * 2);
385
+ if (ASMJIT_UNLIKELY(!dst))
386
+ return DebugUtils::errored(kErrorOutOfMemory);
387
+
388
+ for (size_t i = 0; i < size; i++, dst += 2, src++) {
389
+ dst[0] = String_baseN[(src[0] >> 4) & 0xF];
390
+ dst[1] = String_baseN[(src[0] ) & 0xF];
391
+ }
392
+ }
393
+
394
+ return kErrorOk;
395
+ }
396
+
397
+ Error String::_opFormat(ModifyOp op, const char* fmt, ...) noexcept {
398
+ Error err;
399
+ va_list ap;
400
+
401
+ va_start(ap, fmt);
402
+ err = _opVFormat(op, fmt, ap);
403
+ va_end(ap);
404
+
405
+ return err;
406
+ }
407
+
408
+ Error String::_opVFormat(ModifyOp op, const char* fmt, va_list ap) noexcept {
409
+ size_t startAt = (op == ModifyOp::kAssign) ? size_t(0) : size();
410
+ size_t remainingCapacity = capacity() - startAt;
411
+
412
+ char buf[1024];
413
+ int fmtResult;
414
+ size_t outputSize;
415
+
416
+ va_list apCopy;
417
+ va_copy(apCopy, ap);
418
+
419
+ if (remainingCapacity >= 128) {
420
+ fmtResult = vsnprintf(data() + startAt, remainingCapacity, fmt, ap);
421
+ outputSize = size_t(fmtResult);
422
+
423
+ if (ASMJIT_LIKELY(outputSize <= remainingCapacity)) {
424
+ _setSize(startAt + outputSize);
425
+ return kErrorOk;
426
+ }
427
+ }
428
+ else {
429
+ fmtResult = vsnprintf(buf, ASMJIT_ARRAY_SIZE(buf), fmt, ap);
430
+ outputSize = size_t(fmtResult);
431
+
432
+ if (ASMJIT_LIKELY(outputSize < ASMJIT_ARRAY_SIZE(buf)))
433
+ return _opString(op, buf, outputSize);
434
+ }
435
+
436
+ if (ASMJIT_UNLIKELY(fmtResult < 0))
437
+ return DebugUtils::errored(kErrorInvalidState);
438
+
439
+ char* p = prepare(op, outputSize);
440
+ if (ASMJIT_UNLIKELY(!p))
441
+ return DebugUtils::errored(kErrorOutOfMemory);
442
+
443
+ fmtResult = vsnprintf(p, outputSize + 1, fmt, apCopy);
444
+ ASMJIT_ASSERT(size_t(fmtResult) == outputSize);
445
+
446
+ return kErrorOk;
447
+ }
448
+
449
+ Error String::truncate(size_t newSize) noexcept {
450
+ if (isLargeOrExternal()) {
451
+ if (newSize < _large.size) {
452
+ _large.data[newSize] = '\0';
453
+ _large.size = newSize;
454
+ }
455
+ }
456
+ else {
457
+ if (newSize < _type) {
458
+ _small.data[newSize] = '\0';
459
+ _small.type = uint8_t(newSize);
460
+ }
461
+ }
462
+
463
+ return kErrorOk;
464
+ }
465
+
466
+ bool String::eq(const char* other, size_t size) const noexcept {
467
+ const char* aData = data();
468
+ const char* bData = other;
469
+
470
+ size_t aSize = this->size();
471
+ size_t bSize = size;
472
+
473
+ if (bSize == SIZE_MAX) {
474
+ size_t i;
475
+ for (i = 0; i < aSize; i++)
476
+ if (aData[i] != bData[i] || bData[i] == 0)
477
+ return false;
478
+ return bData[i] == 0;
479
+ }
480
+ else {
481
+ if (aSize != bSize)
482
+ return false;
483
+ return ::memcmp(aData, bData, aSize) == 0;
484
+ }
485
+ }
486
+
487
+ // String - Tests
488
+ // ==============
489
+
490
+ #if defined(ASMJIT_TEST)
491
+ UNIT(core_string) {
492
+ String s;
493
+
494
+ EXPECT(s.isLargeOrExternal() == false);
495
+ EXPECT(s.isExternal() == false);
496
+
497
+ EXPECT(s.assign('a') == kErrorOk);
498
+ EXPECT(s.size() == 1);
499
+ EXPECT(s.capacity() == String::kSSOCapacity);
500
+ EXPECT(s.data()[0] == 'a');
501
+ EXPECT(s.data()[1] == '\0');
502
+ EXPECT(s.eq("a") == true);
503
+ EXPECT(s.eq("a", 1) == true);
504
+
505
+ EXPECT(s.assignChars('b', 4) == kErrorOk);
506
+ EXPECT(s.size() == 4);
507
+ EXPECT(s.capacity() == String::kSSOCapacity);
508
+ EXPECT(s.data()[0] == 'b');
509
+ EXPECT(s.data()[1] == 'b');
510
+ EXPECT(s.data()[2] == 'b');
511
+ EXPECT(s.data()[3] == 'b');
512
+ EXPECT(s.data()[4] == '\0');
513
+ EXPECT(s.eq("bbbb") == true);
514
+ EXPECT(s.eq("bbbb", 4) == true);
515
+
516
+ EXPECT(s.assign("abc") == kErrorOk);
517
+ EXPECT(s.size() == 3);
518
+ EXPECT(s.capacity() == String::kSSOCapacity);
519
+ EXPECT(s.data()[0] == 'a');
520
+ EXPECT(s.data()[1] == 'b');
521
+ EXPECT(s.data()[2] == 'c');
522
+ EXPECT(s.data()[3] == '\0');
523
+ EXPECT(s.eq("abc") == true);
524
+ EXPECT(s.eq("abc", 3) == true);
525
+
526
+ const char* large = "Large string that will not fit into SSO buffer";
527
+ EXPECT(s.assign(large) == kErrorOk);
528
+ EXPECT(s.isLargeOrExternal() == true);
529
+ EXPECT(s.size() == strlen(large));
530
+ EXPECT(s.capacity() > String::kSSOCapacity);
531
+ EXPECT(s.eq(large) == true);
532
+ EXPECT(s.eq(large, strlen(large)) == true);
533
+
534
+ const char* additional = " (additional content)";
535
+ EXPECT(s.isLargeOrExternal() == true);
536
+ EXPECT(s.append(additional) == kErrorOk);
537
+ EXPECT(s.size() == strlen(large) + strlen(additional));
538
+
539
+ EXPECT(s.clear() == kErrorOk);
540
+ EXPECT(s.size() == 0);
541
+ EXPECT(s.empty() == true);
542
+ EXPECT(s.data()[0] == '\0');
543
+ EXPECT(s.isLargeOrExternal() == true); // Clear should never release the memory.
544
+
545
+ EXPECT(s.appendUInt(1234) == kErrorOk);
546
+ EXPECT(s.eq("1234") == true);
547
+
548
+ EXPECT(s.assignUInt(0xFFFF, 16, 0, StringFormatFlags::kAlternate) == kErrorOk);
549
+ EXPECT(s.eq("0xFFFF"));
550
+
551
+ StringTmp<64> sTmp;
552
+ EXPECT(sTmp.isLargeOrExternal());
553
+ EXPECT(sTmp.isExternal());
554
+ EXPECT(sTmp.appendChars(' ', 1000) == kErrorOk);
555
+ EXPECT(!sTmp.isExternal());
556
+ }
557
+ #endif
558
+
559
+ ASMJIT_END_NAMESPACE